GitHub Actions 🎬¢

This page catalogs every GitHub Actions workflow defined under the workflows directory. It lists each workflow together with a short description, its triggers, and the inputs it accepts.

For the CI flow (orchestrator stages, gates, fork-PR handling) see pipeline.md. For the repository variables that control CI behaviour see configuration.md. For the naming and shell-extraction conventions that every workflow file MUST follow see workflow.md. For the branch-prefix scopes referenced by the PR entry workflow see branch.md. For the mirror architecture referenced by the image workflows see mirror.md.

What GitHub Actions are πŸ“˜ΒΆ

GitHub Actions is GitHub’s built-in CI/CD system. Each YAML file under .github/workflows/ is one workflow; a workflow contains one or more jobs, and each job runs a sequence of steps on a hosted or self-hosted runner. Workflows are started by triggers declared in the on: section. The most common triggers in this repository are:

  • push: fires when commits land on a branch.

  • pull_request / pull_request_target: fires on PR lifecycle events (opened, synchronize, reopened, ready_for_review, closed, converted_to_draft). The _target variant runs with the base-branch secrets and is used to grant fork PRs controlled access to privileged steps.

  • schedule: cron-based periodic runs (UTC).

  • workflow_dispatch: manual run from the GitHub UI or gh workflow run, optionally with inputs.

  • workflow_call: the workflow is a reusable workflow and is only started by another workflow that calls it via uses:.

  • delete: fires when a branch or tag is deleted.

Workflows communicate through inputs (on workflow_call / workflow_dispatch), outputs, concurrency groups (which cancel or serialize runs with the same group key), and the GITHUB_TOKEN / repository secrets and variables. The entry points of this repository (entry-*.yml) translate external triggers into a call to the central call-orchestrator.yml. Most other workflows are reusable building blocks invoked from the orchestrator.

Workflow catalog πŸ“šΒΆ

Trigger column legend: auto = fires automatically (push, pull_request, schedule, delete); manual = workflow_dispatch; reusable = workflow_call. Multiple values mean the workflow accepts any of them.

Entry points πŸšͺΒΆ

Workflow

Description

Trigger

Inputs

entry-pr-change-orchestrate.yml: πŸ”€ Pull Request

Detects PR scope from changed files + branch prefix, then conditionally calls the orchestrator. A maintainer πŸ›‘οΈ Trusted label builds the privileged images from the PR head β€” see pipeline.md. A 🧩 Subset label pins the deploy matrix to the roles listed in the PR body β€” see pipeline.md.

auto (pull_request & pull_request_target: opened, synchronize, reopened, ready_for_review, labeled)

none

entry-push-latest.yml: πŸ“€ Push

