Skip to content
m-wells edited this page Feb 21, 2026 · 5 revisions

CI/CD Pipeline

Overview

┌──────────────────────────────────────────────────────────────────┐
│                    watch.yml (every 30 min)                       │
│  Check upstream versions → update PKGBUILDs → push → trigger CI  │
└──────────────────────────────────────────────────────────────────┘
                                │
                                ▼
┌──────────────────────────────────────────────────────────────────┐
│  prepare                                                         │
│  • Lint PKGBUILDs (syntax + source verification)                 │
│  • Auto-repair stale checksums if sources changed upstream       │
│  • Detect changed packages → build matrix                        │
└──────────────────────┬───────────────────────────────────────────┘
                       │
         ┌─────────────┼─────────────┐
         ▼             ▼             ▼
┌──────────────┐ ┌───────────┐ ┌──────────────┐
│    build     │ │build-heavy│ │ aur-publish   │
│ (default)    │ │(dedicated │ │ (independent) │
│              │ │  runner)  │ │               │
└──────┬───────┘ └─────┬─────┘ └──────────────┘
       │               │
       └───────┬───────┘
               ▼
┌──────────────────────────────────────────────────────────────────┐
│  publish                                                         │
│  • Sign packages with GPG                                        │
│  • Update repo database                                          │
│  • Atomic release: draft → upload all assets → publish as latest │
└──────────────────────────────────────────────────────────────────┘

Build and AUR publish run in parallel — neither blocks the other.

Automatic Updates

watch.yml runs every 30 minutes. Each package has a check script in scripts/packages/ that queries the upstream source:

# scripts/packages/gemini-cli.sh
check_npm "gemini-cli" "@google/gemini-cli"

When a new version is found, perform_update (in scripts/lib/common.sh):

  1. Updates pkgver and resets pkgrel in the PKGBUILD
  2. Re-downloads the source and computes new checksums
  3. Commits the change and pushes to main

Available check helpers: check_npm, check_pypi, check_github_release.

Checksum Auto-Repair

Some upstreams (notably npm) can regenerate tarballs after publishing, causing the checksums computed during the update to become stale by the time the build runs.

When lint.sh detects a checksum mismatch:

  1. Runs makepkg -g to regenerate checksums from the files makepkg already downloaded (ensures consistency with makepkg's download agent)
  2. Replaces the checksum array in the PKGBUILD
  3. If any PKGBUILDs were repaired, the prepare job commits and pushes with [skip ci], then records the new HEAD SHA
  4. Downstream jobs (build, publish) checkout that SHA so they get the repaired PKGBUILDs

This prevents stale checksums from blocking the entire pipeline.

Atomic Releases

Releases use a draft-then-publish strategy to avoid partial uploads:

  1. Download all assets from the current latest release
  2. Overlay newly built packages, DB, and signatures
  3. Create a draft release on a timestamped tag (release-YYYYMMDD-HHMMSS)
  4. Upload all assets to the draft
  5. Publish the draft and mark as GitHub's latest release
  6. Clean up old releases (last 3 kept for rollback)

The old release stays live until the new one is fully uploaded. Pacman clients use the releases/latest/download URL, which GitHub resolves to whatever release is currently marked latest.

Dependency Resolution

CI uses yay to resolve dependencies from official repos, AUR, and the local build repo. Packages within the repo are sorted topologically before building so that local dependencies are built first and added to the local repo for subsequent packages.

Target Markers

Marker Behavior
.local Build and publish to GitHub releases
.aur Push PKGBUILD to AUR

Packages can have both markers.

Secrets

Secret Purpose
GPG_PRIVATE_KEY Sign packages
GPG_KEY_ID GPG key identifier
GPG_PASSPHRASE Unlock signing key
AUR_SSH_PRIVATE_KEY Push to AUR git repos
AUR_USERNAME AUR commit author
AUR_EMAIL AUR commit email
GITHUB_TOKEN Upload release assets (auto-provided)

Manual Triggers

Force rebuild all: Actions → "Build packages" → Run workflow → check "Rebuild all packages"

Fix signatures: Actions → "Build packages" → Run workflow → check "Fix database signatures without rebuilding"

Gotchas

Epoch colons in filenames

Packages with epochs produce filenames like gemini-cli-1:0.26.0-1-any.pkg.tar.zst. GitHub Actions can't handle colons in artifact paths, so build.sh renames them (replacing : with .).

Git in containers

The archlinux:base-devel container doesn't include git. Without it, actions/checkout@v4 falls back to downloading a tarball via the GitHub REST API, which produces no .git directory. Git must be installed before the checkout step in every job that needs git operations.

SSH in containers

The archlinux:base-devel container doesn't include openssh. It's installed by setup.sh. AUR publishing uses GIT_SSH_COMMAND to specify the key.

Clone this wiki locally