Skip to content

Question: How to handle branch protections with PSR? #1149

Closed as not planned
Closed as not planned

Description

@ichoosetoaccept

Question

I'm trying to understand if it's possible to use python-semantic-release in a way that ONLY creates GitHub releases, version tags, and release notes WITHOUT requiring commits/pushes to the main branch.

My use case: I have a protected main branch with required status checks (Codacy). I want semantic-release to run AFTER a PR is merged (meaning all checks have passed), but ONLY to create the release artifacts without modifying the repository.
Current behavior: The tool attempts to commit and push changes even when I think I've configured it not to, causing failures due to branch protection rules.

Is there a way to achieve this, or is committing/pushing an essential part of semantic-release's workflow that cannot be bypassed?

The original authors of the semantic-release project strongly recommend against altering project state during a release and I'm trying to heed their advice.

Configuration

Additional context

I've tried various combinations of the GitHub Action configuration, including removing explicit commit: false and push: false settings, but python-semantic-release still attempts to push changes. My GitHub workflow is configured to run on PR merge to main (see Configuration above).

Here's a full log with -vv active. It shows that version detection is working perfectly but it never creates a Github release with release notes and a version bump.

I was able to get the desired outcome once earlier but that was before I added a branch protection ruleset to protect the main branch:

  • Release 0.1.0 was created on: 2025-01-20T09:58:01Z
  • The ruleset was created on: 2025-01-20T12:38:33.202+01:00 (about 2.5 hours after the release)

The ruleset "Protect main" includes:

  • Protection against branch deletion
  • Required status checks from Codacy Static Code Analysis
  • Nothing else

But since it was created after release 0.1.0, it wasn't enforcing any protection at the time of the release.
Adding branch protection for the main branch broke things.

