CI/CD Pipeline
This guide covers the continuous integration and deployment (CI/CD) pipeline for Hello World DAO services.
Overview
All repositories use GitHub Actions with reusable workflows defined in the ops-infra repository. This ensures consistent build, test, and deployment processes across all 15 repositories.
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ Push │───▶│ Build │───▶│ Test │───▶│ Deploy │
│ (code) │ │ (wasm) │ │(PocketIC)│ │(staging) │
└──────────┘ └──────────┘ └──────────┘ └──────────┘
│
▼ (manual approval)
┌──────────┐
│ Deploy │
│(mainnet) │
└──────────┘Workflow Types
Build Workflows
Rust Canisters (build-rust.yml):
- Compiles Rust to WASM using
wasm32-unknown-unknowntarget - Caches cargo dependencies for faster builds
- Uploads WASM artifacts for deployment
Frontend (ci.yml):
- Runs ESLint for code quality
- Builds with Vite
- Uploads dist artifacts
Test Workflows
PocketIC Tests (test-pocketic.yml):
- Downloads PocketIC server
- Runs
cargo testwith integration tests - Posts test results to PR comments
Vitest Tests (test-vitest.yml):
- Runs frontend unit tests
- Generates coverage reports
- Posts results to PR comments
Deployment Workflows
Staging (deploy-staging.yml):
- Automatically triggered on main branch merge
- No approval required
- Deploys to IC testnet
Mainnet (deploy-mainnet.yml):
- Manually triggered only
- Requires approval from team leads
- Full audit logging
Using Reusable Workflows
Rust Canister CI
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
build:
uses: Hello-World-Co-Op/ops-infra/.github/workflows/build-rust.yml@main
with:
canister_name: my_canister
test:
needs: build
uses: Hello-World-Co-Op/ops-infra/.github/workflows/test-pocketic.yml@main
with:
canister_name: my_canisterDeployment
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
workflow_dispatch:
inputs:
environment:
type: choice
options: [staging, mainnet]
jobs:
deploy-staging:
if: github.event_name == 'push'
uses: Hello-World-Co-Op/ops-infra/.github/workflows/deploy-staging.yml@main
with:
canister_name: my_canister
secrets:
DFX_IDENTITY_PEM: ${{ secrets.DFX_IDENTITY_PEM }}Workflow Inputs
build-rust.yml
| Input | Required | Default | Description |
|---|---|---|---|
canister_name | Yes | - | Canister name (matches Cargo.toml) |
rust_version | No | 1.75 | Rust toolchain version |
working_directory | No | . | Directory with Cargo.toml |
test-pocketic.yml
| Input | Required | Default | Description |
|---|---|---|---|
canister_name | Yes | - | Canister to test |
pocket_ic_version | No | 6.0.0 | PocketIC version |
deploy-staging.yml / deploy-mainnet.yml
| Input | Required | Default | Description |
|---|---|---|---|
canister_name | Yes | - | Canister to deploy |
dfx_version | No | 0.24.3 | DFX SDK version |
Deployment Order
Canisters must be deployed in dependency order:
| Layer | Canisters | Dependencies |
|---|---|---|
| 1 | dom-token, proof-nfts | None |
| 2 | membership, treasury | dom-token |
| 3 | governance, auth-service | membership |
| 4 | user-service, identity-gateway | auth-service |
| 5 | otter-camp, marketplace, education | All above |
| 6 | frontend | All canisters |
Performance Targets
| Metric | Target |
|---|---|
| Build time (per repo) | < 5 minutes |
| Test time (per repo) | < 10 minutes |
| Staging deployment | < 3 minutes |
| Mainnet deployment | < 5 minutes |
| Rollback time | < 5 minutes |
Secrets Configuration
Required Secrets
Each repository needs these secrets configured in GitHub:
| Secret | Purpose |
|---|---|
DFX_IDENTITY_PEM | Deployment identity |
Setting Up DFX Identity
# Generate new identity
dfx identity new deploy
# Export for GitHub secret
cat ~/.config/dfx/identity/deploy/identity.pemGitHub Environments
Configure environments in repository settings:
- staging: No protection rules (auto-deploy)
- mainnet: Requires approval from team leads
Troubleshooting
Build Failures
"WASM artifact not found"
- Verify
canister_namematches the crate name in Cargo.toml - Check for compilation errors in build logs
"Build took > 5 minutes"
- Check if cargo cache is being used
- Look for dependency updates causing full rebuilds
Test Failures
"PocketIC server not found"
- Verify
POCKET_IC_BINenvironment variable - Check PocketIC download step logs
"Tests timeout"
- Increase timeout in workflow if needed
- Check for infinite loops in test code
Deployment Failures
"Identity not found"
- Verify
DFX_IDENTITY_PEMsecret is set - Check secret is not expired
"Canister not found"
- Ensure canister exists on target network
- Check canister_ids.json is correct
Rollback Procedure
If a deployment causes issues:
- Find the last good workflow run ID
- Trigger rollback workflow:
- Actions > Emergency Rollback > Run workflow
- Enter canister name, network, and run ID
- Verify rollback completed (< 5 minutes)
- Test canister functionality
See ROLLBACK.md for detailed instructions.
Related Documentation
- ops-infra README - Workflow reference
- Workspace Setup - Local development