Skip to content

Commit b0d7826

Browse files
farhanclaude
andauthored
fix: make release workflow compatible with immutable releases (#949)
The org has immutable releases enabled, which freezes a release's assets the moment it is published. The old flow let python-semantic-release publish the GitHub Release and then attached the built distributions afterwards via publish-action, which now fails with HTTP 422 ("cannot upload assets to an immutable release"). That failure aborts the release job before publish_to_pypi runs, so the tag is created but never shipped to PyPI (v6.3.2 is tagged but missing from PyPI). Set vcs_release: "false" so python-semantic-release commits, tags, and builds but does not publish the release, then create it with `gh release create` which uploads the assets to a draft and publishes it atomically -- the ordering immutable releases require. All actions are SHA-pinned to match the sample-plugin standard. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 59fb6f9 commit b0d7826

1 file changed

Lines changed: 32 additions & 10 deletions

File tree

.github/workflows/release.yml

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,40 +31,62 @@ jobs:
3131

3232
- name: Python Semantic Release
3333
id: release
34-
uses: python-semantic-release/python-semantic-release@v10.6.2
34+
uses: python-semantic-release/python-semantic-release@9a026e9303981c866c3425723009becb2437c757 # v10.6.2
3535
with:
3636
github_token: ${{ secrets.OPENEDX_SEMANTIC_RELEASE_GITHUB_TOKEN }}
3737
git_committer_name: "github-actions"
3838
git_committer_email: "github-actions@github.com"
3939
changelog: "false"
40+
# Commit, tag, push and build, but don't create the GitHub release.
41+
# We create it ourselves in the next step so that the distributions
42+
# are attached before the release is published. See that step for why.
43+
vcs_release: "false"
4044

41-
- name: Publish | Upload to GitHub Release Assets
42-
uses: python-semantic-release/publish-action@v10.6.1
45+
# This repo has immutable releases enabled, which freezes a release's
46+
# assets the moment it is published, so assets cannot be attached
47+
# afterwards. `gh release create` handles this by creating the release as
48+
# a draft, uploading the assets, and only then publishing it:
49+
# https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/immutable-releases
50+
- name: Publish | Create GitHub Release with Assets
4351
if: steps.release.outputs.released == 'true'
44-
with:
45-
github_token: ${{ secrets.GITHUB_TOKEN }}
46-
tag: ${{ steps.release.outputs.tag }}
52+
env:
53+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
54+
# Reuse the release notes python-semantic-release generated for us.
55+
RELEASE_NOTES: ${{ steps.release.outputs.release_notes }}
56+
TAG: ${{ steps.release.outputs.tag }}
57+
run: |
58+
# Output the release notes to a file
59+
printf '%s' "$RELEASE_NOTES" > "$RUNNER_TEMP/release_notes.md"
60+
# Creates the release as a draft, uploads the assets, and then
61+
# publishes it -- all within this one command.
62+
gh release create "$TAG" \
63+
--verify-tag \
64+
--title "$TAG" \
65+
--notes-file "$RUNNER_TEMP/release_notes.md" \
66+
dist/*
4767
4868
- name: Upload dist artifacts
4969
if: steps.release.outputs.released == 'true'
50-
uses: actions/upload-artifact@v7
70+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
5171
with:
5272
name: dist
5373
path: dist/
74+
if-no-files-found: error
5475

5576
publish_to_pypi:
5677
runs-on: ubuntu-latest
5778
needs: release
58-
if: needs.release.outputs.released == 'true'
79+
if: github.ref_name == 'master' && needs.release.outputs.released == 'true'
5980
permissions:
81+
contents: read
6082
id-token: write
6183

6284
steps:
6385
- name: Download dist artifacts
64-
uses: actions/download-artifact@v8
86+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
6587
with:
6688
name: dist
6789
path: dist/
6890

6991
- name: Publish to PyPI
70-
uses: pypa/gh-action-pypi-publish@release/v1
92+
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2

0 commit comments

Comments
 (0)