Activity

  1. codejedi365 commented on Jan 21, 2025

    @codejedi365
    Contributor

    Question

    I'm trying to understand if it's possible to use python-semantic-release in a way that ONLY creates GitHub releases, version tags, and release notes WITHOUT requiring commits/pushes to the main branch.

    Yes, it can be.

    semantic-release version --no-commit
    # it will not create a commit of the changes made to the local repository and will
    # not attempt to push said commit

    For the GitHub action, adding commit: false has the same effect as the cli above.

    My use case: I have a protected main branch with required status checks (Codacy). I want semantic-release to run AFTER a PR is merged (meaning all checks have passed), but ONLY to create the release artifacts without modifying the repository.

    Depends on what you define as modifying the repository (ie local vs remote). There is no turn off flag for stamping any version_variables defined into the local repository other than to not have them defined. If you only want to stamp the version, run the build_command then use this:

    semantic-release version --no-commit --no-tag [--changelog/--no-changelog] 

    Is there a way to achieve this, or is committing/pushing an essential part of semantic-release's workflow that cannot be bypassed?

    The misunderstanding with your request is that a VCS release is tied to a repository tag. At the minimum, a tag must be created in the remote and then a VCS release can be made. The current implementation of PSR chose to build a git tag and then push that to the remote which enables the ability to create VCS release (and write release notes). I have not looked into whether or not a tag can be created through the API directly to the remote (probably) but either way that is not implemented currently for any of the VCS's supported.

    Adding branch protection for the main branch broke things.

    There are many previous issues that comment about branch protection rules breaking things. I have not found a desirable solution to handle both worlds (automated releases and branch protections). I'm not sure how GitHub expects automated releases to work in this case. Some people have dived into using a GitHub App as maybe an authorized user to bypass branch restrictions. Others have used a Personal Access Token to authorize PSR to push while maintaining branch restrictions.

    Since we don't have another way to create the tag in the remote, you could run PSR's action to determine version, release criteria, and build the artifact. Then via the GitHub action outputs use the GitHub CLI to use the api client to create determined tag in the remote (ie without push). You could then run PSR from the command line (we don't have an action for this) to write the release notes to the VCS release.

    The original authors of the semantic-release project strongly recommend against altering project state during a release and I'm trying to heed their advice.

    I used to feel similarly for different reasons, but do consider that when you don't commit anything then you do loose the generated changelog if you desire that to be "updated" as opposed to re-written from scratch each time. I personally could care less about committing version stamping in the code, except it has worked out better for this project for some documentation updates that are persistent. The changelog generation was a key point for me to rather commit it and just update with each release, rather than not commit during release. In my experience, there are a few gotchas to worry about but I have overcome them so it is doable.

  2. changed the title [-]Is it possible to ONLY create a tag-based version bump, Github release and release notes without committing or pushing anything back into the repo?[/-] [+]Question: How to handle branch protections with PSR?[/+] on Jan 21, 2025
  3. codejedi365 commented on Jan 21, 2025

    @codejedi365
    Contributor

    Since we don't have another way to create the tag in the remote, you could run PSR's action to determine version, release criteria, and build the artifact. Then via the GitHub action outputs use the GitHub CLI to use the api client to create determined tag in the remote (ie without push). You could then run PSR from the command line (we don't have an action for this) to write the release notes to the VCS release.

    Slight modification to the steps as I have found that the github API client will create a tag if one doesn't exist. In that case we can do this in a more streamlined fashion. Have PSR determine version, make a local tag, generate a release notes file, then use the GitHub CLI to create a tag in the remote and a VCS release with the generated notes

    release.yml
    on:
      push:
        branches:
          - main
    
    env:
      PYTHON_VERSION: '3.13'
    
    jobs:
      release:
        runs-on: ubuntu-latest
        steps:
          - name: Setup | Checkout Repository at workflow sha
            uses: actions/checkout@v4
            with:
              ref: ${{ github.sha }}
              fetch-depth: 0
    
          - name: Setup | Force correct release branch on workflow sha
            run: |
              git checkout -B ${{ github.ref_name }}
    
          - name: Setup | Install Python ${{ env.PYTHON_VERSION }}
            uses: actions/setup-python@v5
            with:
              python-version: ${{ env.PYTHON_VERSION }}
              cache: 'pip'
    
          - name: Evaluate | Determine Next Version then Stamp & Build
            id: version
            uses: python-semantic-release/[email protected]
            with:
              github_token: ""    # value not actually needed for this limited operation
              root_options: "-v"
              commit: false
              tag: true           # required, due to release notes generation tag check
              push: false
              vcs_release: false
              changelog: false    # I don't know if you wanted this or not
    
          - name: Release | Generate Release Notes
            # step likely not be needed with the resolution of #512
            # Brittle as is, since it is dependent on the log output of PSR which could change (unlikely now that I know)
            if: steps.version.outputs.released == 'true'
            id: release-notes
            run: |
              pip install python-semantic-release==9.16.1
              semantic-release --noop changelog --post-to-release-notes ${{ steps.version.outputs.tag }} 2>release-notes.log
              tac release-notes.log | awk '/posted the following release notes/ {exit} {print}' | tac | tee release-notes.md
              printf '%s\n' "NOTES_FILE=release-notes.md" >> $GITHUB_OUTPUT
    
          - name: Release | Tag & Publish GitHub Release Notes
            if: steps.version.outputs.released == 'true'
            env:
              GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
            run: |
              gh release create ${{ steps.version.outputs.tag }} \
                --title "${{ steps.version.outputs.tag }}" \
                --notes-file "${{ steps.release-notes.outputs.NOTES_FILE }}" \
                --target ${{ github.sha }} \
                --repo ${{ github.repository }}
    

    This, of course, is dependent that the GitHub CLI also isn't blocked from making a tag when branch protections are on. @ichoosetoaccept, Please try it out and let the me know. I just wrote this from scratch and I don't know if it will work but should be 90% there.

  4. added and removed
    triagewaiting for initial maintainer review
    on Jan 21, 2025
  5. github-actions commented on Feb 4, 2025

    @github-actions

    This issue has not received a response in 14 days. If no response is received in 7 days, it will be closed. We look forward to hearing from you.

  6. github-actions commented on Feb 12, 2025

    @github-actions

    This issue was closed because no response was received.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions