Skip to content

CI/CD Workflows

Overview

UberLotto uses GitHub Actions for continuous integration and deployment to Shopify Oxygen. The repository contains two deployment workflows that run in parallel on every push, deploying to two separate Shopify storefronts.

Workflow Files

Both workflows are located in .github/workflows/:

FileNameDeployment Token Secret
oxygen-deployment-1000042728.ymlStorefront 1000042728OXYGEN_DEPLOYMENT_TOKEN_1000042728
oxygen-deployment-1000083568.ymlStorefront 1000083568OXYGEN_DEPLOYMENT_TOKEN_1000083568

Workflow Configuration

Both workflows share an identical structure. Below is the annotated configuration:

yaml
name: Storefront 1000042728   # Unique name per workflow
on: [push]                     # Triggers on every push to any branch

permissions:
  contents: read               # Read repository code
  deployments: write           # Create GitHub deployment records

jobs:
  deploy:
    name: Deploy to Oxygen
    timeout-minutes: 30        # Fail if build exceeds 30 minutes
    runs-on: ubuntu-latest     # GitHub-hosted runner
    steps:
      # Step 1: Checkout the repository
      - uses: actions/checkout@v4

      # Step 2: Setup Node.js (latest LTS version)
      - name: Setup node.js
        uses: actions/setup-node@v4
        with:
          node-version: "lts/*"
          check-latest: true

      # Step 3: Cache npm modules for faster builds
      - name: Cache node modules
        id: cache-npm
        uses: actions/cache@v4
        env:
          cache-name: cache-node-modules
        with:
          path: ~/.npm
          key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-build-${{ env.cache-name }}-
            ${{ runner.os }}-build-
            ${{ runner.os }}-

      # Step 4: Install dependencies using clean install
      - name: Install dependencies
        run: npm ci

      # Step 5: Build and deploy to Shopify Oxygen
      - name: Build and Publish to Oxygen
        run: npx shopify hydrogen deploy
        env:
          SHOPIFY_HYDROGEN_DEPLOYMENT_TOKEN: ${{ secrets.OXYGEN_DEPLOYMENT_TOKEN_1000042728 }}

Workflow Steps Explained

StepActionPurpose
Checkoutactions/checkout@v4Clone the repository at the pushed commit
Setup Node.jsactions/setup-node@v4Install Node.js LTS with latest patch
Cacheactions/cache@v4Cache ~/.npm directory keyed by package-lock.json hash
Installnpm ciClean install from lockfile (deterministic)
Deploynpx shopify hydrogen deployBuild the Hydrogen app and push to Oxygen

Trigger Behavior

When Workflows Run

Both workflows trigger on every push event to any branch:

yaml
on: [push]

This means:

  • Pushing to mainProduction deployment to both storefronts
  • Pushing to any other branch → Preview deployment to both storefronts
  • Both workflows execute in parallel

Branch-to-Environment Mapping

ActionStorefront 1000042728Storefront 1000083568
Push to mainProduction deployProduction deploy
Push to feature/*Preview deployPreview deploy
Push to developPreview deployPreview deploy
Push to hotfix/*Preview deployPreview deploy

TIP

Shopify Oxygen determines the target environment (production vs. preview) based on the branch configuration in your Shopify admin, not the workflow file.

Required GitHub Secrets

Current Secrets

Secret NameUsed ByDescription
OXYGEN_DEPLOYMENT_TOKEN_1000042728Workflow 1Oxygen deployment token for Storefront 1000042728
OXYGEN_DEPLOYMENT_TOKEN_1000083568Workflow 2Oxygen deployment token for Storefront 1000083568

How to Add or Update Secrets

  1. Navigate to your GitHub repository
  2. Go to Settings → Secrets and variables → Actions
  3. Click New repository secret (or update an existing one)
  4. Enter the secret name exactly as shown above
  5. Paste the token value from Shopify Admin
  6. Click Add secret

Obtaining Deployment Tokens

  1. Go to Shopify Admin → Sales channels → Hydrogen
  2. Select the target storefront (by its ID)
  3. Navigate to Settings → Deployment
  4. Copy the deployment token
  5. Add it as a GitHub secret with the matching name

WARNING

Deployment tokens are storefront-specific. Each storefront requires its own token. If you regenerate a token in Shopify, update the corresponding GitHub secret immediately.

Branch Strategy

main (production)

  ├── develop (staging/preview)
  │     │
  │     ├── feature/new-payment-method
  │     ├── feature/ui-redesign
  │     └── bugfix/cart-total

  └── hotfix/critical-fix (urgent production fixes)

Branch Purposes

BranchPurposeDeploys To
mainProduction-ready codeProduction environment
developIntegration branch for featuresPreview environment
feature/*Individual feature developmentPreview environment
bugfix/*Non-urgent bug fixesPreview environment
hotfix/*Urgent production fixesPreview (then merge to main)

Merge Flow

  1. Create feature branch from develop
  2. Develop and test using preview deployments
  3. Merge feature branch into develop
  4. Test integration in develop preview
  5. Merge develop into main for production release

Build Pipeline Details

What shopify hydrogen deploy Does

The deploy command performs these steps internally:

  1. GraphQL Codegen — Generates TypeScript types from Storefront API queries
  2. Vite Build — Compiles React components, bundles CSS (Tailwind v4), tree-shakes imports
  3. Worker Bundle — Creates the Cloudflare Worker edge bundle (dist/worker/index.js)
  4. Client Assets — Produces hashed static assets, PWA manifest, and service worker
  5. Upload — Pushes the build artifacts to Shopify Oxygen
  6. Activate — Makes the deployment live (production) or generates a preview URL

Build Artifacts

dist/
├── client/
│   ├── assets/              # Hashed JS/CSS bundles
│   ├── manifest.webmanifest # PWA manifest
│   └── sw.js                # Service worker
└── worker/
    └── index.js             # Edge worker entry point

Pre-Deployment Checklist

Before merging to main for a production deployment:

  • [ ] TypeScript compiles without errors (npm run typecheck)
  • [ ] ESLint shows no errors (npm run lint)
  • [ ] Application builds successfully (npm run build)
  • [ ] Preview deployment tested and verified
  • [ ] Environment variables verified in Oxygen (shopify hydrogen env list)
  • [ ] Database migrations applied (if any) via Supabase dashboard
  • [ ] No secrets or .env files committed

Monitoring and Debugging

Viewing Workflow Runs

  1. Go to your GitHub repository
  2. Click the Actions tab
  3. Both workflows appear as separate entries
  4. Click a workflow run to see logs for each step

Common CI Failure Causes

SymptomLikely CauseFix
SHOPIFY_HYDROGEN_DEPLOYMENT_TOKEN errorMissing or expired secretRegenerate token in Shopify and update GitHub secret
npm ci failureLockfile mismatchRun npm install locally and commit updated package-lock.json
TypeScript errorsType errors in codeRun npm run typecheck locally and fix errors
Timeout (>30 min)Large dependencies or build loopCheck for circular imports; review recent dependency additions
One workflow fails, other succeedsToken issue for that specific storefrontVerify the failing workflow's secret token

Re-running Failed Workflows

  1. Navigate to the failed workflow run in GitHub Actions
  2. Click Re-run all jobs or Re-run failed jobs
  3. Both workflows can be re-run independently

Adding New Workflows

To add a new Oxygen deployment for a third storefront:

  1. Copy an existing workflow file:

    bash
    cp .github/workflows/oxygen-deployment-1000083568.yml \
       .github/workflows/oxygen-deployment-NEW_ID.yml
  2. Update the workflow name and token reference:

    yaml
    name: Storefront NEW_ID
    # ...
    env:
      SHOPIFY_HYDROGEN_DEPLOYMENT_TOKEN: ${{ secrets.OXYGEN_DEPLOYMENT_TOKEN_NEW_ID }}
  3. Add the new secret OXYGEN_DEPLOYMENT_TOKEN_NEW_ID in GitHub Settings

  4. Commit and push the new workflow file

TIP

Keep workflow filenames consistent with the pattern oxygen-deployment-{storefront-id}.yml for easy identification.

UberLotto Technical Documentation