diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b7ae146..d3b666a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,18 +7,76 @@ on: required: true type: string -permissions: - contents: write - jobs: push-tag: runs-on: ubuntu-latest + # Only allow releases from main. + if: github.ref == 'refs/heads/main' + environment: release + permissions: + contents: write + 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" + + 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/ + + 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 diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 178b93e..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"; 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`. +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.