mirror of
https://github.com/jmcorgan/fips.git
synced 2026-10-05 19:18:25 +00:00
Not one action reference in this repository was pinned. Every uses: line named a mutable tag, and one named a branch. That includes the jobs holding the AUR deploy key, the jobs with release write scope, and the packaging jobs that run with a signing key in the environment, so whoever controls one of those action repositories could repoint a tag into a job holding our credentials. Sixty-two of the sixty-six references are now full commit SHAs with the original tag kept as a trailing comment, so a reader can still tell which release a pin is. Each SHA was resolved from the upstream peeled tag. Four references are left unpinned and justified in one place rather than silently: two actions select the tool they install from the ref name itself, so a bare SHA hands them a hex string where a toolchain name belongs and the step fails. Pinning those means moving the selection into with:, which changes what resolves, and that is a separate decision from pinning. A guard enforces the form on every sweep, wired into the parity job and the local runner beside the existing checkers. It accepts only owner/repo@40-hex with a mandatory trailing comment, treats an unreadable tree as exit 2 rather than as a pass, and its header names what it does not cover: the actions that pinned actions themselves invoke, the pip and cargo installs that are version pinned at best, and anything fetched at run time. The sharper hole was not the tags. The OpenWrt packaging workflow fetched a helper binary straight from a release URL with no verification, in two jobs that hold a signing key, which is code execution from a third-party host into a credentialed job and needs nobody to retag anything. That download now goes through a shared script with per-architecture pinned SHA-256 constants, modelled on the zig block already in that workflow. Upstream publishes no checksum document, so the provenance comment records the asset URL and the date the hashes were taken by downloading rather than pretending they were verified against a published sum.
204 lines
8.5 KiB
YAML
204 lines
8.5 KiB
YAML
name: AUR Publish
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- master
|
|
- maint
|
|
- next
|
|
tags:
|
|
- 'v*'
|
|
pull_request:
|
|
workflow_dispatch:
|
|
inputs:
|
|
tag:
|
|
description: 'Release tag to publish (e.g. v0.4.0). Defaults to the tag the workflow was dispatched from.'
|
|
required: false
|
|
default: ''
|
|
pkgrel:
|
|
description: 'AUR pkgrel to publish. Use 2+ for packaging-only republishes of an existing tag.'
|
|
required: false
|
|
default: '1'
|
|
|
|
jobs:
|
|
# ───────────────────────────────────────────────────────────────────────────
|
|
# Build + lint the AUR package on every trigger, matching the coverage the
|
|
# other package workflows (linux/macos/windows/openwrt) give their artifacts:
|
|
# branch pushes, pull requests, tags, and manual dispatch. Uses makepkg +
|
|
# namcap in an Arch container (neither tool exists on ubuntu-latest) and builds
|
|
# the *checked-out tree* from a local git-archive tarball, so it works for
|
|
# branch/PR builds and unreleased rc tags whose GitHub source archive does not
|
|
# exist yet. This job never publishes.
|
|
# ───────────────────────────────────────────────────────────────────────────
|
|
aur-build:
|
|
name: Build and lint fips AUR package
|
|
runs-on: ubuntu-latest
|
|
container: archlinux:base-devel
|
|
|
|
steps:
|
|
- name: Install build and lint tooling
|
|
run: |
|
|
set -euo pipefail
|
|
pacman -Sy --noconfirm --needed base-devel namcap git curl
|
|
|
|
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
|
|
|
|
- name: Resolve package version
|
|
id: ver
|
|
env:
|
|
INPUT_TAG: ${{ inputs.tag }}
|
|
INPUT_PKGREL: ${{ inputs.pkgrel }}
|
|
run: |
|
|
set -euo pipefail
|
|
if [ -n "${INPUT_TAG:-}" ]; then
|
|
RAW="${INPUT_TAG#v}"
|
|
elif [ "${GITHUB_REF_TYPE:-}" = "tag" ]; then
|
|
RAW="${GITHUB_REF_NAME#v}"
|
|
else
|
|
# Branch push / PR: derive the version from the crate manifest.
|
|
RAW=$(grep -m1 '^version' Cargo.toml | sed -E 's/.*"([^"]+)".*/\1/')
|
|
fi
|
|
# makepkg forbids '-' in pkgver; map e.g. 0.4.0-rc1 -> 0.4.0rc1,
|
|
# 0.4.0-dev -> 0.4.0dev. The build only needs an internally consistent
|
|
# pkgver (it matches the git-archive prefix below); this is not the
|
|
# value the real publish uses.
|
|
VERSION="${RAW//-/}"
|
|
PKGREL="${INPUT_PKGREL:-1}"
|
|
case "$PKGREL" in
|
|
''|*[!0-9]*|0) echo "pkgrel '$PKGREL' must be a positive integer"; exit 1 ;;
|
|
esac
|
|
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
|
|
echo "pkgrel=${PKGREL}" >> "$GITHUB_OUTPUT"
|
|
echo "Resolved AUR pkgver=${VERSION} pkgrel=${PKGREL}"
|
|
|
|
- name: Create non-root build user and fix ownership
|
|
run: |
|
|
set -euo pipefail
|
|
# makepkg refuses to run as root; create an unprivileged build user
|
|
# with passwordless sudo (needed for pacman dep installs during -s).
|
|
useradd -m -s /bin/bash builder
|
|
echo 'builder ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/builder
|
|
chmod 0440 /etc/sudoers.d/builder
|
|
# The checkout is owned by root; hand it to the build user.
|
|
chown -R builder:builder "$GITHUB_WORKSPACE"
|
|
|
|
- name: Build a local source tarball of the checkout
|
|
env:
|
|
VERSION: ${{ steps.ver.outputs.version }}
|
|
run: |
|
|
set -euo pipefail
|
|
# The PKGBUILD source= points at GitHub archive/<tag>.tar.gz, which does
|
|
# not exist for a branch push, a PR, or an unreleased rc tag and would
|
|
# 404. Instead build the checked-out tree by packing it into a local
|
|
# tarball whose top-level directory matches what the PKGBUILD expects
|
|
# ("fips-<pkgver>/"); patch-pkgbuild.sh repoints source= at it.
|
|
TARBALL="packaging/aur/fips-${VERSION}.tar.gz"
|
|
git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
|
git -C "$GITHUB_WORKSPACE" archive --format=tar.gz \
|
|
--prefix="fips-${VERSION}/" -o "$TARBALL" HEAD
|
|
chown builder:builder "$TARBALL"
|
|
ls -l "$TARBALL"
|
|
|
|
- name: Patch PKGBUILD
|
|
env:
|
|
TAG: v${{ steps.ver.outputs.version }}
|
|
VERSION: ${{ steps.ver.outputs.version }}
|
|
PKGREL: ${{ steps.ver.outputs.pkgrel }}
|
|
run: |
|
|
set -euo pipefail
|
|
LOCAL_TARBALL="packaging/aur/fips-${VERSION}.tar.gz" \
|
|
bash packaging/aur/patch-pkgbuild.sh
|
|
chown builder:builder packaging/aur/PKGBUILD
|
|
|
|
- name: makepkg build and namcap lint (as build user)
|
|
run: |
|
|
set -euo pipefail
|
|
sudo -u builder bash -euo pipefail -c '
|
|
cd packaging/aur
|
|
echo "::group::namcap PKGBUILD"
|
|
namcap PKGBUILD
|
|
echo "::endgroup::"
|
|
echo "::group::makepkg build"
|
|
# --nocheck: skip the PKGBUILD check() (cargo test --lib); the test
|
|
# suite is already covered by ci.yml. This job validates packaging.
|
|
makepkg -s --noconfirm --nocheck
|
|
echo "::endgroup::"
|
|
echo "::group::namcap built package"
|
|
for pkg in *.pkg.tar.*; do
|
|
echo "namcap $pkg"
|
|
namcap "$pkg"
|
|
done
|
|
echo "::endgroup::"
|
|
'
|
|
|
|
# ───────────────────────────────────────────────────────────────────────────
|
|
# Publish to the AUR. Runs only on a real (non-prerelease) release tag push,
|
|
# or a manual dispatch (packaging-only republish with explicit tag + pkgrel).
|
|
# Branch pushes and pull requests build+lint above but never reach this job.
|
|
# Gated on aur-build so a package that fails to build/lint is never published.
|
|
# ───────────────────────────────────────────────────────────────────────────
|
|
aur-publish-fips:
|
|
name: Publish fips to AUR
|
|
needs: aur-build
|
|
runs-on: ubuntu-latest
|
|
if: >-
|
|
github.event_name == 'workflow_dispatch'
|
|
|| (github.event_name == 'push'
|
|
&& startsWith(github.ref, 'refs/tags/v')
|
|
&& !contains(github.ref_name, '-'))
|
|
|
|
steps:
|
|
- name: Resolve release tag
|
|
id: tag
|
|
env:
|
|
INPUT_TAG: ${{ inputs.tag }}
|
|
INPUT_PKGREL: ${{ inputs.pkgrel }}
|
|
run: |
|
|
set -euo pipefail
|
|
TAG="${INPUT_TAG:-$GITHUB_REF_NAME}"
|
|
PKGREL="${INPUT_PKGREL:-1}"
|
|
case "$TAG" in
|
|
v*) ;;
|
|
*) echo "Tag '$TAG' does not look like a release tag (vX.Y.Z)"; exit 1 ;;
|
|
esac
|
|
case "$PKGREL" in
|
|
''|*[!0-9]*|0) echo "pkgrel '$PKGREL' must be a positive integer"; exit 1 ;;
|
|
esac
|
|
case "$TAG" in
|
|
*-*)
|
|
if [ "$GITHUB_EVENT_NAME" != "workflow_dispatch" ]; then
|
|
echo "Pre-release tag '$TAG' — skipping AUR publish"
|
|
exit 1
|
|
fi
|
|
;;
|
|
esac
|
|
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
|
|
echo "version=${TAG#v}" >> "$GITHUB_OUTPUT"
|
|
echo "pkgrel=${PKGREL}" >> "$GITHUB_OUTPUT"
|
|
|
|
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
|
|
with:
|
|
ref: ${{ steps.tag.outputs.tag }}
|
|
|
|
- name: Patch PKGBUILD with pkgver, pkgrel, conflicts, and b2sums
|
|
env:
|
|
TAG: ${{ steps.tag.outputs.tag }}
|
|
VERSION: ${{ steps.tag.outputs.version }}
|
|
PKGREL: ${{ steps.tag.outputs.pkgrel }}
|
|
run: bash packaging/aur/patch-pkgbuild.sh
|
|
|
|
- name: Publish to AUR
|
|
uses: KSXGitHub/github-actions-deploy-aur@abe8ac26b51011c88be58c8809fd2ac674068ea5 # v4.1.2
|
|
with:
|
|
pkgname: fips
|
|
pkgbuild: packaging/aur/PKGBUILD
|
|
updpkgsums: false
|
|
assets: |
|
|
packaging/aur/fips.sysusers
|
|
packaging/aur/fips.tmpfiles
|
|
packaging/aur/fips.install
|
|
commit_username: ${{ github.repository_owner }}
|
|
commit_email: ${{ secrets.AUR_EMAIL }}
|
|
ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
|
|
commit_message: "Update to ${{ steps.tag.outputs.tag }}"
|