diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 843b2e1..664e3ac 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -102,6 +102,69 @@ jobs: - name: Test packed-package fixtures run: npm run test:fixtures + artifact-pack: + name: Pack the CI artifact + runs-on: ubuntu-latest + timeout-minutes: 15 + outputs: + sha256: ${{ steps.pack.outputs.sha256 }} + steps: + - name: Check out the repository + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - name: Set up Node.js 24 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: 24.x + cache: npm + - name: Install locked dependencies + run: npm ci + - name: Pack exactly one artifact + id: pack + shell: bash + run: | + set -euo pipefail + mkdir -p ci-artifacts + npm pack --pack-destination ci-artifacts + mapfile -t tarballs < <(find ci-artifacts -maxdepth 1 -type f -name '*.tgz' -print) + if [[ "${#tarballs[@]}" -ne 1 ]]; then + echo "Expected exactly one packed artifact, found ${#tarballs[@]}." >&2 + exit 1 + fi + echo "sha256=$(sha256sum "${tarballs[0]}" | awk '{ print $1 }')" >> "$GITHUB_OUTPUT" + - name: Upload the packed artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: ci-npm-package + path: ci-artifacts/*.tgz + if-no-files-found: error + + artifact-download: + name: Verify the CI artifact round-trip + needs: + - artifact-pack + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - name: Download the packed artifact by name + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: ci-npm-package + path: ci-artifacts + - name: Verify the unique artifact and its digest + env: + EXPECTED_SHA256: ${{ needs.artifact-pack.outputs.sha256 }} + shell: bash + run: | + set -euo pipefail + mapfile -t tarballs < <(find ci-artifacts -maxdepth 1 -type f -name '*.tgz' -print) + if [[ "${#tarballs[@]}" -ne 1 ]]; then + echo "Expected exactly one downloaded artifact, found ${#tarballs[@]}." >&2 + exit 1 + fi + echo "$EXPECTED_SHA256 ${tarballs[0]}" | sha256sum --check --strict + minimum-openai: name: Minimum OpenAI / Node.js 22 runs-on: ubuntu-latest diff --git a/tests/ci-workflow.test.mjs b/tests/ci-workflow.test.mjs index d904bc0..050abb3 100644 --- a/tests/ci-workflow.test.mjs +++ b/tests/ci-workflow.test.mjs @@ -122,4 +122,29 @@ describe("blocking CI workflow", () => { run: "npm run test:live-contract", }); }); + + it("round-trips one packed artifact across separate jobs", () => { + const jobs = readWorkflow().jobs; + const pack = jobs?.["artifact-pack"]; + const download = jobs?.["artifact-download"]; + + expect(pack?.outputs).toEqual({ + sha256: "${{ steps.pack.outputs.sha256 }}", + }); + expect(download?.needs).toEqual(["artifact-pack"]); + expect(pack.steps.some((step) => step.run?.includes("npm pack"))).toBe( + true, + ); + expect( + pack.steps.some((step) => + step.uses?.startsWith("actions/upload-artifact@"), + ), + ).toBe(true); + expect( + download.steps.some((step) => + step.uses?.startsWith("actions/download-artifact@"), + ), + ).toBe(true); + expect(download.steps.at(-1).run).toContain("sha256sum --check --strict"); + }); });