diff --git a/.github/workflows/bump-changelog.yml b/.github/workflows/bump-changelog.yml new file mode 100644 index 0000000000..2c895037fc --- /dev/null +++ b/.github/workflows/bump-changelog.yml @@ -0,0 +1,55 @@ +name: Bump changelog before release + +on: + workflow_dispatch: + inputs: + version: + description: 'Version to be released' + required: true + type: string +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + default-python: "3.12" + minimum-supported-python: "3.8" + +jobs: + bump-changelog: + name: Bump changelog + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + steps: + - name: Checkout ${{ github.ref }} + uses: actions/checkout@v4 + - name: Set up Python ${{ env.default-python }} + uses: actions/setup-python@v5 + with: + python-version: ${{ env.default-python }} + cache: "pip" + - name: Get release version and construct PR branch + run: | + echo "RELEASE_VERSION=${{ inputs.version }}" >> $GITHUB_ENV + echo "PR_BRANCH=bump-changelog-for-${{ inputs.version }}" >> $GITHUB_ENV + - name: Create pull request branch + run: git switch -c $PR_BRANCH + - name: Install nox + run: python -m pip install nox + - name: Update changelog + run: nox --error-on-missing-interpreters --non-interactive --session build_changelog -- $RELEASE_VERSION + - name: Commit and push change + run: | + git config --global user.name 'github-actions[bot]' + git config --global user.email '41898282+github-actions[bot]@users.noreply.github.com' + git commit -am "$RELEASE_VERSION: Bump changelog" + git fetch origin + git push origin $PR_BRANCH + - name: Create pull request + run: | + git fetch origin + gh pr create --base main --fill --label release-version + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000000..f9c3ab0172 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,81 @@ +name: Release + +on: + pull_request_target: + types: + - closed +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + default-python: "3.12" + +jobs: + pypi-publish: + name: Publish pipx to PyPI + if: >- + github.event.pull_request.merged == true + && contains(github.event.pull_request.labels.*.name, 'release-version') + runs-on: ubuntu-latest + environment: + name: release + url: https://pypi.org/p/pipx + permissions: + id-token: write + steps: + - name: Checkout ${{ github.ref }} + uses: actions/checkout@v4 + - name: Set up Python ${{ env.default-python }} + uses: actions/setup-python@v5 + with: + python-version: ${{ env.default-python }} + cache: "pip" + - name: Install nox + run: pip install nox + - name: Build sdist and wheel + run: nox --error-on-missing-interpreters --non-interactive --session build + - name: Publish to PyPi + uses: pypa/gh-action-pypi-publish@v1.8.14 + + create-release: + name: Create a release on GitHub's UI + needs: pypi-publish + runs-on: ubuntu-latest + outputs: + release-tag: ${{ steps.get-version.outputs.version }} + permissions: + contents: write + steps: + - uses: actions/checkout@v4 + - name: Extract version to be released + id: get-version + env: + TITLE: ${{ github.event.pull_request.title }} + run: | + echo "version=${TITLE/: [[:alnum:]]*} }" >> "$GITHUB_OUTPUT" + - name: Create release + uses: ncipollo/release-action@v1 + with: + generateReleaseNotes: true + tag: "${{ steps.get-version.outputs.version }}" + commit: ${{ github.event.pull_request.merge_commit_sha }} + + upload-zipapp: + name: Upload zipapp to GitHub Release + needs: create-release + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: dawidd6/action-download-artifact@v3 + with: + name: pipx.pyz + workflow: tests.yml + workflow_conclusion: success + pr: ${{ github.event.pull_request.number }} + - name: Upload to release + uses: softprops/action-gh-release@v1 + with: + files: pipx.pyz + tag_name: "${{ needs.create-release.outputs.release-tag }}" diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a0aac2f395..71450e74c8 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -85,79 +85,3 @@ jobs: name: pipx.pyz path: pipx.pyz retention-days: 3 - - pypi-publish: - name: Publish pipx to PyPI on release - if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags') - needs: [tests, man, zipapp] - runs-on: ubuntu-latest - environment: - name: release - url: https://pypi.org/p/pipx - permissions: - id-token: write - steps: - - name: Checkout ${{ github.ref }} - uses: actions/checkout@v4 - - name: Set up Python ${{ env.default-python }} - uses: actions/setup-python@v5 - with: - python-version: ${{ env.default-python }} - cache: "pip" - - name: Install nox - run: pip install nox - - name: Build sdist and wheel - run: nox --error-on-missing-interpreters --non-interactive --session build - - name: Publish to PyPi - uses: pypa/gh-action-pypi-publish@v1.8.14 - - upload-zipapp: - name: Upload zipapp to GitHub Release on release - if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags') - needs: [tests, man, zipapp] - runs-on: ubuntu-latest - steps: - - uses: actions/download-artifact@v4 - with: - name: pipx.pyz - - name: Upload to release - uses: softprops/action-gh-release@v2 - with: - files: pipx.pyz - - bump-changelog: - name: Bump changelog on release - if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags') - needs: [pypi-publish, upload-zipapp] - runs-on: ubuntu-latest - permissions: - contents: write - pull-requests: write - steps: - - name: Checkout ${{ github.ref }} - uses: actions/checkout@v4 - - name: Set up Python ${{ env.default-python }} - uses: actions/setup-python@v5 - with: - python-version: ${{ env.default-python }} - cache: "pip" - - name: Extract release tag - run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV - - name: Create pull request branch - run: git switch -c "bump-changelog-for-${RELEASE_VERSION}" - - name: Install nox - run: python -m pip install nox - - name: Update changelog - run: nox --error-on-missing-interpreters --non-interactive --session build_changelog -- $RELEASE_VERSION - - name: Commit and push change - run: | - git config --global user.name 'github-actions[bot]' - git config --global user.email '41898282+github-actions[bot]@users.noreply.github.com' - git commit -am "Bump changelog for $RELEASE_VERSION" - git push origin "bump-changelog-for-${RELEASE_VERSION}" - - name: Create pull request - run: | - git fetch origin - gh pr create --base main --fill - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d601403954..8e5e4eaffe 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -220,10 +220,15 @@ nox -s watch_docs ## Releasing New `pipx` Versions -To publish to PyPI simply create a "published" release on GitHub. This will trigger GitHub workflows that publishes: +To release a new version, manually run the `bump-changelog` action under the *"Actions"* tab, passing it the version to be released. This will create a pull request updating the changelog for the upcoming version, with the `release-version` label. Merging this PR will automatically trigger the release workflows. + +Attaching this label to any pull request of which the title follows the format `: Description` and merging it will trigger the release workflows as well. + +The release workflow consists of publishing: - the pipx version to PyPI, -- the documentation to readthedocs, +- the documentation to ReadTheDocs, +- a GitHub release, - the `zipapp` to the GitHub release created. No need for any other pre or post publish steps.