Syncs main from the configured source repository, then runs the orchestrator on pushes to main, feature/**, hotfix/**, fix/**, update/**, chore/**, alert-autofix-*; on tagged main it also calls call-release-version.yml. Respects the CI_SYNC_MAIN_SOURCE_REPOSITORY and CI_RUN_ON_MAIN repository variables, see configuration.md.

auto (push)

none

entry-manual-steer.yml: πŸ•ΉοΈ Manual

Manual dispatch of the full orchestrator for a chosen app whitelist. The whitelist input accepts the __ALL__ sentinel for forced full deploy; see the β€œDiff-driven app selection” subsection in pipeline.md.

manual

distros (optional; empty spreads the rows over every declared distro), filesystem (optional; empty spreads them over zfs, btrfs, ext4), whitelist (optional; __ALL__ forces full deploy, empty triggers diff derivation, any other value is verbatim), lifecycles, mode (default auto), priority (optional; priority rows get chunks of their own, the regular chunks run after them), offset (default 0; a row count or a selection token naming where the regular line resumes), chunk_gate (default true), sweep (optional; empty means the run number)

entry-cancel-superseded.yml: 🚫 Cancel: Superseded Runs

Cancels the runs superseded by a newer one on the same branch or PR via the API, for the case where the concurrency group fails to reap its occupant and the newer run parks on pending behind it β€” see cancel/README.md. Carries no concurrency group of its own, otherwise it would queue behind the run it has to free, and only touches the workflows that share the group it backs up. The push job skips main like the global-ci-* group it backs up, see configuration.md.

auto (push except main, pull_request_target: opened, synchronize, reopened, ready_for_review, labeled)

none

entry-pr-closed-cancel-workflows.yml: 🚫 Cancel: PR Runs on Close

Cancels active workflow runs for a PR when it is closed or converted to draft.

auto (pull_request_target: closed, converted_to_draft)

none

entry-delete-branch.yml: 🚫 Cancel: Runs on Branch Delete

Enters the push-entry concurrency group for the deleted branch so that any in-flight run on it is cancelled; a fallback step cancels remaining runs via the API.

auto (delete)

none

Orchestration 🎡¢

Workflow

Description

Trigger

Inputs

call-orchestrator.yml: 🎡 CI: Orchestrator

Central coordinator. Runs fork-prereq wait, security, linting, CI image build, code tests, code-quality gate, DNS tests, mirror, deploy tests as a serial chain of chunk blocks (each chunk’s discover job renders the sweep’s plan table via cli.meta.ci.plan into the run summary), install tests, test-workspace, final done gate.

reusable

distros (optional; empty spreads the rows over every declared distro), filesystem (optional; empty spreads them over zfs, btrfs, ext4), whitelist (optional), priority (optional; app ids sorted to the head of the list and cut into chunks of their own, so every priority row is deployed before the first regular one starts, and deployed in every combination it can take: each variant Γ— each offered mode Γ— Tor and clearnet, in one sweep), mode (default auto), sweep, resume_from_chunk (default 0), chunk_gate (default true), image_wait_attempts (default 1980), image_wait_sleep_seconds (default 10), workspace (default auto)

Security and linting πŸ›‘οΈπŸ”ΒΆ

Workflow

Description

Trigger

Inputs

cron-security-codeql.yml: πŸ” Scan with CodeQL

CodeQL static analysis. Invoked by call-orchestrator.yml so every CI run produces a single scan; additionally runs on a weekly cron so coverage does not drop when no pushes land on main. See pipeline.md for the gating behaviour.

reusable, auto (schedule: weekly Mon 00:00 UTC)

none

cron-security-fuzz.yml: 🧬 Fuzz parsers

Runs the atheris harness _yaml_bootstrap.py for 15 minutes and uploads every crashing input as the fuzz-crashes artifact. Reproduce one locally with pip install -e ".[fuzz]" and python3 tests/fuzz/_yaml_bootstrap.py <crash-file>.

auto (schedule: weekly Sun 04:00 UTC), manual

none

call-lint.yml: 🧹 Lint

Runs make lint (every lint check in parallel: action, ansible, css, dockerfile, javascript, makefile, markdown, mermaid, packages, php, playwright, python, ruby, shellcheck, sql). Hadolint checks Dockerfile as lint-dockerfile and uploads no SARIF.

reusable, manual

none

CI images 🐳¢

Workflow

Description

Trigger

Inputs

call-images-build-ci.yml: πŸ–ΌοΈ Build: CI Images (all distros)

Builds the per-distro CI base images consumed by all test jobs.

reusable

distros (required), checkout_ref (optional), image_tag (default ci-${github.sha}), concurrency_channel (default default)

cron-images-cleanup-ci.yml: 🧹 Prune CI images

Deletes CI images from GHCR older than N days.

auto (schedule: weekly Mon 00:00 UTC), manual

days (default 7)

Image mirroring πŸͺžΒΆ

Workflow

Description

Trigger

Inputs

call-images-mirror-missing.yml: πŸͺž Mirror: Docker Hub β†’ GHCR (only missing)

Mirrors only the upstream images that are not yet in GHCR. Called from the orchestrator before deploy tests.

reusable

ghcr_namespace, ghcr_prefix (default mirror), repo_root (default .), source_repository, source_ref, plus throttling knobs

cron-images-mirror-all.yml: πŸͺž Mirror all images

Full nightly mirror of every referenced upstream image into GHCR.

auto (schedule: daily 00:00 UTC), manual

ghcr_namespace, ghcr_prefix (default mirror), repo_root (default .), images_per_hour (throttle)

entry-manual-mirror-cleanup.yml: 🧹 Images: Cleanup GHCR

Deletes GHCR mirror packages by prefix and visibility. Supports dry_run.

manual

ghcr_namespace, ghcr_prefix (default mirror), visibility (private/public/internal, default private), dry_run

Code tests πŸ§ͺΒΆ

Workflow

Description

Trigger

Inputs

call-test.yml: πŸ§ͺ Test

Runs make test (unit, integration, lint and external tests in parallel) on the runner host.

reusable, manual

none

Infrastructure tests πŸŒπŸ“¦πŸ’»πŸ“₯ΒΆ

Workflow

Description

Trigger

Inputs

call-test-dns.yml: πŸ’¬ Test: DNS

Validates DNS resolution across target distributions.

reusable, manual

distros (required on call; default debian on manual)

call-test-deploy.yml: πŸš€ Test: Deploy

Deploys one chunk of the sweep. Every matrix row is a single role#variant carrying the deploy mode, onion state, distro and filesystem the rotation assigned it: swarm rows get a simulated 3-node DinD cluster with an NFS server plus a drain/reschedule state-survival assertion, compose and host rows run the single-node drill. When whitelist is empty, the discover job derives one from the branch’s diff vs origin/main; see the β€œDiff-driven app selection” subsection in pipeline.md. A row marked πŸ“– – the role’s smallest variant, see instructions.md – replays the role README’s ### Production block on the same runner once the deploy has released it.

reusable

index, sweep (required), distros (optional pool), filesystem (optional pool), whitelist (optional; explicit value wins over diff), priority, lifecycles, modes (default auto), tor, marker

call-test-install-make.yml: πŸ“₯ Test: Install Make

Validates the make install entry points.

reusable

none

call-test-install-pkgmgr.yml: πŸ“₯ Test: Install Package Manager

Validates installation via the upstream package manager.

reusable

none

call-test-workspace.yml: πŸ’» Test: Workspace

Builds and exercises the dev-runtime image matrix.

reusable, manual

none

Release and maintenance πŸš€πŸ”„ΒΆ

Workflow

Description

Trigger

Inputs

call-release-version.yml: πŸš€ Release: Version Logic

Releases a specific version tag (build + publish). Called from entry-push-latest.yml on tagged pushes.

reusable, manual

tag (required, e.g. v1.2.3)

cron-release-highest.yml: πŸš€ Release missing tag

Scheduled backfill: finds the highest tag without a release and triggers call-release-version.yml for it.

auto (schedule: daily 00:00 UTC), manual

none

cron-cleanup-stale.yml: 🧹 Prune stale data

Marks and closes stale issues and PRs, deletes inactive branches, and prunes old GHCR CI image versions.

auto (schedule: daily 00:00 UTC), manual

none

cron-update.yml: πŸ”„ Update versions

Updates Docker image versions and other pinned dependencies; opens an update PR via a GitHub App installation token so PR-lifecycle events fire on the resulting PR. Both jobs are gated behind the CI_ENABLE_AUTO_UPDATES repository variable, see configuration.md. Requires the BOT_APP_CLIENT_ID and BOT_APP_PRIVATE_KEY repository secrets, see secrets.md.

auto (push to main, schedule: daily 00:30 UTC), manual

none

entry-pr-open-dependabot-close.yml: 🚫 Dependabot: Close while auto-updates disabled

Auto-closes Dependabot PRs while CI_ENABLE_AUTO_UPDATES is not set to true, so Dependabot honours the same gate as the workflow-driven update jobs. See configuration.md.

auto (pull_request_target: opened, reopened)

none

Changing workflows ✍️¢

Before adding or editing a workflow file:

  1. Follow the naming schema and shell-extraction rules in workflow.md.

  2. If the change affects the CI flow (stages, gates, order), also update pipeline.md.

  3. If the change adds or removes a repository variable, also update configuration.md.

  4. Update the relevant row in this page so the catalog stays accurate.