diff --git a/.github/actions/setup-deps/action.yml b/.github/actions/setup-deps/action.yml index 8075ac11..649a51e4 100644 --- a/.github/actions/setup-deps/action.yml +++ b/.github/actions/setup-deps/action.yml @@ -43,7 +43,25 @@ runs: ghcr-buildcache oci://ghcr.io/fairrootgroup/fairmq-spack-buildcache echo "::endgroup::" + - name: Resolve lockfile + id: lock + shell: bash + run: | + # Prefer a committed, fully-concretized lockfile so the hashes match the + # binaries the buildcache pushed (guaranteed cache hits, no re-solve). + # Fresh runs (the buildcache itself) must re-concretize, so skip the lock. + lock="test/ci/locks/${{ inputs.env }}-gcc${{ inputs.gcc }}.lock" + if [ "${{ inputs.fresh }}" != "true" ] && [ -f "$lock" ]; then + echo "Using committed lockfile: $lock" + echo "use=true" >> "$GITHUB_OUTPUT" + echo "path=$lock" >> "$GITHUB_OUTPUT" + else + echo "No lockfile for ${{ inputs.env }}-gcc${{ inputs.gcc }}; concretizing from spec" + echo "use=false" >> "$GITHUB_OUTPUT" + fi + - name: Install GCC + if: steps.lock.outputs.use != 'true' shell: spack-bash {0} run: | echo "::group::Install GCC" @@ -53,6 +71,7 @@ runs: echo "::endgroup::" - name: Install dependencies + if: steps.lock.outputs.use != 'true' shell: spack-bash {0} run: | echo "::group::Install dependencies" @@ -60,5 +79,20 @@ runs: spack -e fairmq add gcc@${{ inputs.gcc }} spack -e fairmq config add "packages:all:require:'%gcc@${{ inputs.gcc }}'" spack -e fairmq install --fail-fast ${{ inputs.fresh == 'true' && '--fresh' || '' }} + echo "::endgroup::" + + - name: Install dependencies (from lockfile) + if: steps.lock.outputs.use == 'true' + shell: spack-bash {0} + run: | + echo "::group::Install dependencies (from lockfile)" + spack env create fairmq ${{ steps.lock.outputs.path }} + spack -e fairmq install --fail-fast + echo "::endgroup::" + + - name: Export environment + shell: spack-bash {0} + run: | + echo "::group::Export environment" spack env activate --sh fairmq | grep '^export ' | sed 's/^export //;s/;$//' >> $GITHUB_ENV echo "::endgroup::" diff --git a/.github/workflows/buildcache.yml b/.github/workflows/buildcache.yml index caea9959..26e03cbf 100644 --- a/.github/workflows/buildcache.yml +++ b/.github/workflows/buildcache.yml @@ -50,6 +50,21 @@ jobs: spack -e fairmq mirror set --oci-username ${{ github.actor }} --oci-password-variable GITHUB_TOKEN ghcr-buildcache spack -e fairmq buildcache push --unsigned ghcr-buildcache + - name: Export lockfile + if: ${{ !cancelled() }} + shell: spack-bash {0} + run: | + mkdir -p test/ci/locks + cp "$(spack location -e fairmq)/spack.lock" \ + "test/ci/locks/${{ matrix.env }}-gcc${{ matrix.gcc }}.lock" + + - name: Upload lockfile + if: ${{ !cancelled() }} + uses: actions/upload-artifact@v4 + with: + name: lock-${{ matrix.env }}-gcc${{ matrix.gcc }} + path: test/ci/locks/${{ matrix.env }}-gcc${{ matrix.gcc }}.lock + update-index: if: github.repository == 'FairRootGroup/FairMQ' && !cancelled() needs: build diff --git a/test/ci/locks/README.md b/test/ci/locks/README.md new file mode 100644 index 00000000..1d81ebf1 --- /dev/null +++ b/test/ci/locks/README.md @@ -0,0 +1,21 @@ +# Committed spack lockfiles + +`setup-deps` installs from `-gcc.lock` here when a matching file exists, +skipping concretization so the resolved hashes match the binaries the buildcache +pushed (guaranteed cache hits). When no lockfile is present it falls back to +concretizing from `test/ci/spack-.yaml`. + +## Regenerating + +Lockfiles pin host externals (glibc, system gcc), so they must be concretized on +the same runner image CI uses (`ubuntu-24.04`) — do **not** generate them on a +local machine. + +1. Run the `Spack Buildcache` workflow (push to `dev`/`master` touching the spack + configs, or `workflow_dispatch`). It concretizes fresh (`fresh: 'true'`), + pushes binaries, and uploads each env's `spack.lock` as a `lock--gcc` + artifact. +2. Download the artifacts and commit them here as `-gcc.lock`. + +Regenerate whenever the specs in `test/ci/spack-*.yaml` change or the runner +image is bumped.