From 7b40919a56e7e154aea2a93585a07b6a9c6aed30 Mon Sep 17 00:00:00 2001 From: Savyasachi Date: Fri, 28 Aug 2026 19:50:00 -0700 Subject: [PATCH] ci: gate the release on the full test matrix The release gate was strictly weaker than the test gate. test.yml ran a JDK matrix plus a lint job, while release.yml pinned a single JDK and ran one test step, so a red main could still publish to Clojars. This is not hypothetical. jose-clj 0.7.0 published broken: both JDK 11 cells and the lint job were failing on main, and the tag's own weaker check passed. The matrix and lint jobs move to a reusable test-matrix.yml that both workflows call, so the two gates cannot drift apart. release.yml becomes guards -> verify -> release: the cheap metadata guards fail fast before the matrix runs, verification covers everything test.yml covers for the tagged commit itself, and only then does anything reach Clojars. Verifying the tagged commit directly rather than querying the test workflow's conclusion avoids a race, since a tag can be pushed before the branch run finishes and a commit that never landed on a branch has no run at all. Publishing stays conditioned on github.ref_type == 'tag', and contents: write is now scoped to the release job instead of the whole workflow. --- .github/workflows/release.yml | 60 ++++++++++++++++++++----------- .github/workflows/test-matrix.yml | 44 +++++++++++++++++++++++ .github/workflows/test.yml | 35 +----------------- 3 files changed, 84 insertions(+), 55 deletions(-) create mode 100644 .github/workflows/test-matrix.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 68dbb87..d6d5ead 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,31 +8,16 @@ on: workflow_dispatch: {} # manual run for testing; publishing remains tag-only permissions: - contents: write # create the GitHub Release + contents: read jobs: - release: + guards: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: actions/setup-java@v4 - with: - distribution: temurin - java-version: '21' - - - uses: DeLaGuardo/setup-clojure@13.6.1 - with: - cli: latest - - - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-m2-${{ hashFiles('deps.edn') }} - restore-keys: ${{ runner.os }}-m2- - - name: Verify tag matches build.clj version if: github.ref_type == 'tag' run: | @@ -88,10 +73,6 @@ jobs: done < <(grep -oE "net\.clojars\.[a-zA-Z0-9._/-]+ \{:mvn/version \"[^\"]+\"\}" "$f" | grep -F "$LIB {:mvn/version" | grep -oE '"[^"]+"' | tr -d '"') done exit $rc - - name: Test - run: | - clojure -T:build compile-java - clojure -M:test - name: Verify tag commit is on main if: github.ref_type == 'tag' @@ -118,6 +99,43 @@ jobs: fi cat release-notes.md + - name: Upload release notes + if: github.ref_type == 'tag' + uses: actions/upload-artifact@v4 + with: + name: release-notes + path: release-notes.md + + verify: + needs: guards + uses: ./.github/workflows/test-matrix.yml + + release: + needs: [guards, verify] + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: '21' + - uses: DeLaGuardo/setup-clojure@13.6.1 + with: + cli: latest + - uses: actions/cache@v4 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-m2-${{ hashFiles('deps.edn') }} + restore-keys: ${{ runner.os }}-m2- + - uses: actions/download-artifact@v4 + if: github.ref_type == 'tag' + with: + name: release-notes + - name: Deploy to Clojars if: github.ref_type == 'tag' env: diff --git a/.github/workflows/test-matrix.yml b/.github/workflows/test-matrix.yml new file mode 100644 index 0000000..a2ac9a5 --- /dev/null +++ b/.github/workflows/test-matrix.yml @@ -0,0 +1,44 @@ +name: test matrix + +on: + workflow_call: + +permissions: + contents: read + +jobs: + test: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + jdk: ['17', '21'] + clojure: ['1.10', '1.11', '1.12'] + name: jdk ${{ matrix.jdk }} / clojure ${{ matrix.clojure }} + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: ${{ matrix.jdk }} + - uses: DeLaGuardo/setup-clojure@13.6.1 + with: + cli: latest + - uses: actions/cache@v4 + with: + path: ~/.m2/repository + key: m2-${{ hashFiles('deps.edn') }} + restore-keys: m2- + - run: clojure -T:build compile-java + - run: clojure -M:${{ matrix.clojure }}:test + + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install clj-kondo + run: | + curl -sSL https://raw.githubusercontent.com/clj-kondo/clj-kondo/v2026.08.04/script/install-clj-kondo | bash -s -- --dir "$HOME/.local/bin" --version 2026.08.04 + echo "$HOME/.local/bin" >> "$GITHUB_PATH" + - name: Lint + run: clj-kondo --lint src test --fail-level error diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1dd1504..93660e6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,37 +10,4 @@ permissions: jobs: test: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - jdk: ['17', '21'] - clojure: ['1.10', '1.11', '1.12'] - name: jdk ${{ matrix.jdk }} / clojure ${{ matrix.clojure }} - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-java@v4 - with: - distribution: temurin - java-version: ${{ matrix.jdk }} - - uses: DeLaGuardo/setup-clojure@13.6.1 - with: - cli: latest - - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: m2-${{ hashFiles('deps.edn') }} - restore-keys: m2- - - run: clojure -T:build compile-java - - run: clojure -M:${{ matrix.clojure }}:test - - lint: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Install clj-kondo - run: | - curl -sSL https://raw.githubusercontent.com/clj-kondo/clj-kondo/v2026.08.04/script/install-clj-kondo | bash -s -- --dir "$HOME/.local/bin" --version 2026.08.04 - echo "$HOME/.local/bin" >> "$GITHUB_PATH" - - name: Lint - run: clj-kondo --lint src test --fail-level error + uses: ./.github/workflows/test-matrix.yml