Cache the CI toolchain in a shared action

ci/toolchain installs the pinned tools, collections and rsync from cache for
both GitHub and Gitea; GitLab caches pip downloads. shellcheck now finds
scripts rather than globbing, which broke when a glob matched nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Lucas Winther
2026-09-30 15:16:58 +02:00
co-authored by Claude Opus 5.5
parent 665ac7d52f
commit be0b90b879
13 changed files with 216 additions and 55 deletions
+1 -6
View File
@@ -37,13 +37,8 @@ jobs:
environment: production
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install the pinned toolchain
run: |
set -eu
scripts/check.sh --print-specs | head -1 | xargs -d '\n' pip install --quiet
uses: ./ci/toolchain
- name: Load the deploy key
env:
SSH_KEY_BACKEND: ci
+6 -8
View File
@@ -80,10 +80,6 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
# STACK, MODE and PULL reach a shell command, and under repository_dispatch
# they come from another repository. They go through the environment, never
# through ${{ }} interpolation into a run: block — an expression is
@@ -122,11 +118,13 @@ jobs:
echo "PULL=$PULL"
} >> "$GITHUB_ENV"
# rsync too: ansible.posix.synchronize shells out to it on the machine
# Ansible runs on, not only on the target.
- name: Install the pinned toolchain
run: |
set -eu
scripts/check.sh --print-specs | head -1 | xargs -d '\n' pip install --quiet
ansible-galaxy install -r ansible/requirements.yml
uses: ./ci/toolchain
with:
collections: "true"
rsync: "true"
# Two lines, not `export SSH_KEY_PATH="$(...)"`. export is a special
# builtin, so the compound command reports *its* exit status and swallows
+15 -11
View File
@@ -27,17 +27,15 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
# scripts/check.sh is the single source of the version pins; it prints
# them so that this workflow can install exactly what a contributor runs
# locally. Nothing here can drift from the script.
# scripts/check.sh is the single source of the version pins; the action
# installs exactly what a contributor runs locally, so nothing here can
# drift from `make check`. The collections are cached with it, which
# leaves check.sh's own `ansible-galaxy install` nothing to fetch.
- name: Install the pinned toolchain
run: |
set -eu
scripts/check.sh --print-specs | tee /dev/stderr | xargs -d '\n' pip install --quiet
uses: ./ci/toolchain
with:
specs: all
collections: "true"
- name: Run the static gate
run: RUNNER=installed scripts/check.sh
@@ -52,7 +50,13 @@ jobs:
- name: Install shellcheck
run: command -v shellcheck || sudo apt-get install -y --no-install-recommends shellcheck
- name: Check the shell scripts
run: shellcheck scripts/*.sh server/*/*/app/*.sh
# find rather than a glob. Bash leaves an unmatched pattern alone instead
# of expanding it to nothing, so `server/*/*/app/*.sh` reaches
# shellcheck as a literal filename the moment the last payload script
# goes away, and the job fails with `openBinaryFile: does not exist`.
# `xargs -r` covers the other half: no scripts at all must be a no-op,
# not a shellcheck invocation with no arguments that sits reading stdin.
run: find scripts server -name '*.sh' -print0 | xargs -0 -r shellcheck
secrets:
name: secret scan