@@ -3,10 +3,16 @@ name: Publish Release
33on :
44 workflow_dispatch :
55
6+ permissions :
7+ # Required so GH_TOKEN can create the GitHub Release and upload the artifact.
8+ contents : write
9+
610jobs :
7- publish-release :
11+ # This job is the irreversible boundary. Once Maven Central publish succeeds,
12+ # we do not want retries for downstream GitHub operations to re-run it.
13+ build-and-publish-to-maven :
814 runs-on : macos-latest
9- if : github.repository == 'block/radiography'
15+ if : github.repository == 'block/radiography' && startsWith(github.ref, 'refs/tags/v')
1016 timeout-minutes : 35
1117
1218 steps :
@@ -23,10 +29,81 @@ jobs:
2329 - name : Assemble
2430 run : ./gradlew assemble
2531
26- - name : Publish Release
32+ # Build and hand off the release asset in the same build context as Maven
33+ # publish, so the release uses artifacts from the same pipeline run.
34+ - name : Build Stoic Plugin Distribution
35+ run : ./gradlew :stoic-plugin:dist
36+
37+ - name : Upload Stoic Plugin Distribution
38+ uses : actions/upload-artifact@v4
39+ with :
40+ # Include tag + commit to avoid any ambiguity about which artifact this is.
41+ name : stoic-plugin-dist-${{ github.ref_name }}-${{ github.sha }}
42+ path : stoic-plugin/build/distributions/radiography-stoic-plugin-*.tar.gz
43+ if-no-files-found : error
44+ # Keep the upload for 7 days so we have time to retry publishing the
45+ # Github release
46+ retention-days : 7
47+
48+ # Maven publish must be the final step in this job because it's
49+ # irreversible: if we attempt to republish it will fail.
50+ - name : Publish To Maven
2751 run : ./gradlew publish
2852 env :
2953 ORG_GRADLE_PROJECT_mavenCentralUsername : ${{ secrets.SONATYPE_CENTRAL_USERNAME }}
3054 ORG_GRADLE_PROJECT_mavenCentralPassword : ${{ secrets.SONATYPE_CENTRAL_PASSWORD }}
3155 ORG_GRADLE_PROJECT_signingInMemoryKey : ${{ secrets.GPG_SECRET_KEY }}
3256 ORG_GRADLE_PROJECT_signingInMemoryKeyPassword : ${{ secrets.GPG_SECRET_PASSPHRASE }}
57+
58+ # Keep release publication in a separate job so "Re-run failed jobs" can retry
59+ # GitHub release operations without re-running Maven publish.
60+ publish-to-github-release :
61+ runs-on : ubuntu-latest
62+ needs : build-and-publish-to-maven
63+ timeout-minutes : 10
64+
65+ steps :
66+ - name : Download Stoic Plugin Distribution
67+ uses : actions/download-artifact@v4
68+ with :
69+ # Download the exact artifact produced by build-and-publish-to-maven.
70+ name : stoic-plugin-dist-${{ github.ref_name }}-${{ github.sha }}
71+ path : dist
72+
73+ - name : Create Draft GitHub Release, Upload Asset, and Publish
74+ env :
75+ GH_TOKEN : ${{ github.token }}
76+ run : |
77+ set -euo pipefail
78+
79+ artifact_path="$(ls dist/radiography-stoic-plugin-*.tar.gz)"
80+ release_notes='See [Change Log](https://github.com/square/radiography/blob/main/CHANGELOG.md)'
81+
82+ if gh release view "$GITHUB_REF_NAME" >/dev/null 2>&1; then
83+ # We only auto-recover if the existing release is still a draft.
84+ # A published immutable release may reject asset modifications.
85+ is_draft="$(gh release view "$GITHUB_REF_NAME" --json isDraft --jq .isDraft)"
86+ if [ "$is_draft" != "true" ]; then
87+ echo "Release $GITHUB_REF_NAME is already published and cannot be safely finalized as draft-first."
88+ echo "If immutable releases are enabled, published release assets cannot be modified:"
89+ echo "https://docs.github.com/en/code-security/concepts/supply-chain-security/immutable-releases"
90+ exit 1
91+ fi
92+ else
93+ gh release create "$GITHUB_REF_NAME" \
94+ --draft \
95+ --title "$GITHUB_REF_NAME" \
96+ --notes "$release_notes"
97+ fi
98+
99+ # Draft-first follows GitHub immutable release guidance:
100+ # https://docs.github.com/en/code-security/concepts/supply-chain-security/immutable-releases
101+ # --clobber makes retries idempotent if an earlier attempt uploaded assets.
102+ gh release upload "$GITHUB_REF_NAME" "$artifact_path" --clobber
103+
104+ # Publish only after assets are uploaded to avoid partially published
105+ # immutable releases missing artifacts.
106+ gh release edit "$GITHUB_REF_NAME" \
107+ --draft=false \
108+ --title "$GITHUB_REF_NAME" \
109+ --notes "$release_notes"
0 commit comments