Skip to content

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-unknown target
  • 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 test with 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

yaml
# .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_canister

Deployment

yaml
# .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

InputRequiredDefaultDescription
canister_nameYes-Canister name (matches Cargo.toml)
rust_versionNo1.75Rust toolchain version
working_directoryNo.Directory with Cargo.toml

test-pocketic.yml

InputRequiredDefaultDescription
canister_nameYes-Canister to test
pocket_ic_versionNo6.0.0PocketIC version

deploy-staging.yml / deploy-mainnet.yml

InputRequiredDefaultDescription
canister_nameYes-Canister to deploy
dfx_versionNo0.24.3DFX SDK version

Deployment Order

Canisters must be deployed in dependency order:

LayerCanistersDependencies
1dom-token, proof-nftsNone
2membership, treasurydom-token
3governance, auth-servicemembership
4user-service, identity-gatewayauth-service
5otter-camp, marketplace, educationAll above
6frontendAll canisters

Performance Targets

MetricTarget
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:

SecretPurpose
DFX_IDENTITY_PEMDeployment identity

Setting Up DFX Identity

bash
# Generate new identity
dfx identity new deploy

# Export for GitHub secret
cat ~/.config/dfx/identity/deploy/identity.pem

GitHub Environments

Configure environments in repository settings:

  1. staging: No protection rules (auto-deploy)
  2. mainnet: Requires approval from team leads

Troubleshooting

Build Failures

"WASM artifact not found"

  • Verify canister_name matches 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_BIN environment 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_PEM secret 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:

  1. Find the last good workflow run ID
  2. Trigger rollback workflow:
    • Actions > Emergency Rollback > Run workflow
    • Enter canister name, network, and run ID
  3. Verify rollback completed (< 5 minutes)
  4. Test canister functionality

See ROLLBACK.md for detailed instructions.

Hello World Co-Op DAO