Skip to main content

Documentation Index

Fetch the complete documentation index at: https://jacobpevans-docs-automation-surface.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

The CI tier is whatever the workload actually needs. Build it from marketplace actions, version-pin every dependency, and treat releases as permanent.
The policy on this page applies to every workflow under JacobPEvans/* and dryvist/*. The companion page git-signing covers identity and signed-commit attribution; this page covers everything else.

Prefer native CI/CD constructs

TaskUse thisNot this
CI/CD automationMarketplace actions, reusable workflows, composite actionsCustom shell script
GitHub Actions logicExpressions, fromJSON(), matrix strategiesPython or bash in a run: step
Scripts belong in dedicated files (.github/scripts/*.sh, scripts/*.py), not inlined into YAML — see No scripts in non-script files for the full rule.

GitHub Releases

Treat published releases as permanent. Once a release is promoted from draft to published, do not modify or delete it — ever. GitHub technically allows edits and deletions; the policy here forbids it. If a correction is needed, create a new release.
  • Open releases as drafts until fully complete (all assets uploaded, notes finalized).
  • Promote draft to published only when everything is ready.
  • Every repo uses release-please for automated version bumps:
    • Patch bumps come from fix: commits
    • Minor bumps come from feat: commits
    • Major bumps are human-initiated only — edit .release-please-manifest.json manually. Automated major bumps (including from BREAKING CHANGE: footers) are blocked by the release workflow
  • Conventional-commit style preference:
    • fix: for config tweaks, small improvements, incremental adjustments, dependency updates
    • feat: reserved for genuinely new capabilities, integrations, or significant behavioral changes
  • Templates and reusable workflows live in JacobPEvans/.github
Conventional Commits and the no-emoji rule for commit subjects live in Commit conventions.

Dependency versioning

Action sourceHow to pin
Self-references (JacobPEvans/*)@main or a major version tag — never SHA or minor/patch pins
Trusted external actionsVersion tags (major like @v6 or full SemVer like @v2.3.5). Trusted orgs are listed in JacobPEvans/.github/renovate-presets.json
Untrusted external actionsSHA commit hashes only — for orgs not on the trusted list. SHA pinning is the exception, not the default

Runner choice

RunsOn (AWS EC2 spot via terraform-runs-on) is the default for Linux jobs. The control plane is paid for whether it is running jobs or not (~$3.50/mo fixed App Runner + CloudWatch); workflows that stay on ubuntu-latest spend GitHub Actions minutes that do not need to be spent. On-prem self-hosted is the documented exception for jobs that genuinely need local hardware — not a routine choice.
WorkloadRunner
Linux job (lint, validate, build, test)RunsOn — runs-on=${{ github.run_id }}/runner=2cpu-linux-x64
Nix flake check (Linux)RunsOn with more RAM — runs-on=${{ github.run_id }}/cpu=4/ram=16/family=m7+c7/extras=s3-cache
macos-latestGitHub-hosted — RunsOn EC2 Mac has a 24-hour minimum allocation; for short jobs macos-latest is cheaper despite the 10× billing multiplier
windows-latestRunsOn — supports Windows; case-by-case
*.lock.yml from gh-aw compileGitHub-hosted — lock files are regenerated; runner label must flow through the .md companion (gh-aw does not expose this yet)
Disabled-schedule workflow (manual workflow_dispatch only)GitHub-hosted — migration saves nothing
Job requiring local hardware (OrbStack cluster, Proxmox LAN access, dev-loop instrumentation that cannot be replicated on a fresh EC2 spot instance)on-prem self-hosted[self-hosted, Linux, ARM64] (orbstack-kubernetes) or [self-hosted, Linux] (ansible-proxmox-apps); see “On-prem runner requirements” below
The leading runs-on=${{ github.run_id }} segment is required so the RunsOn control plane can correlate the GitHub Actions workflow_job webhook back to the originating run — without it, the job hangs in queued. Reusable workflows in JacobPEvans/.github accept a runner_label input (default ubuntu-latest); callers opt in by passing the RunsOn label string. Full RunsOn label catalog, prereqs (GitHub App allowlist), rollout playbook, and verification steps live in terraform-runs-on/docs/migration-guide.md.

On-prem runner requirements

On-prem self-hosted runners are a single point of failure when the job has E2E coverage and the runner is broken or stale. Every on-prem runner must:
  1. Authenticate via a GitHub App (APP_ID + APP_PRIVATE_KEY) — never a personal access token. App installation tokens auto-refresh; PATs silently expire and break the runner with no upstream visibility.
  2. Pin the runner image (or VM template) by digest, with Renovate tracking the digest. No floating tags.
  3. Expose a process-level healthcheck (Docker healthcheck:, systemd WatchdogSec, or equivalent) so failed state surfaces in standard inspection tools.
  4. Emit a periodic heartbeat to a dead-man’s-switch endpoint (healthchecks.io or equivalent) so silent death pages someone.
  5. Pre-flight check the secret-injection step so it fails loud when required secrets are missing.
Reference implementation: orbstack-kubernetes/docker/actions-runner/ — see that repo’s Makefile runner-* targets and TESTING.md.

Where to go next

Git signing

Identity per execution context and the App-token pattern that signs every AI-authored commit.

terraform-runs-on

The RunsOn runner pool itself — provisioning, OIDC trust, migration guide.

Terraform check placement

Static checks in pre-commit, credentialed operations in CI via OIDC.

CI/CD overview

Runner tiers in context, plan/apply gating, branch rulesets.