GitHub Actions Integration¶
NON-NORMATIVE. Reference for the CI/CD workflows in
.github/workflows/.
Workflow Overview¶
| Workflow | Trigger | Purpose |
|---|---|---|
ci.yml |
PRs to main, workflow_call |
TypeScript and Python checks; integration gate |
deploy.yml |
Push to main, workflow_dispatch |
Stage + optionally promote to production |
release.yml |
Tag push (v*) |
Full CI → publish npm + PyPI → GitHub Release |
docs.yml |
Push to main (docs/mkdocs changes) |
Validate and deploy MkDocs to GitHub Pages |
governance.yml |
Weekly schedule (Mon 10:00 UTC), workflow_dispatch |
Full categorical governance loop |
governance-gate.yml |
workflow_call |
Reusable governance gate (κ threshold) |
drift-check.yml |
Weekly schedule (Mon 09:00 UTC), workflow_dispatch |
SSOT drift, maturity score, structural checks |
security.yml |
(see file) | Security scanning |
benchmarks.yml |
(see file) | Performance benchmarks |
stale.yml |
Schedule | Mark stale issues and PRs |
labeler.yml |
PRs | Auto-label by changed paths |
notify.yml |
(see file) | Webhook notifications (uses NOTIFY_WEBHOOK_URL) |
post-deploy-smoke.yml |
(see file) | Post-deployment smoke tests |
workspace-audit.yml |
(see file) | Portfolio-wide governance audit |
historical-pr-inventory.yml |
workflow_dispatch |
Build historical PR inventory |
CI Pipeline (ci.yml)¶
Triggered on all PRs targeting main and as a reusable workflow (workflow_call).
Concurrency: one run per workflow+ref; in-progress runs are cancelled on new push.
Jobs:
typescript¶
Runs on ubuntu-latest. Steps:
1. Checkout + Node.js setup (.github/actions/setup-node)
2. npx turbo typecheck — TypeScript type checking across all packages
3. npx turbo lint — ESLint
4. npx turbo test — Vitest unit tests
5. npx turbo build — production build
6. Upload .next build as artifact (next-build, 7-day retention)
Placeholder env vars are injected for the build (Clerk, Supabase, Stripe) — these do not represent real credentials.
python¶
Runs on ubuntu-latest. Steps:
1. Checkout + Python setup (.github/actions/setup-python)
2. ruff check src/ tests/ — linting
3. mypy src/ — type checking
4. pytest tests/ --cov=morphism --cov-report=xml — tests with coverage
5. Docs graph check, docs contract check, reviewer spec sync, backlog stale check
6. Upload coverage.xml artifact
review-comments¶
Runs only on PRs. Checks for unresolved review threads via GitHub GraphQL API. Blocks merge if any thread is unresolved.
integration-gate¶
Runs after typescript and python. Steps:
1. Credential scan (scripts/scan-credentials.sh)
2. Security preflight (scripts/security-preflight.sh)
3. Scope check — validates commit message against I-4 (Scope Binding)
4. Policy check (scripts/policy_check.py --mode ci)
5. Repo conventions check
6. Diff-aware docs contract check
7. Pipeline verification (scripts/verify_pipeline.py)
8. Maturity score gate (scripts/maturity_score.py --ci --threshold 60)
9. Publish drift check (scripts/check_publish_drift.py)
10. CLI doctor (node packages/cli/dist/index.js doctor)
Governance Gate (governance.yml)¶
Runs weekly on Monday at 10:00 UTC (after drift-check.yml at 09:00 UTC). Also available via workflow_dispatch.
What it checks:
- Pinned version sync
- OpenAPI parity
- Asset recovery prerequisites
- Historical gap matrix freshness
- Full governance validation via npx morphism validate --full — outputs κ (kappa) and maturity score
- Gates on κ ≤ 0.35
Results are uploaded as artifacts (governance-proof-<sha>, 90-day retention). The κ history is cached per branch using actions/cache.
Reusable gate (governance-gate.yml)¶
A workflow_call variant that exposes inputs (threshold, fail_on, target, upload_sarif, python_version) and outputs (kappa, verdict, passed). Runs morphism gate and optionally uploads SARIF to GitHub Code Scanning. Posts a Mermaid governance diagram as a sticky PR comment.
Deploy Pipeline (deploy.yml)¶
Triggered on push to main and via workflow_dispatch.
Jobs:
staging (always runs)¶
Deploys to Vercel preview using the Vercel CLI (vercel deploy --token ...). Falls back to unscoped deploy if the scoped deploy fails with an account access error. Runs a smoke test against /api/health — expects { "status": "ok" }. If VERCEL_AUTOMATION_BYPASS_SECRET is not set, the smoke test is skipped with a warning.
Output: deployment-url (the preview URL)
production (manual only)¶
Runs only when workflow_dispatch is triggered with promote: "production". Calls vercel promote <staging-url> to alias staging to production. Smoke-tests https://morphism.systems/api/health.
Release Pipeline (release.yml)¶
Triggered on version tags (v*).
Job order:
ci → docs-evidence → build-ts ─────────────────┐
→ build-python → publish-pypi ┤
→ publish-npm ────────────────┤
→ sbom ──────────────────────→ release (GitHub Release)
ci— full CI viaworkflow_calldocs-evidence— validates docs contract metadata and release note coveragebuild-ts— builds all packages, uploadspackages/*/dist/artifactpublish-npm— publishes all 6 packages (shared,agentic-math,mcp-server,cli,plugin-bundle,design-tokens) usingNPM_TOKEN; uses--provenanceflagbuild-python— buildsmorphismPython packagepublish-pypi— publishes via OIDC trusted publishing (no token needed)sbom— generates CycloneDX SBOMs for npm and Pythonrelease— creates GitHub Release with auto-generated notes, attaches Python dist and SBOMs
Docs Pipeline (docs.yml)¶
Triggered on push to main when files in docs/ or mkdocs.yml/mkdocs-internal.yml change.
docs-check— validates docs graph, docs contract, then builds both public (mkdocs.yml) and internal (mkdocs-internal.yml) sites in strict modedeploy— deploys public site to GitHub Pages (requiresdocs-checkto pass)
Required Secrets¶
These secrets must be configured in the repository (Settings > Secrets and variables > Actions):
| Secret | Used by | Purpose |
|---|---|---|
GITHUB_TOKEN |
release.yml, drift-check.yml |
Auto-provided by GitHub; used for releases and issue creation |
VERCEL_TOKEN |
deploy.yml |
Vercel CLI authentication |
VERCEL_ORG_ID |
deploy.yml |
Vercel organization/team ID |
VERCEL_PROJECT_ID |
deploy.yml |
Vercel project ID |
VERCEL_AUTOMATION_BYPASS_SECRET |
deploy.yml |
Bypasses Vercel deployment protection for smoke tests |
NPM_TOKEN |
release.yml |
npm publish authentication for @morphism-systems packages |
NOTIFY_WEBHOOK_URL |
notify.yml |
Webhook URL for deployment/event notifications |
SENTRY_AUTH_TOKEN and SENTRY_ORG/SENTRY_PROJECT are not workflow secrets — they are set as Vercel environment variables and used at build time by the Sentry Next.js SDK.
Adding a New Workflow¶
Create .github/workflows/<name>.yml. Use one of these trigger patterns:
on:
push:
branches: [main] # on merge to main
pull_request:
branches: [main] # on PR targeting main
schedule:
- cron: "0 10 * * 1" # weekly Monday 10:00 UTC
workflow_dispatch: # manual trigger
workflow_call: # reusable (called by other workflows)
inputs: {}
outputs: {}
Reference the composite actions for consistent setup:
- .github/actions/setup-node — Node.js 22 + npm ci
- .github/actions/setup-python — Python 3.11/3.12 + pip install -e ".[dev]"
Add a concurrency group to prevent duplicate runs:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true