Create GitHub Release #39
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Create GitHub Release | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| branch: | |
| description: 'Branch to release from' | |
| required: true | |
| default: 'beta' | |
| workflow_run: | |
| workflows: ['Test PR'] | |
| types: [completed] | |
| branches: ['main', 'beta', 'httpx'] | |
| # The release is created with a GitHub App token. The "Build changelog" step | |
| # commits the rendered CHANGELOG.md back to the release branch, so the default | |
| # token needs write access to contents. | |
| permissions: | |
| contents: write | |
| jobs: | |
| create-release: | |
| if: github.event_name == 'workflow_dispatch' || (github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'push') | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ inputs.branch || github.event.workflow_run.head_branch }} | |
| - name: Generate app token | |
| id: app-token | |
| uses: actions/create-github-app-token@v3 | |
| with: | |
| app-id: ${{ secrets.RELEASE_APP_ID }} | |
| private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }} | |
| - name: Read version | |
| id: version | |
| run: | | |
| VERSION=$(grep '^version' pyproject.toml | sed 's/version = "\(.*\)"/\1/') | |
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | |
| if [[ "$VERSION" == *"b"* || "$VERSION" == *"rc"* || "$VERSION" == *"a"* ]]; then | |
| echo "prerelease=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "prerelease=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Check if release already exists | |
| id: check-release | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| VERSION="${{ steps.version.outputs.version }}" | |
| if gh release view "$VERSION" > /dev/null 2>&1; then | |
| echo "Release $VERSION already exists, skipping." | |
| echo "exists=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "exists=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Validate version matches branch | |
| if: steps.check-release.outputs.exists == 'false' | |
| run: | | |
| BRANCH="${{ inputs.branch || github.event.workflow_run.head_branch }}" | |
| VERSION="${{ steps.version.outputs.version }}" | |
| PRERELEASE="${{ steps.version.outputs.prerelease }}" | |
| if [[ "$BRANCH" == "beta" && "$PRERELEASE" == "false" ]]; then | |
| echo "::error::Beta branch must have a prerelease version (e.g. 3.1.0b0), got '$VERSION'" | |
| exit 1 | |
| fi | |
| if [[ "$BRANCH" == "httpx" && "$PRERELEASE" == "false" ]]; then | |
| echo "::error::httpx branch must have a prerelease version (e.g. 4.0.0b1), got '$VERSION'" | |
| exit 1 | |
| fi | |
| if [[ "$BRANCH" == "main" && "$PRERELEASE" == "true" ]]; then | |
| echo "::error::Main branch must not have a prerelease version, got '$VERSION'" | |
| exit 1 | |
| fi | |
| # Render changelog.d/ fragments into CHANGELOG.md and commit before the | |
| # release is cut. Reuses the version already read from pyproject.toml, so | |
| # there is no separate towncrier version to keep in sync. --generate-notes | |
| # below remains as a fallback for the GitHub release body. | |
| - name: Build changelog | |
| env: | |
| GH_TOKEN: ${{ steps.app-token.outputs.token }} | |
| run: | | |
| VERSION="${{ steps.version.outputs.version }}" | |
| BRANCH="${{ inputs.branch || github.event.workflow_run.head_branch }}" | |
| # Nothing to do if there are no fragments to consume. | |
| if ! ls changelog.d/*.md >/dev/null 2>&1; then | |
| echo "No changelog fragments; skipping towncrier build." | |
| exit 0 | |
| fi | |
| pip install --quiet towncrier | |
| towncrier build --yes --version "$VERSION" | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git add CHANGELOG.md changelog.d/ | |
| if ! git diff --cached --quiet; then | |
| git commit -m "docs: update changelog for $VERSION" | |
| git push origin "HEAD:$BRANCH" | |
| fi | |
| - name: Create release | |
| if: steps.check-release.outputs.exists == 'false' | |
| env: | |
| GH_TOKEN: ${{ steps.app-token.outputs.token }} | |
| run: | | |
| FLAGS="" | |
| if [ "${{ steps.version.outputs.prerelease }}" = "true" ]; then | |
| FLAGS="--prerelease" | |
| fi | |
| gh release create "${{ steps.version.outputs.version }}" \ | |
| --target "${{ inputs.branch || github.event.workflow_run.head_branch }}" \ | |
| --title "${{ steps.version.outputs.version }}" \ | |
| --generate-notes \ | |
| $FLAGS |