Skip to content

verify_upstream_unchanged fails on github actions when git repo is unauthenticated #1373

@estyrke

Description

@estyrke

Bug Report

Description

We have a github actions workflow to create releases. A few days ago it suddenly stopped working and it seems related to the new verify upstream unchanged feature. See job definition below. We suspected the persist-credentials: false option to the checkout action, and while removing that option does make the fetch go through, the build then instead fails at the push step because the (presumably default) token has insufficient credentials.

Expected behavior

This is the output from a run at November 7th, presumably using PSR 10.4.1:

Details
[...]
Installed 30 packages in 27ms
2.1.0
The next version is: 2.1.0! 🚀
Skipping build due to --skip-build flag
Using CPython 3.12.3 interpreter at: /usr/bin/python3.12
[...]
2.1.0
The next version is: 2.1.0! 🚀
🛠 Running build command: uv build
Building source distribution...
Building wheel from source distribution...
Successfully built dist/[redacted]-2.1.0.tar.gz
Successfully built dist/[redacted]-2.1.0-py3-none-any.whl
Build completed successfully!

Actual behavior

This is the output today, using PSR 10.5.2:

Details
2.1.1
The next version is: 2.1.1! 🚀
Skipping build due to --skip-build flag
Using CPython 3.12.3 interpreter at: /usr/bin/python3.12
[...]
2.1.1
The next version is: 2.1.1! 🚀
🛠 Running build command: uv build
Building source distribution...
Building wheel from source distribution...
Successfully built dist/[redacted]-2.1.1.tar.gz
Successfully built dist/[redacted]-2.1.1-py3-none-any.whl
Build completed successfully!
[08:37:16] ERROR    Cmd('git') failed due to: exit code(128)   gitproject.py:414
                      cmdline: git fetch -v -- origin                           
                      stderr: 'fatal: could not read Username                   
                    for 'https://github.com/': No such device                    
                    or address'                                                 
                    ╭── Traceback (most recent call last) ───╮                  
                    │ /home/runner/work/_temp/setup-uv-cache │                  
                    │ /archive-v0/zCqNxvksJxPI6MA7YgzqA/lib/ │                  
                    │ python3.12/site-packages/semantic_rele │                  
                    │ ase/gitproject.py:412 in               │                  
                    │ verify_upstream_unchanged              │                  
                    │                                        │                  
                    │   409 │   │   │   # Fetch the latest c │                  
                    │   410 │   │   │   self.logger.info("Fe │                  
                    │   411 │   │   │   try:                 │                  
                    │ ❱ 412 │   │   │   │   remote_ref_obj.f │                  
                    │   413 │   │   │   except GitCommandErr │                  
                    │   414 │   │   │   │   self.logger.exce │                  
                    │   415 │   │   │   │   err_msg = f"Fail │                  
                    │                                        │                  
                    │ /home/runner/work/_temp/setup-uv-cache │                  
                    │ /archive-v0/zCqNxvksJxPI6MA7YgzqA/lib/ │                  
                    │ python3.12/site-packages/git/remote.py │                  
                    │ :1076 in fetch                         │                  
                    │                                        │                  
                    │   1073 │   │   proc = self.repo.git.fe │                  
                    │   1074 │   │   │   "--", self, *args,  │                  
                    │        universal_newlines=True, v=verb │                  
                    │   1075 │   │   )                       │                  
                    │ ❱ 1076 │   │   res = self._get_fetch_i │                  
                    │        kill_after_timeout=kill_after_t │                  
                    │   1077 │   │   if hasattr(self.repo.od │                  
                    │   1078 │   │   │   self.repo.odb.updat │                  
                    │   1079 │   │   return res              │                  
                    │                                        │                  
                    │ /home/runner/work/_temp/setup-uv-cache │                  
                    │ /archive-v0/zCqNxvksJxPI6MA7YgzqA/lib/ │                  
                    │ python3.12/site-packages/git/remote.py │                  
                    │ :902 in _get_fetch_info_from_stderr    │                  
                    │                                        │                  
                    │    899 │   │   )                       │                  
                    │    900 │   │                           │                  
                    │    901 │   │   stderr_text = progress. │                  
                    │ ❱  902 │   │   proc.wait(stderr=stderr │                  
                    │    903 │   │   if stderr_text:         │                  
                    │    904 │   │   │   _logger.warning("Er │                  
                    │    905                                 │                  
                    │                                        │                  
                    │ /home/runner/work/_temp/setup-uv-cache │                  
                    │ /archive-v0/zCqNxvksJxPI6MA7YgzqA/lib/ │                  
                    │ python3.12/site-packages/git/cmd.py:41 │                  
                    │ 9 in wait                              │                  
                    │                                        │                  
                    │    416 │   │   if status != 0:         │                  
                    │    417 │   │   │   errstr = read_all_f │                  
                    │    418 │   │   │   _logger.debug("Auto │                  
                    │ ❱  419 │   │   │   raise GitCommandErr │                  
                    │    420 │   │   return status           │                  
                    │    421                                 │                  
                    │    422                                 │                  
                    ╰────────────────────────────────────────╯                  
                    GitCommandError: Cmd('git') failed due to:                  
                    exit code(128)                                              
                      cmdline: git fetch -v -- origin                           
                      stderr: 'fatal: could not read Username                   
                    for 'https://github.com/': No such device                    
                    or address'                                                 
Failed to fetch from remote 'origin'
Unable to verify upstream due to error!

And this is the output after removing persist-credentials: false:

Details
2.1.1
The next version is: 2.1.1! 🚀
Skipping build due to --skip-build flag
Using CPython 3.12.3 interpreter at: /usr/bin/python3.12
[...]
2.1.1
The next version is: 2.1.1! 🚀
🛠 Running build command: uv build
Building source distribution...
Building wheel from source distribution...
Successfully built dist/<redacted>-2.1.1.tar.gz
Successfully built dist/<redacted>-2.1.1-py3-none-any.whl
Build completed successfully!
[09:26:52] ERROR    Cmd('git') failed due to: exit code(1)     gitproject.py:312
                      cmdline: git push                                         
                    ***github.com/<redacted>.git main                                             
                      stderr: 'remote: error: GH013:                            
                    Repository rule violations found for                        
                    refs/heads/main.                                            
                    remote: Review all repository rules at                      
                    https://github.com/<redacted>/rules                  
                    ?ref=refs%2Fheads%2Fmain                                    
                    remote:                                                     
                    remote: - Changes must be made through a                    
                    pull request.                                               
                    remote:                                                     
                    To                                                          
                    https://github.com/<redacted>.git                    
                     ! [remote rejected] main -> main (push                     
                    declined due to repository rule                             
                    violations)                                                 
                    error: failed to push some refs to                          
                    'https://github.com/<redacted>.git'                  
                    '                                                           
                    ╭── Traceback (most recent call last) ───╮                  
                    │ /home/runner/work/_temp/setup-uv-cache │                  
                    │ /archive-v0/RSMkjl3R3t64vpgxKv1Ws/lib/ │                  
                    │ python3.12/site-packages/semantic_rele │                  
                    │ ase/gitproject.py:310 in               │                  
                    │ git_push_branch                        │                  
                    │                                        │                  
                    │   307 │   │                            │                  
                    │   308 │   │   with Repo(str(self.proje │                  
                    │   309 │   │   │   try:                 │                  
                    │ ❱ 310 │   │   │   │   repo.git.push(re │                  
                    │   311 │   │   │   except GitCommandErr │                  
                    │   312 │   │   │   │   self.logger.exce │                  
                    │   313 │   │   │   │   raise GitPushErr │                  
                    │                                        │                  
                    │ /home/runner/work/_temp/setup-uv-cache │                  
                    │ /archive-v0/RSMkjl3R3t64vpgxKv1Ws/lib/ │                  
                    │ python3.12/site-packages/git/cmd.py:10 │                  
                    │ 03 in <lambda>                         │                  
                    │                                        │                  
                    │   1000 │   │   """                     │                  
                    │   1001 │   │   if name.startswith("_") │                  
                    │   1002 │   │   │   return super().__ge │                  
                    │ ❱ 1003 │   │   return lambda *args, ** │                  
                    │   1004 │                               │                  
                    │   1005 │   def set_persistent_git_opti │                  
                    │   1006 │   │   """Specify command line │                  
                    │                                        │                  
                    │ /home/runner/work/_temp/setup-uv-cache │                  
                    │ /archive-v0/RSMkjl3R3t64vpgxKv1Ws/lib/ │                  
                    │ python3.12/site-packages/git/cmd.py:16 │                  
                    │ 16 in _call_process                    │                  
                    │                                        │                  
                    │   1613 │   │   call.append(dashify(met │                  
                    │   1614 │   │   call.extend(args_list)  │                  
                    │   1615 │   │                           │                  
                    │ ❱ 1616 │   │   return self.execute(cal │                  
                    │   1617 │                               │                  
                    │   1618 │   def _parse_object_header(se │                  
                    │   1619 │   │   """                     │                  
                    │                                        │                  
                    │ /home/runner/work/_temp/setup-uv-cache │                  
                    │ /archive-v0/RSMkjl3R3t64vpgxKv1Ws/lib/ │                  
                    │ python3.12/site-packages/git/cmd.py:14 │                  
                    │ 06 in execute                          │                  
                    │                                        │                  
                    │   1403 │   │   # END handle debug prin │                  
                    │   1404 │   │                           │                  
                    │   1405 │   │   if with_exceptions and  │                  
                    │ ❱ 1406 │   │   │   raise GitCommandErr │                  
                    │   1407 │   │                           │                  
                    │   1408 │   │   if isinstance(stdout_va │                  
                    │        output_stream.                  │                  
                    │   1409 │   │   │   stdout_value = safe │                  
                    ╰────────────────────────────────────────╯                  
                    GitCommandError: Cmd('git') failed due to:                  
                    exit code(1)                                                
                      cmdline: git push                                         
                    ***github.com/<redacted>.git main                                             
                      stderr: 'remote: error: GH013:                            
                    Repository rule violations found for                        
                    refs/heads/main.                                            
                    remote: Review all repository rules at                      
                    https://github.com/<redacted>/rules                  
                    ?ref=refs%2Fheads%2Fmain                                    
                    remote:                                                     
                    remote: - Changes must be made through a                    
                    pull request.                                               
                    remote:                                                     
                    To                                                          
                    https://github.com/<redacted>.git                    
                     ! [remote rejected] main -> main (push                     
                    declined due to repository rule                             
                    violations)                                                 
                    error: failed to push some refs to                          
                    'https://github.com/<redacted>.git'                  
                    '       
### Environment
  • Operating System (w/ version): Ubuntu 24.04.3 LTS
  • Python version: 3.12.3
  • Pip version: unknown
  • Semantic-release version: 10.5.2
  • Build tool (w/ version): uv

Configuration

Semantic Release Configuration
[tool.semantic_release]
  branch = "main"
  build_command = "uv build"
  commit_message = "chore(release): v{version} [skip ci]"
  commit_version_number = true
  upload_to_pypi = false
  upload_to_release = true
  upload_to_repository = false
  version_source = "tag"
  version_toml = ["pyproject.toml:project.version"]

  [tool.semantic_release.commit_parser_options]
    allowed_tags = [
      "build",
      "chore",
      "ci",
      "docs",
      "feat",
      "fix",
      "perf",
      "refactor",
      "style",
      "test",
    ]
    minor_tags = ["feat"]
    patch_tags = ["build", "chore", "ci", "fix", "perf", "test"]

GitHub Actions Job Definition
jobs:
  release:
    runs-on: ubuntu-latest
    outputs:
      released: ${{ steps.release.outputs.released }}
      tag: ${{ steps.release.outputs.tag }}
    steps:
      - name: Checkout Repo
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
          persist-credentials: false

      - name: "Setup Python & UV"
        [...]

      - name: Python Semantic Release
        id: release
        run: |
          git config --global user.name "github-actions"
          git config --global user.email "github-actions@github.com"
          uvx python-semantic-release=="10.*" version --skip-build --no-commit --no-tag --no-changelog
          uv lock
          git add uv.lock
          uvx python-semantic-release=="10.*" version
        env:
          GH_TOKEN: ${{ secrets.SEMANTIC_RELEASE_GITHUB_TOKEN }}

      - name: Publish package distributions to GitHub Releases
        if: steps.release.outputs.released == 'true'
        run: |
          uvx python-semantic-release=="10.*" publish --tag "${{steps.release.outputs.tag}}"
        env:
          GH_TOKEN: ${{ github.token }}

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working properlyreleased

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions