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/:
| File | Name | Deployment Token Secret |
|---|---|---|
oxygen-deployment-1000042728.yml | Storefront 1000042728 | OXYGEN_DEPLOYMENT_TOKEN_1000042728 |
oxygen-deployment-1000083568.yml | Storefront 1000083568 | OXYGEN_DEPLOYMENT_TOKEN_1000083568 |
Workflow Configuration
Both workflows share an identical structure. Below is the annotated configuration:
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
| Step | Action | Purpose |
|---|---|---|
| Checkout | actions/checkout@v4 | Clone the repository at the pushed commit |
| Setup Node.js | actions/setup-node@v4 | Install Node.js LTS with latest patch |
| Cache | actions/cache@v4 | Cache ~/.npm directory keyed by package-lock.json hash |
| Install | npm ci | Clean install from lockfile (deterministic) |
| Deploy | npx shopify hydrogen deploy | Build the Hydrogen app and push to Oxygen |
Trigger Behavior
When Workflows Run
Both workflows trigger on every push event to any branch:
on: [push]This means:
- Pushing to
main→ Production deployment to both storefronts - Pushing to any other branch → Preview deployment to both storefronts
- Both workflows execute in parallel
Branch-to-Environment Mapping
| Action | Storefront 1000042728 | Storefront 1000083568 |
|---|---|---|
Push to main | Production deploy | Production deploy |
Push to feature/* | Preview deploy | Preview deploy |
Push to develop | Preview deploy | Preview deploy |
Push to hotfix/* | Preview deploy | Preview 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 Name | Used By | Description |
|---|---|---|
OXYGEN_DEPLOYMENT_TOKEN_1000042728 | Workflow 1 | Oxygen deployment token for Storefront 1000042728 |
OXYGEN_DEPLOYMENT_TOKEN_1000083568 | Workflow 2 | Oxygen deployment token for Storefront 1000083568 |
How to Add or Update Secrets
- Navigate to your GitHub repository
- Go to Settings → Secrets and variables → Actions
- Click New repository secret (or update an existing one)
- Enter the secret name exactly as shown above
- Paste the token value from Shopify Admin
- Click Add secret
Obtaining Deployment Tokens
- Go to Shopify Admin → Sales channels → Hydrogen
- Select the target storefront (by its ID)
- Navigate to Settings → Deployment
- Copy the deployment token
- 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
Recommended Branch Flow
main (production)
│
├── develop (staging/preview)
│ │
│ ├── feature/new-payment-method
│ ├── feature/ui-redesign
│ └── bugfix/cart-total
│
└── hotfix/critical-fix (urgent production fixes)Branch Purposes
| Branch | Purpose | Deploys To |
|---|---|---|
main | Production-ready code | Production environment |
develop | Integration branch for features | Preview environment |
feature/* | Individual feature development | Preview environment |
bugfix/* | Non-urgent bug fixes | Preview environment |
hotfix/* | Urgent production fixes | Preview (then merge to main) |
Merge Flow
- Create feature branch from
develop - Develop and test using preview deployments
- Merge feature branch into
develop - Test integration in
developpreview - Merge
developintomainfor production release
Build Pipeline Details
What shopify hydrogen deploy Does
The deploy command performs these steps internally:
- GraphQL Codegen — Generates TypeScript types from Storefront API queries
- Vite Build — Compiles React components, bundles CSS (Tailwind v4), tree-shakes imports
- Worker Bundle — Creates the Cloudflare Worker edge bundle (
dist/worker/index.js) - Client Assets — Produces hashed static assets, PWA manifest, and service worker
- Upload — Pushes the build artifacts to Shopify Oxygen
- 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 pointPre-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
.envfiles committed
Monitoring and Debugging
Viewing Workflow Runs
- Go to your GitHub repository
- Click the Actions tab
- Both workflows appear as separate entries
- Click a workflow run to see logs for each step
Common CI Failure Causes
| Symptom | Likely Cause | Fix |
|---|---|---|
SHOPIFY_HYDROGEN_DEPLOYMENT_TOKEN error | Missing or expired secret | Regenerate token in Shopify and update GitHub secret |
npm ci failure | Lockfile mismatch | Run npm install locally and commit updated package-lock.json |
| TypeScript errors | Type errors in code | Run npm run typecheck locally and fix errors |
| Timeout (>30 min) | Large dependencies or build loop | Check for circular imports; review recent dependency additions |
| One workflow fails, other succeeds | Token issue for that specific storefront | Verify the failing workflow's secret token |
Re-running Failed Workflows
- Navigate to the failed workflow run in GitHub Actions
- Click Re-run all jobs or Re-run failed jobs
- Both workflows can be re-run independently
Adding New Workflows
To add a new Oxygen deployment for a third storefront:
Copy an existing workflow file:
bashcp .github/workflows/oxygen-deployment-1000083568.yml \ .github/workflows/oxygen-deployment-NEW_ID.ymlUpdate the workflow name and token reference:
yamlname: Storefront NEW_ID # ... env: SHOPIFY_HYDROGEN_DEPLOYMENT_TOKEN: ${{ secrets.OXYGEN_DEPLOYMENT_TOKEN_NEW_ID }}Add the new secret
OXYGEN_DEPLOYMENT_TOKEN_NEW_IDin GitHub SettingsCommit and push the new workflow file
TIP
Keep workflow filenames consistent with the pattern oxygen-deployment-{storefront-id}.yml for easy identification.