From bcfed870aaa82b58c10181d9f1157e9a2e25e113 Mon Sep 17 00:00:00 2001 From: Krzysztof Maziarz Date: Mon, 15 Jun 2026 18:33:29 +0000 Subject: [PATCH 1/7] feat(release): Validate version format --- .github/workflows/release.yml | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b7ae146..e8d9e4d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,12 +13,22 @@ permissions: jobs: push-tag: runs-on: ubuntu-latest + env: + VERSION: ${{ inputs.version }} steps: - uses: actions/checkout@v4 + - name: Validate version + # Reject anything that is not in the `x.y.z` format. + run: | + if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "::error::Version '$VERSION' is not in the x.y.z format." + exit 1 + fi - name: Configure Git run: | git config user.name github-actions[bot] git config user.email 41898282+github-actions[bot]@users.noreply.github.com - - run: | - git tag -a v${{ inputs.version }} -m "Release v${{ inputs.version }}" - git push origin v${{ inputs.version }} + - name: Create and push tag + run: | + git tag -a "v$VERSION" -m "Release v$VERSION" + git push origin "v$VERSION" From b3af3b5717397924808681779c45776575e97a1e Mon Sep 17 00:00:00 2001 From: Krzysztof Maziarz Date: Mon, 15 Jun 2026 19:02:39 +0000 Subject: [PATCH 2/7] feat(release): Add step for package build --- .github/workflows/release.yml | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e8d9e4d..8b43d15 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,12 +7,11 @@ on: required: true type: string -permissions: - contents: write - jobs: push-tag: runs-on: ubuntu-latest + permissions: + contents: write env: VERSION: ${{ inputs.version }} steps: @@ -32,3 +31,33 @@ jobs: run: | git tag -a "v$VERSION" -m "Release v$VERSION" git push origin "v$VERSION" + + build: + needs: push-tag + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: actions/checkout@v4 + with: + ref: v${{ inputs.version }} + fetch-depth: 0 # Full history and tags so setuptools_scm derives the version. + - uses: actions/setup-python@v5 + with: + python-version: "3.11" + - name: Build sdist and wheel + run: | + python -m pip install --upgrade build twine + python -m build + - name: Verify built version matches the requested tag + env: + VERSION: ${{ inputs.version }} + run: | + ls -l dist/ + test -f "dist/retrochimera-${VERSION}.tar.gz" + - name: Check distribution metadata + run: twine check dist/* + - uses: actions/upload-artifact@v4 + with: + name: dist + path: dist/ From ba577b69c849fc24d9bbdf98b7a6b358867bcbf2 Mon Sep 17 00:00:00 2001 From: Krzysztof Maziarz Date: Mon, 15 Jun 2026 19:09:05 +0000 Subject: [PATCH 3/7] feat(release): Validate source branch --- .github/workflows/release.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8b43d15..12bc75d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,6 +10,8 @@ on: jobs: push-tag: runs-on: ubuntu-latest + # Only allow releases from main. + if: github.ref == 'refs/heads/main' permissions: contents: write env: From 2bea7d6e192bcfa0c43cd33cbc0df3e9cfa42d8c Mon Sep 17 00:00:00 2001 From: Krzysztof Maziarz Date: Mon, 15 Jun 2026 19:45:34 +0000 Subject: [PATCH 4/7] feat(release): Add step for publishing to PyPI --- .github/workflows/release.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 12bc75d..0cd2fad 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -63,3 +63,19 @@ jobs: with: name: dist path: dist/ + + publish: + needs: build + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/retrochimera + permissions: + id-token: write # Required for OIDC trusted publishing to PyPI. + steps: + - uses: actions/download-artifact@v4 + with: + name: dist + path: dist/ + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 From 3a85b0649c09c1bd772ed46280046c84941e37a7 Mon Sep 17 00:00:00 2001 From: Krzysztof Maziarz Date: Tue, 16 Jun 2026 11:09:35 +0000 Subject: [PATCH 5/7] doc(DEVELOPMENT): Update release steps --- DEVELOPMENT.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 178b93e..d4476a7 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -1,6 +1,6 @@ To release a new stable version of `retrochimera` one needs to complete the following steps: 1. Create a PR editing the `CHANGELOG.md` (note it has to be modified in three places). -2. Run the ["Release Stable Version" workflow](https://github.com/microsoft/retrochimera/actions/workflows/release.yml), providing the version number as argument (use the `x.y.z` format _without_ the leading "v"; the workflow will prepend it wherever necessary). Make sure the branch is set to `main`. If this step does not work as intended the tag can always be deleted manually. -3. Create a GitHub Release from the [newly created tag](https://github.com/microsoft/retrochimera/tags). Set the name to `retrochimera x.y.z`. The description should be the list of changes copied from the changelog. Consider including a short description before the list of changes to describe the main gist of the release. -4. Release a new version to PyPI (e.g. by following [these instructions](https://realpython.com/pypi-publish-python-package/)). Consider publishing to [Test PyPI](https://test.pypi.org/) first to verify that the README renders correctly. \ No newline at end of file +2. Run the ["Release Stable Version" workflow](https://github.com/microsoft/retrochimera/actions/workflows/release.yml), providing the version number as argument (use the `x.y.z` format _without_ the leading "v") and setting branch to `main`. The workflow pushes the tag, builds the package, and publishes to PyPI via [OIDC trusted publishing](https://docs.pypi.org/trusted-publishers/). +3. Ask one of the eligible approvers (defined in the `pypi` GitHub environment) to approve the push to PyPI. Among other things, they should double-check the package version. +4. Create a GitHub Release from the [newly created tag](https://github.com/microsoft/retrochimera/tags). Set the name to `retrochimera x.y.z`. The description should be the list of changes copied from the changelog. Consider including a short description before the list of changes to describe the main gist of the release. From 06f583620be06c9e74228592475c9fe8466334ac Mon Sep 17 00:00:00 2001 From: Krzysztof Maziarz Date: Tue, 16 Jun 2026 12:36:19 +0000 Subject: [PATCH 6/7] feat(DEVELOPMENT): Allow anyone in microsoft/msrai4s-dd to approve --- DEVELOPMENT.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index d4476a7..d9602d5 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -2,5 +2,5 @@ To release a new stable version of `retrochimera` one needs to complete the foll 1. Create a PR editing the `CHANGELOG.md` (note it has to be modified in three places). 2. Run the ["Release Stable Version" workflow](https://github.com/microsoft/retrochimera/actions/workflows/release.yml), providing the version number as argument (use the `x.y.z` format _without_ the leading "v") and setting branch to `main`. The workflow pushes the tag, builds the package, and publishes to PyPI via [OIDC trusted publishing](https://docs.pypi.org/trusted-publishers/). -3. Ask one of the eligible approvers (defined in the `pypi` GitHub environment) to approve the push to PyPI. Among other things, they should double-check the package version. +3. Ask one of the eligible approvers (anyone in the [@microsoft/msrai4s-dd](https://github.com/orgs/microsoft/teams/msrai4s-dd) team) to approve the push to PyPI. Among other things, they should double-check the package version. 4. Create a GitHub Release from the [newly created tag](https://github.com/microsoft/retrochimera/tags). Set the name to `retrochimera x.y.z`. The description should be the list of changes copied from the changelog. Consider including a short description before the list of changes to describe the main gist of the release. From cd6fb2bce3309fcc923fe18b674797b9b6783cf0 Mon Sep 17 00:00:00 2001 From: Krzysztof Maziarz Date: Wed, 17 Jun 2026 11:18:21 +0000 Subject: [PATCH 7/7] feat(release): Ask for approval before pushing the tag --- .github/workflows/release.yml | 1 + DEVELOPMENT.md | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0cd2fad..d3b666a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,6 +12,7 @@ jobs: runs-on: ubuntu-latest # Only allow releases from main. if: github.ref == 'refs/heads/main' + environment: release permissions: contents: write env: diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index d9602d5..4a8119c 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -1,6 +1,7 @@ To release a new stable version of `retrochimera` one needs to complete the following steps: 1. Create a PR editing the `CHANGELOG.md` (note it has to be modified in three places). -2. Run the ["Release Stable Version" workflow](https://github.com/microsoft/retrochimera/actions/workflows/release.yml), providing the version number as argument (use the `x.y.z` format _without_ the leading "v") and setting branch to `main`. The workflow pushes the tag, builds the package, and publishes to PyPI via [OIDC trusted publishing](https://docs.pypi.org/trusted-publishers/). -3. Ask one of the eligible approvers (anyone in the [@microsoft/msrai4s-dd](https://github.com/orgs/microsoft/teams/msrai4s-dd) team) to approve the push to PyPI. Among other things, they should double-check the package version. -4. Create a GitHub Release from the [newly created tag](https://github.com/microsoft/retrochimera/tags). Set the name to `retrochimera x.y.z`. The description should be the list of changes copied from the changelog. Consider including a short description before the list of changes to describe the main gist of the release. +2. Run the ["Release Stable Version" workflow](https://github.com/microsoft/retrochimera/actions/workflows/release.yml), providing the version number as argument (use the `x.y.z` format _without_ the leading "v") and setting branch to `main`. +3. Ask one of the eligible approvers (anyone in the [@microsoft/msrai4s-dd](https://github.com/orgs/microsoft/teams/msrai4s-dd) team) to approve the workflow. Among other things, they should verify step (1) was completed, and double-check the package version. +4. After approval, the release workflow will push the tag, build the package, and publish to PyPI via [OIDC trusted publishing](https://docs.pypi.org/trusted-publishers/). +5. Create a GitHub Release from the [newly created tag](https://github.com/microsoft/retrochimera/tags). Set the name to `retrochimera x.y.z`. The description should be the list of changes copied from the changelog. Consider including a short description before the list of changes to describe the main gist of the release.