albertonline.org docs

CI/CD

The GitHub Actions workflows, the local pre-push gate, quality gates, and how CI checks are toggled per context.

CI is GitHub Actions in .github/workflows/. The same gates run locally before every push via a Husky hook, so a red push should never reach GitHub.

The local gate — run it before pushing

The .husky/pre-push hook runs the CI gates locally. Its first step, pnpm ci:precheck, is a superset of the CI "Static Checks" job:

pnpm ci:precheck
# = pnpm lint · turbo run lint · check-types · format:check
#   · check:boundaries · check:architecture · check:no-raw-getsession
#   · check:doc-versions · fallow

It then runs the test suite and an affected build.

pnpm check-types alone is not enough — it misses the repo-wide oxlint (pnpm lint) that Static Checks runs. "Ready to push" means ci:precheck is green. Never bypass the gate with SKIP_PREPUSH=1, --no-verify, or -n; scope-skip only the env-bound steps with RUN_BUILD=0 / RUN_TESTS=0.

The main CI workflow (ci.yml)

JobLocal equivalent
Static Checkspnpm ci:precheck (superset)
Tests + coveragepnpm turbo run test:ci
Buildpnpm turbo run build --affected
SonarQubepnpm sonar:scan (needs docker + JDK)
a11y / e2esee e2e.yml and the a11y job

For the closest parity to the GitHub runner, RUN_ACT=1 git push runs the real static job through act.

Quality gates

  • Coverage on New Code ≥ 80% — SonarQube measures the changed/added production lines in the PR diff. A new untested module sinks the gate even if the rest of the repo is well covered. Write tests in the same change.
  • react-doctor at 0 errors — a separate workflow (react-doctor.yml). It is not in the default pre-push, so run npx react-doctor@latest . --blocking error -y before finishing any React change (or opt in with RUN_REACT_DOCTOR=1 git push).
  • fallow — dead-code and duplicate detection, part of ci:precheck.

Configurable CI

Which checks run is configurable per context and persistent via .github/ci-config.json:

  • Three contexts — pr, default_branch (push to main), and release (release-please PRs) — each with a boolean per toggleable check (static, tests, a11y, build, sonar, e2e, react_doctor, market_web_e2e, market_web_quality).
  • Toggle via the Configure CI workflow (Actions → Configure CI → Run workflow) or by editing the JSON. Every workflow reads the config from main, not the PR head — so a PR can't disable its own checks.

The workflow catalogue

WorkflowPurpose
ci.ymlStatic checks, tests + coverage, build, Sonar, a11y
e2e.ymlPlaywright end-to-end tests
configure-ci.ymlWrite per-context check toggles to main
ci-checkbox-comment.yml / ci-checkbox-handler.ymlPR checkbox → re-run controls
vercel-preview-deploy.ymlVercel preview deploys for PRs
deploy-portal.ymlDeploy apps/portal to Cloudflare Workers
storybook-deploy.ymlDeploy the Storybook component library
db-migrate.ymlApply Drizzle migrations
react-doctor.ymlReact health gate (0 errors)
security-audit.ymlDependency / security audit
dependency-update.ymlAutomated dependency bumps
release-please.ymlRelease PRs + changelogs
bundle-size.ymlBundle-size budget check
pr-standards.ymlPR title / description / conventional-commit checks
i18n-sync.ymlKeep translations in sync
maintenance.ymlScheduled maintenance jobs
gitnexus-analyze.yml / graphify.ymlRefresh code-intelligence indexes
ak-quality-gate.ymlAggregate quality gate
market-web-coverage.yml / market-web-e2e.yml / market-web-quality-gate.ymlapps/market-web checks
teliaplay-e2e.ymlE2E against prod teliaplay.se
turbo-cache-purge.ymlPurge the remote Turbo cache

When CI fails

Recognise known failures before diagnosing from scratch — most red checks in this repo are already-understood flakes or pre-existing, unrelated-app reds. Confirm scope against main (gh run list --workflow ci.yml --branch main) before blaming your diff, fix the root cause at the source, and record any new failure mode in an obsidian-vault/01 Fleeting/ note.

See local development for running the tests behind these gates.

On this page