CI/CD Pipeline for apple/container: GitHub Actions Workflow Explained
The apple/container project uses a GitHub Actions-based CI/CD pipeline where three workflow files orchestrate builds, tests, and releases by delegating to a shared common.yml configuration executed on self-hosted macOS runners.
The apple/container repository automates its software delivery through a comprehensive CI/CD pipeline defined in the .github/workflows/ directory. This pipeline validates every contribution through automated checks and produces signed release artifacts for Apple's containerization framework. All workflow jobs execute on self-hosted macOS runners with Apple Silicon architecture to ensure native ARM64 compatibility.
Workflow Architecture Overview
The CI/CD pipeline employs a modular design pattern that separates event triggers from implementation logic. Three entry-point workflows—pr-build.yml, merge-build.yml, and release.yml—handle specific Git events while delegating execution to .github/workflows/common.yml. This architecture eliminates duplication and ensures consistent build behavior across different trigger types.
The Three Entry-Point Workflows
PR Build (pr-build.yml)
Located at .github/workflows/pr-build.yml, this workflow triggers on pull_request events (opened, reopened, synchronize). It executes two sequential jobs: first, a signature verification step that validates all commits are cryptographically signed, followed by the shared build and test workflow. The workflow passes release: false and coverage: true to the common configuration.
name: container project - PR build
on:
pull_request:
types: [opened, reopened, synchronize]
jobs:
verify-signatures:
runs-on: ubuntu-latest
steps:
- name: Check all commits are signed
env:
GH_TOKEN: ${{ github.token }}
REPO: ${{ github.repository }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
commits=$(gh api "repos/${REPO}/pulls/${PR_NUMBER}/commits" --paginate)
# ... loop that fails on unsigned commits ...
build:
uses: ./.github/workflows/common.yml
with:
release: false
coverage: true
pr_number: ${{ github.event.pull_request.number }}
Merge Build (merge-build.yml)
The .github/workflows/merge-build.yml workflow activates on push events to the main branch or any release/* branch. It invokes common.yml with release: true to ensure merged code produces releasable artifacts and passes all integration tests.
Release Build (release.yml)
Triggered exclusively by version tags matching the vX.Y.Z pattern, .github/workflows/release.yml coordinates production releases. After executing the shared build logic with release configuration, it uses the softprops/action-gh-release action to create a draft GitHub release marked as prerelease, attaching the built .pkg and .zip artifacts.
Shared Build Logic in common.yml
The pipeline's core implementation resides in .github/workflows/common.yml, which executes on runs-on: [self-hosted, macos, tahoe, ARM64]. This workflow accepts boolean inputs including release, coverage, and pr_number to customize behavior.
The shared workflow executes the following stages:
- Checkout - Retrieves full repository history using
actions/checkout@v7withfetch-depth: 0 - Formatting Verification - Executes
make fmtafter installing the Hawkeye formatter viascripts/install-hawkeye.sh, failing if uncommitted changes exist - Protobuf Validation - Runs
make protosto ensure generated code is synchronized with source definitions - Configuration - Sets the
BUILD_CONFIGURATIONenvironment variable todebugorreleasebased on theinputs.releasevalue - Compilation - Executes
make container dsym docsto build the binary, debug symbols, and documentation, then archives the site as_site.tgz - Testing - Runs
make test install-kernel integration integration-newfor standard validation, ormake coverage-newwhen coverage analysis is requested - Coverage Processing - Extracts line-coverage percentages and archives HTML reports when enabled
- Artifact Packaging - Bundles
container-installer-unsigned.pkgand dSYM archives for distribution - Log Collection - Gathers container logs from temporary test directories and uploads them for debugging
jobs:
buildAndTest:
runs-on: [self-hosted, macos, tahoe, ARM64]
steps:
- name: Checkout repository
uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Check formatting
run: |
./scripts/install-hawkeye.sh
make fmt
if ! git diff --quiet -- . ; then
echo "❌ Formatting required"
false
fi
- name: Set build configuration
env:
RELEASE: ${{ inputs.release }}
run: |
echo "BUILD_CONFIGURATION=debug" >> $GITHUB_ENV
if [[ "${RELEASE}" == "true" ]]; then
echo "BUILD_CONFIGURATION=release" >> $GITHUB_ENV
fi
- name: Make the container project and docs
run: |
make container dsym docs
tar cfz _site.tgz _site
Signature Verification and Security
Before compilation begins, the PR workflow enforces cryptographic signing requirements through a dedicated verification job. A Bash script queries the GitHub API using the gh CLI to enumerate commits in the pull request, inspecting the verification.verified field for each entry. If any commit lacks a valid signature, the script exits with an error, preventing unsigned code from entering the build pipeline.
Release Publishing Process
When a maintainer pushes a semantic version tag, the release workflow automatically prepares distribution assets. The process generates a draft release containing the container-installer-unsigned.pkg installer and compressed archives, allowing maintainers to review release notes and assets before publication. The draft status ensures automated tooling does not immediately publicize potentially incomplete releases.
Summary
- The pipeline uses three entry-point workflows (
pr-build.yml,merge-build.yml,release.yml) that delegate to a shared.github/workflows/common.yml - All builds execute on self-hosted macOS ARM64 runners (
[self-hosted, macos, tahoe, ARM64]) for native Apple Silicon compatibility - Mandatory commit signature verification prevents unsigned code from merging via the GitHub API verification check
- The
Makefiledrives build tasks includingmake fmt,make protos,make container, andmake test - Automated drafting of GitHub releases occurs when version tags are pushed, producing
.pkgand.zipartifacts
Frequently Asked Questions
What triggers the CI/CD pipeline in apple/container?
The pipeline triggers on three distinct events: pull request activity (opened, reopened, or synchronized), pushes to main or release/* branches, and pushes of version tags matching semantic versioning patterns. Each event type routes to a specific workflow file optimized for that validation scenario.
Why does apple/container use self-hosted runners instead of GitHub-hosted runners?
The workflow specifies runs-on: [self-hosted, macos, tahoe, ARM64] to ensure builds execute on dedicated Apple Silicon hardware with specific kernel extension capabilities and environment configurations required for testing container functionality on macOS.
How does the pipeline enforce commit signing requirements?
The PR build workflow executes a Bash script that queries the GitHub API for all commits in the pull request, inspecting the verification.verified field. If any commit lacks a valid cryptographic signature, the workflow fails immediately before reaching build or test stages.
What build configurations are supported?
The pipeline supports debug and release configurations controlled by the release input parameter passed to common.yml. Debug builds execute during standard PR validation, while release builds produce optimized binaries, installer packages, and draft GitHub releases.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →