GitHub Actions Workflows
This document describes the GitHub Actions workflows used in this repository and explains the recent improvements made for better performance and maintainability.
Overview
The repository uses four main workflows:
- CI (
ci.yml) - Continuous Integration for code quality and deployment - Version Bump (
version-bump.yml) - Automatic or manual version updates with changelog - Create Version Tag (
create-version-tag.yml) - Creates release tags for merged version bump PRs - Release (
release.yml) - Build and publish releases
CI Workflow
Trigger: Push to main, Pull Requests, Manual dispatch
Jobs
Parallel Quality Checks (runs concurrently)
- Lint - Code linting with Deno
- Format - Code formatting check with Deno
- Type Check - TypeScript type checking for all entry points
- Test - Run test suite with coverage; coverage artifact uploaded on both PRs and main push
- Security - Trivy vulnerability scanning
- Frontend Build - Angular frontend lint, test, build, and artifact upload (single merged job)
- Validate Cloudflare Schema - Runs
deno task schema:cloudflareand verifies thatdocs/api/cloudflare-schema.yaml(Cloudflare API Shield schema generated from the OpenAPI spec) is up to date
PR-Only Parallel Job (needs frontend-build artifact)
- Verify Deploy - Cloudflare Worker build dry-run (
deno task wrangler:verify); runs on PRs only, waits for thefrontend-buildartifact but otherwise runs in parallel with the quality checks above
Sequential Jobs (run after all checks pass)
- CI Gate - Python script verifying all upstream jobs passed or were acceptably skipped; blocks publish and deploy
- Publish - Publish to JSR (main only, after CI gate passes)
- Deploy - Deploy to Cloudflare (main only, when enabled, after CI gate passes)
Composite Actions
A reusable composite action handles Deno dependency installation with a 3-attempt retry loop and DENO_TLS_CA_STORE=system:
# Used in all jobs that require Deno deps
- uses: ./.github/actions/deno-install
The action is defined in .github/actions/deno-install/action.yml and is used by the typecheck, test, publish, verify-deploy, and deploy jobs.
Key Improvements
- ✅ Parallelization: Lint, format, typecheck, test, and security scans run simultaneously
- ✅ Proper Gating:
ci-gateblocks publish/deploy until lint, format, typecheck, test, security, frontend-build, and verify-deploy all pass - ✅ Worker Build Verified on PRs:
verify-deployruns a Cloudflare Worker dry-run on every PR so Worker build failures are caught before merge - ✅ Composite Action:
deno installretry logic extracted to.github/actions/deno-install— no duplication across jobs - ✅ Merged Frontend Jobs:
frontend(lint+test) andfrontend-build(build+artifact) are now a singlefrontend-buildjob — onepnpm installper run - ✅ Frozen Lockfile:
pnpm install --frozen-lockfileenforced — CI fails ifpnpm-lock.yamldrifts frompackage.json - ✅ Coverage on PRs: Test coverage artifact uploaded on pull requests, not just main push
- ✅ SHA-Pinned Actions: All third-party actions pinned to full commit SHAs with version comments (supply-chain hardening)
- ✅ Better Caching: Includes
deno.lockin cache key for more precise invalidation - ✅ Comprehensive Type Checking: Checks all entry points (index.ts, cli.ts, worker.ts, tail.ts)
- ✅ Consolidated Worker Deployment: Main and tail Cloudflare Workers deployed from a single CI deploy job (no separate Pages deployment)
- ✅ Migration Error Handling:
run_migration()shell function distinguishes real errors from "already applied" idempotency messages
Performance Gains
- Before: ~5-7 minutes (sequential execution)
- After: ~2-3 minutes (parallel execution)
- Improvement: ~40-50% faster
Release Workflow
Trigger: Push tags (v*), Manual dispatch with version input
Jobs
- Validate - Run full CI suite before building anything
- Build Binaries - Build native binaries for all platforms (parallel matrix)
- Build Docker - Build and push multi-platform Docker images
- Create Release - Generate GitHub release with all artifacts
Key Improvements
- ✅ Pre-build Validation: Ensures code quality before expensive build operations
- ✅ Better Caching: Per-target caching for binary builds
- ✅ Simplified Asset Prep: Uses
findinstead of complex loop - ✅ Cleaner Structure: Removed verbose comments, organized logically
Performance Gains
- Before: ~15-20 minutes (no validation, potential failures late)
- After: ~12-15 minutes (early validation prevents wasted builds)
- Improvement: Faster failure detection, ~20% reduction in failed build time
Version Bump Workflow
Trigger: Push to main, Manual dispatch
Jobs
- Version Bump - Automatically analyze commits and bump version, or manually specify bump type
- Trigger Release - Optionally trigger release workflow (if requested via manual dispatch)
Key Features
- ✅ Automatic Detection: Uses conventional commits to determine version bump type
- ✅ Manual Override: Can manually specify patch/minor/major bump
- ✅ Changelog Generation: Automatically generates changelog entries from commits
- ✅ PR-Based: Creates pull request with version changes for review
- ✅ Skip Logic: Skips if
[skip ci]or[skip version]in commit message
Conventional Commits Support
feat:→ minor bumpfix:→ patch bumpperf:→ patch bumpfeat!:orBREAKING CHANGE:→ major bump
Changes from Previous Version
- Consolidated: Merged
auto-version-bump.ymlandversion-bump.ymlinto single workflow - Simplified: Single workflow handles both automatic and manual triggers
- Improved: Better error handling and verification steps
Create Version Tag Workflow
Trigger: PR closed (for version bump PRs only)
Jobs
- Create Tag - Creates release tag when version bump PR is merged
Key Features
- ✅ Automatic Tagging: Creates
v<version>tag when version bump PR is merged - ✅ Idempotent: Checks if tag exists before creating
- ✅ Cleanup: Deletes version bump branch after tagging
- ✅ Release Trigger: Tag automatically triggers release workflow
Caching Strategy
All workflows now use an improved caching strategy:
key: deno-${{ runner.os }}-${{ hashFiles('deno.json', 'deno.lock') }}
restore-keys: |
deno-${{ runner.os }}-
This ensures:
- Cache is invalidated when dependencies change
- Fallback to OS-specific cache if exact match not found
- Faster dependency installation
Environment Variables
Common
DENO_VERSION: '2.x'- Deno version used across all workflows
CI Workflow
CODECOV_TOKEN- For uploading test coverage (optional)CLOUDFLARE_API_TOKEN- For Cloudflare deployments (optional)CLOUDFLARE_ACCOUNT_ID- For Cloudflare deployments (optional)
Required Variables
ENABLE_CLOUDFLARE_DEPLOY- Repository variable to enable/disable Cloudflare deployments
Permissions
All workflows use minimal permissions following the principle of least privilege:
CI
contents: read- For checking out codeid-token: write- For JSR publishing (publish job only)security-events: write- For uploading security scan results (security job only)
Release
contents: write- For creating releases and tagspackages: write- For publishing Docker images
Version Bump
contents: write- For committing version changesactions: write- For triggering release workflow
Concurrency
All workflows use concurrency groups to prevent multiple runs on the same ref:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
This ensures:
- Only one workflow runs per branch/PR at a time
- Outdated runs are automatically cancelled when new commits are pushed
- Saves CI minutes and prevents race conditions
Best Practices
When to Use Each Workflow
- CI: Automatically runs on every push/PR - no manual intervention needed
- Version Bump: Run manually when you want to bump the version
- Release: Automatically triggered by version tags, or run manually for specific versions
Recommended Release Process
- Make your changes on a feature branch
- Create a PR and wait for CI to pass
- Merge to main
- Version bump workflow automatically runs and creates a version bump PR
- Review and merge the version bump PR
- Create version tag workflow automatically creates the release tag
- Release workflow automatically builds and publishes the release
Or for manual version bump:
- Make your changes on a feature branch
- Create a PR and wait for CI to pass
- Merge to main
- Run "Version Bump" workflow manually with desired bump type
- Optionally check "Create a release after bumping" to skip the PR review step
Troubleshooting
Publish Fails with "Version Already Exists"
This is expected and not an error. The workflow treats this as success to allow re-running the workflow.
Deploy Jobs Don't Run
Check that ENABLE_CLOUDFLARE_DEPLOY repository variable is set to 'true' (as a string).
Binary Build Fails for ARM64 Linux
The ARM64 Linux build uses cross-compilation. If it fails, check Deno's compatibility with the target platform in the Deno release notes.
Migration Notes
If you're migrating from the old workflows:
Breaking Changes
- Version bump no longer runs automatically on PR open
- Example files are no longer automatically updated during version bump
- Deploy jobs now combined into single job
Non-Breaking Changes
- All existing secrets and variables work the same way
- Workflow dispatch inputs are backwards compatible
- Release process is unchanged
Future Improvements
Potential areas for further optimization:
- Add workflow to automatically create PRs for dependency updates
- Add scheduled security scanning (weekly)
- Consider splitting test job by test type (unit vs integration)
- Add benchmark tracking over time
- Add automatic changelog generation
- Add path-based filtering to skip frontend-build on backend-only PRs (currently blocked by verify-deploy's artifact dependency)