ci: build variants in a shell loop, not a dynamic matrix
Some checks failed
build image / build (push) Has been cancelled
Some checks failed
build image / build (push) Has been cancelled
The first run produced one job leg with an empty variant, and the build rejected it. The prepare job was fine — it set variants=["minimal"] and the output evaluated correctly — but Gitea's runner resolves strategy.matrix while planning the workflow, before `needs` has produced anything, so fromJSON(needs.prepare.outputs.variants) saw an empty string. Dynamic matrices from needs outputs are not supported here. Drop the prepare job and loop in shell instead: one job, no expression-engine dependency, and a non-zero exit only after every requested variant has been attempted. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XWRjNJMistCy6ngXH5aJLS
This commit is contained in:
@@ -13,35 +13,21 @@ on:
|
||||
default: minimal
|
||||
options: [minimal, workstation, both]
|
||||
|
||||
jobs:
|
||||
# Which variants to build. Pushes and PRs build minimal only — it is the fast
|
||||
# one and it exercises the entire pipeline. Tags build everything.
|
||||
prepare:
|
||||
runs-on: metal
|
||||
outputs:
|
||||
variants: ${{ steps.pick.outputs.variants }}
|
||||
steps:
|
||||
- id: pick
|
||||
run: |
|
||||
if [ "${{ startsWith(github.ref, 'refs/tags/') }}" = "true" ]; then
|
||||
variants='["minimal","workstation"]'
|
||||
else
|
||||
case "${{ inputs.variant }}" in
|
||||
both) variants='["minimal","workstation"]' ;;
|
||||
workstation) variants='["workstation"]' ;;
|
||||
*) variants='["minimal"]' ;;
|
||||
esac
|
||||
fi
|
||||
echo "variants=$variants" | tee -a "$GITHUB_OUTPUT"
|
||||
# Deliberately no strategy.matrix here.
|
||||
#
|
||||
# The obvious shape for this is a `prepare` job emitting a JSON list and a
|
||||
# matrix built from `fromJSON(needs.prepare.outputs.variants)`. Gitea's runner
|
||||
# evaluates strategy.matrix when it plans the workflow — before `needs` has run
|
||||
# — so that expression resolves to an empty string and you get exactly one job
|
||||
# leg with an empty variant. The prepare job succeeds and sets its output
|
||||
# correctly; the matrix simply never sees it.
|
||||
#
|
||||
# Looping in shell is less elegant and entirely reliable.
|
||||
|
||||
jobs:
|
||||
build:
|
||||
needs: prepare
|
||||
runs-on: metal
|
||||
timeout-minutes: 600
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
variant: ${{ fromJSON(needs.prepare.outputs.variants) }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@@ -79,39 +65,65 @@ jobs:
|
||||
# that has not built before starts cold.
|
||||
- name: Prepare persistent build state
|
||||
run: |
|
||||
echo "CACHE_DIR=/var/tmp/c630-build/dnf" >> "$GITHUB_ENV"
|
||||
echo "WORK_DIR=/var/tmp/c630-build/work" >> "$GITHUB_ENV"
|
||||
mkdir -p /var/tmp/c630-build/{dnf,work}
|
||||
echo "CACHE_DIR=/var/tmp/c630-build/dnf" >> "$GITHUB_ENV"
|
||||
echo "WORK_DIR=/var/tmp/c630-build/work" >> "$GITHUB_ENV"
|
||||
mkdir -p /var/tmp/c630-build/dnf /var/tmp/c630-build/work
|
||||
# Keep it bounded: drop cached rpms nothing has touched in a month.
|
||||
find /var/tmp/c630-build/dnf -type f -atime +30 -delete 2>/dev/null || true
|
||||
du -sh /var/tmp/c630-build/* 2>/dev/null || true
|
||||
|
||||
- name: Select variants
|
||||
run: |
|
||||
if [ "${{ startsWith(github.ref, 'refs/tags/') }}" = "true" ]; then
|
||||
variants="minimal workstation"
|
||||
else
|
||||
case "${{ inputs.variant }}" in
|
||||
both) variants="minimal workstation" ;;
|
||||
workstation) variants="workstation" ;;
|
||||
*) variants="minimal" ;;
|
||||
esac
|
||||
fi
|
||||
echo "VARIANTS=$variants" | tee -a "$GITHUB_ENV"
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
case "${{ matrix.variant }}" in
|
||||
workstation) size=16384 ;;
|
||||
*) size=8192 ;;
|
||||
esac
|
||||
# No --fresh: the stamp in stage2.sh hashes the package lists, so a
|
||||
# change there invalidates the staged base on its own. Checkout is
|
||||
# shallow here anyway, so diffing against HEAD~1 would not be reliable.
|
||||
./build/build-image.sh \
|
||||
--variant "${{ matrix.variant }}" \
|
||||
--size "$size" \
|
||||
--cache "$CACHE_DIR" \
|
||||
--work "$WORK_DIR"
|
||||
rc=0
|
||||
for variant in $VARIANTS; do
|
||||
case "$variant" in
|
||||
workstation) size=16384 ;;
|
||||
*) size=8192 ;;
|
||||
esac
|
||||
echo "::group::build $variant (${size} MiB)"
|
||||
# No --fresh: the stamp in stage2.sh hashes the package lists, so a
|
||||
# change there invalidates the staged base on its own.
|
||||
if ./build/build-image.sh \
|
||||
--variant "$variant" \
|
||||
--size "$size" \
|
||||
--cache "$CACHE_DIR" \
|
||||
--work "$WORK_DIR"; then
|
||||
echo "$variant ok"
|
||||
else
|
||||
echo "::error::build failed for $variant"
|
||||
rc=1
|
||||
fi
|
||||
echo "::endgroup::"
|
||||
done
|
||||
exit $rc
|
||||
|
||||
- name: Checksums
|
||||
run: cat output/*.sha256
|
||||
if: always()
|
||||
run: cat output/*.sha256 2>/dev/null || echo "no images produced"
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: fedora-${{ matrix.variant }}-lenovo-yoga-c630
|
||||
name: fedora-lenovo-yoga-c630
|
||||
path: |
|
||||
output/*.img.zst
|
||||
output/*.sha256
|
||||
retention-days: 14
|
||||
compression-level: 0 # already zstd
|
||||
if-no-files-found: warn
|
||||
|
||||
- name: Attach to release
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
|
||||
Reference in New Issue
Block a user