Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Continuous Integration

All CI for cardano-wallet runs on GitHub Actions. Workflows are defined in .github/workflows/.

Workflows

Core CI

WorkflowTriggerDescription
ci.ymlpush, PRMain build & test pipeline — Linux unit/integration tests, builds all artifacts

Platform-specific

WorkflowTriggerDescription
windows.ymlpush, dispatchWindows build & unit tests (self-hosted)
macos-unit-tests.ymlpush, dispatchmacOS unit tests (self-hosted Apple Silicon)
macos-integration.ymldispatchmacOS integration tests (self-hosted)

End-to-end

WorkflowTriggerDescription
linux-e2e.ymlpush, dispatchLinux E2E tests against preprod
windows-e2e.ymldispatchWindows E2E tests (self-hosted)

Benchmarks & sync

WorkflowTriggerDescription
linux-benchmarks.ymlpush, dispatchRestoration benchmarks on mainnet (long-running)
linux-mithril-sync.ymlpush, dispatchMithril snapshot sync test

Release

WorkflowTriggerDescription
release.ymlpush, tagsCreates release candidate branches and release artifacts
publish.ymlpush, tags, PRPublishes documentation to GitHub Pages

Housekeeping

WorkflowTriggerDescription
cleanup.ymldispatchDeletes old workflow runs
approve-docs.ymlPR targetAuto-approves docs-only PRs
lean.ymlpush, PRLean specification checks (path-filtered to specifications/)

Nix verbosity

All nix commands in CI workflows must include the --quiet flag. This suppresses verbose build logs and warnings that clutter GitHub Actions output, making it easier to spot actual failures.

# Good
nix build --quiet .#cardano-wallet
nix shell --quiet .#cardano-node -c cardano-node --version
nix develop --quiet --command scripts/check.sh

# Bad — missing --quiet
nix build .#cardano-wallet
nix build -L .#cardano-wallet

When adding or modifying workflow steps that invoke nix, always include --quiet.

Self-hosted runners

Several workflows run on self-hosted machines. The GHA runner service replaces the former Buildkite agent on these machines.

Windows machine

System configuration

We assume the machine is configured with a recent Windows version (2022 Server) and has winget installed.

  • Install the GitHub Actions runner as a Windows service
  • Install the Ruby environment in version 2.7 using winget (needed for E2E tests):
    winget install RubyInstallerTeam.Ruby.2.7 --force --disable-interactivity  --accept-source-agreements --accept-package-agreements
    
  • Install Ruby installer toolkit to be able to compile native extensions:
    ridk install
    
  • Install some more packages:
    • winget install zstandard — decompressing hosted archives
    • winget install nssm — running cardano-node as a service

Runner configuration

  • When launched as a service, the GHA runner runs as the Local System Account which does not inherit the environment from the hal user. Ensure software installed through winget is on the runner's PATH.
  • Configure environment secrets (FIXTURE_DECRYPTION_KEY, etc.) via the runner's .env file or repository/org-level GitHub Actions secrets.
  • Ensure node DB files can be removed (they are created readonly which breaks git clean -xfd):
    icacls . /grant hal:F /T /Q
    
  • Ensure cardano-node and cardano-wallet services are cleaned up after each run to avoid leaks from interrupted workflows.

Troubleshooting

Windows permissions are complex. Stick to the default Local System Account as the user for the runner service.

  1. Ensure the user SYSTEM has full control to the runner work directory and this right is inherited:

    PS C:\actions-runner> icacls.exe .
    . NT AUTHORITY\SYSTEM:(OI)(CI)(F)
      BUILTIN\Administrators:(F)
      ZUR1-S-D-027\hal:(OI)(CI)(F)
    
  2. To operate under the right identity, use pstools:

    psexec -s -i cmd
    
  3. If steps fail to delete the checkout directory, ensure no other process is locking it.

macOS machine (hal-mac)

The macOS builder runs on a Mac Mini (Apple Silicon) managed via nix-darwin. Access via SSH through the jumpbox:

ssh mac-builder  # requires SSH config with ProxyJump through jumpbox-dev

Runner configuration

The GHA runner runs as a launchd service. Key paths:

  • Service plist: /Library/LaunchDaemons/org.nixos.github-runner-hal-mac.plist
  • Runner directory: /var/lib/github-runner-hal-mac/
  • Log file: check via journalctl or the runner's _diag/ directory

Updating the runner token

If the runner token expires or becomes invalid:

  1. Create a new runner token at the repository's Settings > Actions > Runners page
  2. Update the token on the machine:
    ssh mac-builder
    # Re-configure the runner with the new token
    
  3. Restart the runner:
    sudo launchctl kickstart -k system/org.nixos.github-runner-hal-mac
    
  4. Verify the runner is connected in the repository's Settings > Actions > Runners page

Environment variables

Secrets are configured via:

  • ATTIC_TOKEN — from /var/lib/gha-runner-hal-mac/env-attic-token
  • FIXTURE_DECRYPTION_KEY — from /var/lib/gha-runner-hal-mac/env-fixture-decryption-key
  • HAL_E2E_PREPROD_MNEMONICS — from /var/lib/gha-runner-hal-mac/env-hal-e2e-preprod-mnemonics

Troubleshooting

  • Check runner status: repository Settings > Actions > Runners
  • View logs: check the runner's _diag/ directory
  • Restart service: sudo launchctl kickstart -k system/org.nixos.github-runner-hal-mac
  • Stop service: sudo launchctl stop system/org.nixos.github-runner-hal-mac
Attic cache failures

The Attic cache job pushes build artifacts to the Attic cache server. If it fails:

  1. Check Attic token — The JWT token in /var/lib/gha-runner-hal-mac/env-attic-token may have expired. Decode it:

    cat /var/lib/gha-runner-hal-mac/env-attic-token | cut -d. -f2 | base64 -d
    

    Look for the exp field (Unix timestamp).

  2. Test Attic login:

    ATTIC_TOKEN=$(cat /var/lib/gha-runner-hal-mac/env-attic-token)
    nix-shell -p attic-client --run "attic login adrestia https://attic.cf-app.org/ $ATTIC_TOKEN"
    
  3. Verify Attic server is reachable: curl -I https://attic.cf-app.org/

  4. SSL Certificate Error — If you see invalid peer certificate: UnknownIssuer, the machine may be resolving attic.cf-app.org to an internal IP with an untrusted certificate.

    Check which IP is being used:

    ping -c1 attic.cf-app.org
    

    If it resolves to an internal IP (e.g., 10.1.21.x), override with the external IP in /etc/hosts:

    sudo sed -i '' 's/ attic.cf-app.org//g; s/ attic//g' /etc/hosts
    echo "195.48.82.220 attic.cf-app.org" | sudo tee -a /etc/hosts
    
Stale processes

Test cluster processes (cardano-node) may accumulate if builds are interrupted:

ps aux | grep cardano-node
pkill -f "cardano-node.*test-cluster"