python-semantic-release 10.5.0__tar.gz → 10.5.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (238) hide show
  1. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/PKG-INFO +1 -1
  2. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/configuration/automatic-releases/github-actions.rst +9 -9
  3. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/configuration/configuration.rst +1 -1
  4. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/pyproject.toml +1 -1
  5. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/cli/commands/version.py +5 -1
  6. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/gitproject.py +31 -7
  7. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/test_version_upstream_check.py +132 -0
  8. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/test_gitproject.py +28 -4
  9. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/LICENSE +0 -0
  10. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/MANIFEST.in +0 -0
  11. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/README.rst +0 -0
  12. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/Makefile +0 -0
  13. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/api/commands.rst +0 -0
  14. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/concepts/changelog_templates.rst +0 -0
  15. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/concepts/commit_parsing.rst +0 -0
  16. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/concepts/getting_started.rst +0 -0
  17. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/concepts/index.rst +0 -0
  18. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/concepts/installation.rst +0 -0
  19. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/concepts/multibranch_releases.rst +0 -0
  20. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/concepts/strict_mode.rst +0 -0
  21. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/conf.py +0 -0
  22. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/configuration/automatic-releases/cronjobs.rst +0 -0
  23. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/configuration/automatic-releases/index.rst +0 -0
  24. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/configuration/automatic-releases/travis.rst +0 -0
  25. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/configuration/configuration-guides/index.rst +0 -0
  26. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/configuration/configuration-guides/monorepos-ex-easy-before-release.png +0 -0
  27. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/configuration/configuration-guides/monorepos-ex-easy-post-release.png +0 -0
  28. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/configuration/configuration-guides/monorepos.rst +0 -0
  29. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/configuration/configuration-guides/uv_integration.rst +0 -0
  30. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/configuration/index.rst +0 -0
  31. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/contributing/contributing_guide.rst +0 -0
  32. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/contributing/index.rst +0 -0
  33. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/index.rst +0 -0
  34. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/make.bat +0 -0
  35. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/misc/psr_changelog.rst +0 -0
  36. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/misc/troubleshooting.rst +0 -0
  37. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/upgrading/08-upgrade.rst +0 -0
  38. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/upgrading/09-upgrade.rst +0 -0
  39. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/upgrading/10-upgrade.rst +0 -0
  40. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/docs/upgrading/index.rst +0 -0
  41. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/setup.cfg +0 -0
  42. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/python_semantic_release.egg-info/SOURCES.txt +0 -0
  43. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/__init__.py +0 -0
  44. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/__main__.py +0 -0
  45. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/changelog/__init__.py +0 -0
  46. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/changelog/context.py +0 -0
  47. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/changelog/release_history.py +0 -0
  48. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/changelog/template.py +0 -0
  49. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/cli/__init__.py +0 -0
  50. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/cli/changelog_writer.py +0 -0
  51. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/cli/cli_context.py +0 -0
  52. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/cli/commands/__init__.py +0 -0
  53. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/cli/commands/changelog.py +0 -0
  54. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/cli/commands/generate_config.py +0 -0
  55. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/cli/commands/main.py +0 -0
  56. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/cli/commands/publish.py +0 -0
  57. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/cli/config.py +0 -0
  58. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/cli/const.py +0 -0
  59. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/cli/github_actions_output.py +0 -0
  60. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/cli/masking_filter.py +0 -0
  61. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/cli/util.py +0 -0
  62. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/commit_parser/__init__.py +0 -0
  63. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/commit_parser/_base.py +0 -0
  64. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/commit_parser/angular.py +0 -0
  65. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/commit_parser/conventional/__init__.py +0 -0
  66. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/commit_parser/conventional/options.py +0 -0
  67. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/commit_parser/conventional/options_monorepo.py +0 -0
  68. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/commit_parser/conventional/parser.py +0 -0
  69. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/commit_parser/conventional/parser_monorepo.py +0 -0
  70. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/commit_parser/emoji.py +0 -0
  71. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/commit_parser/scipy.py +0 -0
  72. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/commit_parser/tag.py +0 -0
  73. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/commit_parser/token.py +0 -0
  74. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/commit_parser/util.py +0 -0
  75. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/const.py +0 -0
  76. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/data/templates/conventional/md/.components/changelog_header.md.j2 +0 -0
  77. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/data/templates/conventional/md/.components/changelog_init.md.j2 +0 -0
  78. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/data/templates/conventional/md/.components/changelog_update.md.j2 +0 -0
  79. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/data/templates/conventional/md/.components/changes.md.j2 +0 -0
  80. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/data/templates/conventional/md/.components/first_release.md.j2 +0 -0
  81. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/data/templates/conventional/md/.components/macros.md.j2 +0 -0
  82. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/data/templates/conventional/md/.components/unreleased_changes.md.j2 +0 -0
  83. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/data/templates/conventional/md/.components/versioned_changes.md.j2 +0 -0
  84. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/data/templates/conventional/md/.release_notes.md.j2 +0 -0
  85. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/data/templates/conventional/md/CHANGELOG.md.j2 +0 -0
  86. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/data/templates/conventional/rst/.components/changelog_header.rst.j2 +0 -0
  87. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/data/templates/conventional/rst/.components/changelog_init.rst.j2 +0 -0
  88. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/data/templates/conventional/rst/.components/changelog_update.rst.j2 +0 -0
  89. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/data/templates/conventional/rst/.components/changes.rst.j2 +0 -0
  90. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/data/templates/conventional/rst/.components/first_release.rst.j2 +0 -0
  91. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/data/templates/conventional/rst/.components/macros.rst.j2 +0 -0
  92. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/data/templates/conventional/rst/.components/unreleased_changes.rst.j2 +0 -0
  93. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/data/templates/conventional/rst/.components/versioned_changes.rst.j2 +0 -0
  94. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/data/templates/conventional/rst/CHANGELOG.rst.j2 +0 -0
  95. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/enums.py +0 -0
  96. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/errors.py +0 -0
  97. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/globals.py +0 -0
  98. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/helpers.py +0 -0
  99. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/hvcs/__init__.py +0 -0
  100. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/hvcs/_base.py +0 -0
  101. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/hvcs/bitbucket.py +0 -0
  102. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/hvcs/gitea.py +0 -0
  103. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/hvcs/github.py +0 -0
  104. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/hvcs/gitlab.py +0 -0
  105. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/hvcs/remote_hvcs_base.py +0 -0
  106. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/hvcs/token_auth.py +0 -0
  107. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/hvcs/util.py +0 -0
  108. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/py.typed +0 -0
  109. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/version/__init__.py +0 -0
  110. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/version/algorithm.py +0 -0
  111. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/version/declaration.py +0 -0
  112. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/version/declarations/__init__.py +0 -0
  113. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/version/declarations/enum.py +0 -0
  114. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/version/declarations/i_version_replacer.py +0 -0
  115. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/version/declarations/pattern.py +0 -0
  116. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/version/declarations/toml.py +0 -0
  117. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/version/translator.py +0 -0
  118. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/src/semantic_release/version/version.py +0 -0
  119. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/__init__.py +0 -0
  120. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/conftest.py +0 -0
  121. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/const.py +0 -0
  122. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/__init__.py +0 -0
  123. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_changelog/__init__.py +0 -0
  124. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_changelog/test_changelog.py +0 -0
  125. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_changelog/test_changelog_custom_parser.py +0 -0
  126. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_changelog/test_changelog_parsing.py +0 -0
  127. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_changelog/test_changelog_release_notes.py +0 -0
  128. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_config/__init__.py +0 -0
  129. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_config/test_generate_config.py +0 -0
  130. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_publish/__init__.py +0 -0
  131. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_publish/test_publish.py +0 -0
  132. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/__init__.py +0 -0
  133. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/bump_version/__init__.py +0 -0
  134. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/bump_version/conftest.py +0 -0
  135. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/bump_version/git_flow/__init__.py +0 -0
  136. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/bump_version/git_flow/test_repo_1_channel.py +0 -0
  137. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/bump_version/git_flow/test_repo_2_channels.py +0 -0
  138. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/bump_version/git_flow/test_repo_3_channels.py +0 -0
  139. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/bump_version/git_flow/test_repo_4_channels.py +0 -0
  140. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/bump_version/github_flow/__init__.py +0 -0
  141. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/bump_version/github_flow/test_repo_1_channel.py +0 -0
  142. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/bump_version/github_flow/test_repo_1_channel_branch_update_merge.py +0 -0
  143. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/bump_version/github_flow/test_repo_2_channels.py +0 -0
  144. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/bump_version/github_flow_monorepo/__init__.py +0 -0
  145. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/bump_version/github_flow_monorepo/test_monorepo_1_channel.py +0 -0
  146. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/bump_version/github_flow_monorepo/test_monorepo_2_channels.py +0 -0
  147. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/bump_version/trunk_based_dev/__init__.py +0 -0
  148. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/bump_version/trunk_based_dev/test_repo_trunk.py +0 -0
  149. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/bump_version/trunk_based_dev/test_repo_trunk_dual_version_support.py +0 -0
  150. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/bump_version/trunk_based_dev/test_repo_trunk_dual_version_support_w_prereleases.py +0 -0
  151. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/bump_version/trunk_based_dev/test_repo_trunk_w_prereleases.py +0 -0
  152. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/bump_version/trunk_based_dev_monorepo/__init__.py +0 -0
  153. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/bump_version/trunk_based_dev_monorepo/test_monorepo_trunk.py +0 -0
  154. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/test_version.py +0 -0
  155. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/test_version_build.py +0 -0
  156. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/test_version_bump.py +0 -0
  157. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/test_version_changelog.py +0 -0
  158. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/test_version_changelog_custom_commit_msg.py +0 -0
  159. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/test_version_github_actions.py +0 -0
  160. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/test_version_partial_tag.py +0 -0
  161. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/test_version_print.py +0 -0
  162. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/test_version_release_notes.py +0 -0
  163. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/test_version_shallow.py +0 -0
  164. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/test_version_stamp.py +0 -0
  165. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/cmd_version/test_version_strict.py +0 -0
  166. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/conftest.py +0 -0
  167. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/test_help.py +0 -0
  168. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/e2e/test_main.py +0 -0
  169. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/fixtures/__init__.py +0 -0
  170. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/fixtures/commit_parsers.py +0 -0
  171. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/fixtures/example_project.py +0 -0
  172. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/fixtures/git_repo.py +0 -0
  173. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/fixtures/monorepos/__init__.py +0 -0
  174. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/fixtures/monorepos/example_monorepo.py +0 -0
  175. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/fixtures/monorepos/git_monorepo.py +0 -0
  176. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/fixtures/monorepos/github_flow/__init__.py +0 -0
  177. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/fixtures/monorepos/github_flow/monorepo_w_default_release.py +0 -0
  178. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/fixtures/monorepos/github_flow/monorepo_w_release_channels.py +0 -0
  179. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/fixtures/monorepos/trunk_based_dev/__init__.py +0 -0
  180. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/fixtures/monorepos/trunk_based_dev/monorepo_w_tags.py +0 -0
  181. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/fixtures/repos/__init__.py +0 -0
  182. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/fixtures/repos/git_flow/__init__.py +0 -0
  183. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/fixtures/repos/git_flow/repo_w_1_release_channel.py +0 -0
  184. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/fixtures/repos/git_flow/repo_w_2_release_channels.py +0 -0
  185. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/fixtures/repos/git_flow/repo_w_3_release_channels.py +0 -0
  186. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/fixtures/repos/git_flow/repo_w_4_release_channels.py +0 -0
  187. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/fixtures/repos/github_flow/__init__.py +0 -0
  188. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/fixtures/repos/github_flow/repo_w_default_release.py +0 -0
  189. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/fixtures/repos/github_flow/repo_w_default_release_w_branch_update_merge.py +0 -0
  190. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/fixtures/repos/github_flow/repo_w_release_channels.py +0 -0
  191. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/fixtures/repos/repo_initial_commit.py +0 -0
  192. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/fixtures/repos/trunk_based_dev/__init__.py +0 -0
  193. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/fixtures/repos/trunk_based_dev/repo_w_dual_version_support.py +0 -0
  194. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/fixtures/repos/trunk_based_dev/repo_w_dual_version_support_w_prereleases.py +0 -0
  195. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/fixtures/repos/trunk_based_dev/repo_w_no_tags.py +0 -0
  196. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/fixtures/repos/trunk_based_dev/repo_w_prereleases.py +0 -0
  197. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/fixtures/repos/trunk_based_dev/repo_w_tags.py +0 -0
  198. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/fixtures/scipy.py +0 -0
  199. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/__init__.py +0 -0
  200. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/conftest.py +0 -0
  201. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/__init__.py +0 -0
  202. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/changelog/__init__.py +0 -0
  203. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/changelog/conftest.py +0 -0
  204. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/changelog/test_changelog_context.py +0 -0
  205. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/changelog/test_default_changelog.py +0 -0
  206. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/changelog/test_release_history.py +0 -0
  207. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/changelog/test_release_notes.py +0 -0
  208. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/changelog/test_template.py +0 -0
  209. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/changelog/test_template_render.py +0 -0
  210. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/cli/__init__.py +0 -0
  211. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/cli/test_config.py +0 -0
  212. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/cli/test_github_actions_output.py +0 -0
  213. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/cli/test_masking_filter.py +0 -0
  214. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/cli/test_util.py +0 -0
  215. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/cli/test_version.py +0 -0
  216. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/commit_parser/__init__.py +0 -0
  217. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/commit_parser/test_conventional.py +0 -0
  218. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/commit_parser/test_emoji.py +0 -0
  219. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/commit_parser/test_parsed_commit.py +0 -0
  220. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/commit_parser/test_scipy.py +0 -0
  221. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/commit_parser/test_util.py +0 -0
  222. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/hvcs/__init__.py +0 -0
  223. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/hvcs/test__base.py +0 -0
  224. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/hvcs/test_bitbucket.py +0 -0
  225. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/hvcs/test_gitea.py +0 -0
  226. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/hvcs/test_github.py +0 -0
  227. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/hvcs/test_gitlab.py +0 -0
  228. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/hvcs/test_token_auth.py +0 -0
  229. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/hvcs/test_util.py +0 -0
  230. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/test_helpers.py +0 -0
  231. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/version/__init__.py +0 -0
  232. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/version/declarations/__init__.py +0 -0
  233. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/version/declarations/test_pattern_declaration.py +0 -0
  234. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/version/declarations/test_toml_declaration.py +0 -0
  235. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/version/test_algorithm.py +0 -0
  236. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/version/test_translator.py +0 -0
  237. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/unit/semantic_release/version/test_version.py +0 -0
  238. {python_semantic_release-10.5.0 → python_semantic_release-10.5.1}/tests/util.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-semantic-release
3
- Version: 10.5.0
3
+ Version: 10.5.1
4
4
  Summary: Automatic Semantic Versioning for Python projects
5
5
  Author-email: Rolf Erik Lekang <me@rolflekang.com>, codejedi365 <codejedi365@gmail.com>
6
6
  License: MIT
@@ -893,14 +893,14 @@ to the GitHub Release Assets as well.
893
893
  - name: Action | Semantic Version Release
894
894
  id: release
895
895
  # Adjust tag with desired version if applicable.
896
- uses: python-semantic-release/python-semantic-release@v10.5.0
896
+ uses: python-semantic-release/python-semantic-release@v10.5.1
897
897
  with:
898
898
  github_token: ${{ secrets.GITHUB_TOKEN }}
899
899
  git_committer_name: "github-actions"
900
900
  git_committer_email: "actions@users.noreply.github.com"
901
901
 
902
902
  - name: Publish | Upload to GitHub Release Assets
903
- uses: python-semantic-release/publish-action@v10.5.0
903
+ uses: python-semantic-release/publish-action@v10.5.1
904
904
  if: steps.release.outputs.released == 'true'
905
905
  with:
906
906
  github_token: ${{ secrets.GITHUB_TOKEN }}
@@ -969,7 +969,7 @@ to the GitHub Release Assets as well.
969
969
  the ``token`` input) in order to gain push access.
970
970
 
971
971
  .. note::
972
- As of $NEW_RELEASE_TAG, Python Semantic Release automatically detects and converts
972
+ As of v10.5.0, Python Semantic Release automatically detects and converts
973
973
  shallow clones to full clones when needed. While you can still use ``fetch-depth: 0``
974
974
  with ``actions/checkout@v4`` to fetch the full history upfront, it is no longer
975
975
  required. If you use the default shallow clone, Python Semantic Release will
@@ -977,7 +977,7 @@ to the GitHub Release Assets as well.
977
977
  an older version of PSR, you will need to unshallow the repository prior to use.
978
978
 
979
979
  .. note::
980
- As of $NEW_RELEASE_TAG, the verify upstream step is no longer required as it has been
980
+ As of v10.5.0, the verify upstream step is no longer required as it has been
981
981
  integrated into PSR directly. If you are using an older version of PSR, you will need
982
982
  to review the older documentation for that step. See Issue `#1201`_ for more details.
983
983
 
@@ -1005,7 +1005,7 @@ The equivalent GitHub Action configuration would be:
1005
1005
 
1006
1006
  - name: Action | Semantic Version Release
1007
1007
  # Adjust tag with desired version if applicable.
1008
- uses: python-semantic-release/python-semantic-release@v10.5.0
1008
+ uses: python-semantic-release/python-semantic-release@v10.5.1
1009
1009
  with:
1010
1010
  github_token: ${{ secrets.GITHUB_TOKEN }}
1011
1011
  force: patch
@@ -1064,14 +1064,14 @@ Publish Action.
1064
1064
 
1065
1065
  - name: Release submodule 1
1066
1066
  id: release-submod-1
1067
- uses: python-semantic-release/python-semantic-release@v10.5.0
1067
+ uses: python-semantic-release/python-semantic-release@v10.5.1
1068
1068
  with:
1069
1069
  directory: ${{ env.SUBMODULE_1_DIR }}
1070
1070
  github_token: ${{ secrets.GITHUB_TOKEN }}
1071
1071
 
1072
1072
  - name: Release submodule 2
1073
1073
  id: release-submod-2
1074
- uses: python-semantic-release/python-semantic-release@v10.5.0
1074
+ uses: python-semantic-release/python-semantic-release@v10.5.1
1075
1075
  with:
1076
1076
  directory: ${{ env.SUBMODULE_2_DIR }}
1077
1077
  github_token: ${{ secrets.GITHUB_TOKEN }}
@@ -1083,7 +1083,7 @@ Publish Action.
1083
1083
  # ------------------------------------------------------------------- #
1084
1084
 
1085
1085
  - name: Publish | Upload package 1 to GitHub Release Assets
1086
- uses: python-semantic-release/publish-action@v10.5.0
1086
+ uses: python-semantic-release/publish-action@v10.5.1
1087
1087
  if: steps.release-submod-1.outputs.released == 'true'
1088
1088
  with:
1089
1089
  directory: ${{ env.SUBMODULE_1_DIR }}
@@ -1091,7 +1091,7 @@ Publish Action.
1091
1091
  tag: ${{ steps.release-submod-1.outputs.tag }}
1092
1092
 
1093
1093
  - name: Publish | Upload package 2 to GitHub Release Assets
1094
- uses: python-semantic-release/publish-action@v10.5.0
1094
+ uses: python-semantic-release/publish-action@v10.5.1
1095
1095
  if: steps.release-submod-2.outputs.released == 'true'
1096
1096
  with:
1097
1097
  directory: ${{ env.SUBMODULE_2_DIR }}
@@ -1398,7 +1398,7 @@ The regular expression generated from the ``version_variables`` definition will:
1398
1398
  2. The variable name defined by ``variable`` and the version must be separated by
1399
1399
  an operand symbol (``=``, ``:``, ``:=``, or ``@``). Whitespace is optional around
1400
1400
  the symbol. As of v10.0.0, a double-equals (``==``) operator is also supported
1401
- as a valid operand symbol. As of $NEW_RELEASE_TAG, PSR can omit all operands as long
1401
+ as a valid operand symbol. As of v10.5.0, PSR can omit all operands as long
1402
1402
  as there is at least one whitespace character between the variable name and the version.
1403
1403
 
1404
1404
  3. The value of the variable must match a `SemVer`_ regular expression and can be
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
6
6
 
7
7
  [project]
8
8
  name = "python-semantic-release"
9
- version = "10.5.0"
9
+ version = "10.5.1"
10
10
  description = "Automatic Semantic Versioning for Python projects"
11
11
  requires-python = "~= 3.8"
12
12
  license = { text = "MIT" }
@@ -749,7 +749,11 @@ def version( # noqa: C901
749
749
  # This prevents conflicts if another commit was pushed while we were preparing the release
750
750
  # We check HEAD~1 because we just made a release commit
751
751
  try:
752
- project.verify_upstream_unchanged(local_ref="HEAD~1", noop=opts.noop)
752
+ project.verify_upstream_unchanged(
753
+ local_ref="HEAD~1",
754
+ upstream_ref=config.remote.name,
755
+ noop=opts.noop,
756
+ )
753
757
  except UpstreamBranchChangedError as exc:
754
758
  click.echo(str(exc), err=True)
755
759
  click.echo(
@@ -335,17 +335,23 @@ class GitProject:
335
335
  self.logger.exception(str(err))
336
336
  raise GitPushError(f"Failed to push tag ({tag}) to remote") from err
337
337
 
338
- def verify_upstream_unchanged(
339
- self, local_ref: str = "HEAD", noop: bool = False
338
+ def verify_upstream_unchanged( # noqa: C901
339
+ self, local_ref: str = "HEAD", upstream_ref: str = "origin", noop: bool = False
340
340
  ) -> None:
341
341
  """
342
342
  Verify that the upstream branch has not changed since the given local reference.
343
343
 
344
344
  :param local_ref: The local reference to compare against upstream (default: HEAD)
345
+ :param upstream_ref: The name of the upstream remote or specific remote branch (default: origin)
345
346
  :param noop: Whether to skip the actual verification (for dry-run mode)
346
347
 
347
348
  :raises UpstreamBranchChangedError: If the upstream branch has changed
348
349
  """
350
+ if not local_ref.strip():
351
+ raise ValueError("Local reference cannot be empty")
352
+ if not upstream_ref.strip():
353
+ raise ValueError("Upstream reference cannot be empty")
354
+
349
355
  if noop:
350
356
  noop_report(
351
357
  indented(
@@ -368,12 +374,30 @@ class GitProject:
368
374
  raise DetachedHeadGitError(err_msg) from None
369
375
 
370
376
  # Get the tracking branch (upstream branch)
371
- if (tracking_branch := active_branch.tracking_branch()) is None:
372
- err_msg = f"No upstream branch found for '{active_branch.name}'; cannot verify upstream state!"
373
- raise UnknownUpstreamBranchError(err_msg)
377
+ if (tracking_branch := active_branch.tracking_branch()) is not None:
378
+ upstream_full_ref_name = tracking_branch.name
379
+ self.logger.info("Upstream branch name: %s", upstream_full_ref_name)
380
+ else:
381
+ # If no tracking branch is set, derive it
382
+ upstream_name = (
383
+ upstream_ref.strip()
384
+ if upstream_ref.find("/") == -1
385
+ else upstream_ref.strip().split("/", maxsplit=1)[0]
386
+ )
387
+
388
+ if not repo.remotes or upstream_name not in repo.remotes:
389
+ err_msg = "No remote found; cannot verify upstream state!"
390
+ raise UnknownUpstreamBranchError(err_msg)
391
+
392
+ upstream_full_ref_name = (
393
+ f"{upstream_name}/{active_branch.name}"
394
+ if upstream_ref.find("/") == -1
395
+ else upstream_ref.strip()
396
+ )
374
397
 
375
- upstream_full_ref_name = tracking_branch.name
376
- self.logger.info("Upstream branch name: %s", upstream_full_ref_name)
398
+ if upstream_full_ref_name not in repo.refs:
399
+ err_msg = f"No upstream branch found for '{active_branch.name}'; cannot verify upstream state!"
400
+ raise UnknownUpstreamBranchError(err_msg)
377
401
 
378
402
  # Extract the remote name from the tracking branch
379
403
  # tracking_branch.name is in the format "remote/branch"
@@ -3,6 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import contextlib
6
+ from pathlib import PureWindowsPath
6
7
  from typing import TYPE_CHECKING, cast
7
8
 
8
9
  import pytest
@@ -159,6 +160,137 @@ def test_version_upstream_check_success_no_changes(
159
160
  assert expected_vcs_url_post == post_mocker.call_count # one vcs release created
160
161
 
161
162
 
163
+ @pytest.mark.parametrize(
164
+ "repo_fixture_name, build_repo_fn",
165
+ [
166
+ (
167
+ repo_fixture_name,
168
+ lazy_fixture(build_repo_fn_name),
169
+ )
170
+ for repo_fixture_name, build_repo_fn_name in [
171
+ (
172
+ repo_w_trunk_only_conventional_commits.__name__,
173
+ build_trunk_only_repo_w_tags.__name__,
174
+ ),
175
+ ]
176
+ ],
177
+ )
178
+ @pytest.mark.usefixtures(change_to_ex_proj_dir.__name__)
179
+ def test_version_upstream_check_success_no_changes_untracked_branch(
180
+ repo_fixture_name: str,
181
+ run_cli: RunCliFn,
182
+ build_repo_fn: BuildSpecificRepoFn,
183
+ example_project_dir: ExProjectDir,
184
+ git_repo_for_directory: GetGitRepo4DirFn,
185
+ post_mocker: Mocker,
186
+ get_cfg_value_from_def: GetCfgValueFromDefFn,
187
+ get_versions_from_repo_build_def: GetVersionsFromRepoBuildDefFn,
188
+ pyproject_toml_file: Path,
189
+ update_pyproject_toml: UpdatePyprojectTomlFn,
190
+ ):
191
+ """Test that PSR succeeds when the upstream branch is untracked but unchanged."""
192
+ remote_name = "origin"
193
+ # Create a bare remote (simulating origin)
194
+ local_origin = Repo.init(str(example_project_dir / "local_origin"), bare=True)
195
+
196
+ # build target repo into a temporary directory
197
+ target_repo_dir = example_project_dir / repo_fixture_name
198
+ commit_type: CommitConvention = (
199
+ repo_fixture_name.split("commits", 1)[0].split("_")[-2] # type: ignore[assignment]
200
+ )
201
+ target_repo_definition = build_repo_fn(
202
+ repo_name=repo_fixture_name,
203
+ commit_type=commit_type,
204
+ dest_dir=target_repo_dir,
205
+ )
206
+ target_git_repo = git_repo_for_directory(target_repo_dir)
207
+
208
+ # Configure the source repo to use the bare remote (removing any existing 'origin')
209
+ with contextlib.suppress(AttributeError):
210
+ target_git_repo.delete_remote(target_git_repo.remotes[remote_name])
211
+
212
+ target_git_repo.create_remote(remote_name, str(local_origin.working_dir))
213
+
214
+ # Remove last release before pushing to upstream
215
+ tag_format_str = cast(
216
+ "str", get_cfg_value_from_def(target_repo_definition, "tag_format_str")
217
+ )
218
+ latest_tag = tag_format_str.format(
219
+ version=get_versions_from_repo_build_def(target_repo_definition)[-1]
220
+ )
221
+ target_git_repo.git.tag("-d", latest_tag)
222
+ target_git_repo.git.reset("--hard", "HEAD~1")
223
+
224
+ # TODO: when available, switch this to use hvcs=none or similar config to avoid token use for push
225
+ update_pyproject_toml(
226
+ "tool.semantic_release.remote.ignore_token_for_push",
227
+ True,
228
+ target_repo_dir / pyproject_toml_file,
229
+ )
230
+ target_git_repo.git.commit(amend=True, no_edit=True, all=True)
231
+
232
+ # push the current state to establish the remote (cannot push tags and branches at the same time)
233
+ target_git_repo.git.push(remote_name, all=True) # all branches
234
+ target_git_repo.git.push(remote_name, tags=True) # all tags
235
+
236
+ # ensure bare remote HEAD points to the active branch so clones can checkout
237
+ local_origin.git.symbolic_ref(
238
+ "HEAD", f"refs/heads/{target_git_repo.active_branch.name}"
239
+ )
240
+
241
+ # Simulate CI environment after someone pushes to the repo
242
+ ci_commit_sha = target_git_repo.head.commit.hexsha
243
+ ci_branch = target_git_repo.active_branch.name
244
+
245
+ # current remote tags
246
+ remote_origin_tags_before = {tag.name for tag in local_origin.tags}
247
+
248
+ # Simulate a CI environment by fetching the repo to a new location
249
+ test_repo = Repo.init(str(example_project_dir / "ci_repo"))
250
+ with test_repo.config_writer("repository") as config:
251
+ config.set_value("core", "hookspath", "")
252
+ config.set_value("commit", "gpgsign", False)
253
+ config.set_value("tag", "gpgsign", False)
254
+
255
+ # Configure and retrieve the repository (see GitHub actions/checkout@v5)
256
+ test_repo.git.remote(
257
+ "add",
258
+ remote_name,
259
+ f"file:///{PureWindowsPath(local_origin.working_dir).as_posix()}",
260
+ )
261
+ test_repo.git.fetch("--depth=1", remote_name, ci_commit_sha)
262
+
263
+ # Simulate CI environment and recommended workflow (in docs)
264
+ # NOTE: this could be done in 1 step, but most CI pipelines are doing it in 2 steps
265
+ # 1. Checkout the commit sha (detached head)
266
+ test_repo.git.checkout(ci_commit_sha, force=True)
267
+ # 2. Forcefully set the branch to the current detached head
268
+ test_repo.git.checkout("-B", ci_branch)
269
+
270
+ # Act: run PSR on the cloned repo - it should verify upstream and succeed
271
+ with temporary_working_directory(str(test_repo.working_dir)):
272
+ cli_cmd = [MAIN_PROG_NAME, "--strict", VERSION_SUBCMD]
273
+ result = run_cli(cli_cmd[1:], env={Github.DEFAULT_ENV_TOKEN_NAME: "1234"})
274
+
275
+ remote_origin_tags_after = {tag.name for tag in local_origin.tags}
276
+
277
+ # Evaluate
278
+ assert_successful_exit_code(result, cli_cmd)
279
+
280
+ # Verify release occurred as expected
281
+ with test_repo:
282
+ assert latest_tag in test_repo.tags, "Expected release tag to be created"
283
+ assert ci_commit_sha in [
284
+ parent.hexsha for parent in test_repo.head.commit.parents
285
+ ], "Expected new commit to be created on HEAD"
286
+ different_tags = remote_origin_tags_after.difference(remote_origin_tags_before)
287
+ assert latest_tag in different_tags, "Expected new tag to be pushed to remote"
288
+
289
+ # Verify VCS release was created
290
+ expected_vcs_url_post = 1
291
+ assert expected_vcs_url_post == post_mocker.call_count # one vcs release created
292
+
293
+
162
294
  @pytest.mark.parametrize(
163
295
  "repo_fixture_name, build_repo_fn",
164
296
  [
@@ -38,6 +38,7 @@ if TYPE_CHECKING:
38
38
  git: MockGit
39
39
  git_dir: str
40
40
  commit: MagicMock
41
+ refs: dict[str, MagicMock]
41
42
 
42
43
 
43
44
  @pytest.fixture
@@ -70,6 +71,7 @@ def mock_repo(tmp_path: Path) -> RepoMock:
70
71
 
71
72
  remote_obj.refs = {"main": ref_obj}
72
73
  repo.remotes = {"origin": remote_obj}
74
+ repo.refs = {"origin/main": ref_obj}
73
75
 
74
76
  # Mock git.rev_parse
75
77
  repo.git = MagicMock()
@@ -146,16 +148,38 @@ def test_verify_upstream_unchanged_noop(
146
148
  mock_repo.assert_not_called()
147
149
 
148
150
 
149
- def test_verify_upstream_unchanged_no_tracking_branch(
151
+ def test_verify_upstream_unchanged_no_remote(
150
152
  mock_gitproject: GitProject, mock_repo: RepoMock
151
153
  ):
152
- """Test that verify_upstream_unchanged raises error when no tracking branch exists."""
153
- # Mock no tracking branch
154
+ """Test that verify_upstream_unchanged raises error when no remote exists."""
155
+ # Mock no remote
156
+ mock_repo.remotes = {}
157
+ # Simulate no tracking branch
154
158
  mock_repo.active_branch.tracking_branch = MagicMock(return_value=None)
155
159
 
160
+ # Should raise UnknownUpstreamBranchError
161
+ with pytest.raises(
162
+ UnknownUpstreamBranchError,
163
+ match="No remote found; cannot verify upstream state!",
164
+ ):
165
+ mock_gitproject.verify_upstream_unchanged(
166
+ local_ref="HEAD", upstream_ref="upstream", noop=False
167
+ )
168
+
169
+
170
+ def test_verify_upstream_unchanged_no_upstream_ref(
171
+ mock_gitproject: GitProject, mock_repo: RepoMock
172
+ ):
173
+ """Test that verify_upstream_unchanged raises error when no upstream ref exists."""
174
+ # Simulate no tracking branch
175
+ mock_repo.active_branch.tracking_branch = MagicMock(return_value=None)
176
+ mock_repo.refs = {} # No refs available
177
+
156
178
  # Should raise UnknownUpstreamBranchError
157
179
  with pytest.raises(UnknownUpstreamBranchError, match="No upstream branch found"):
158
- mock_gitproject.verify_upstream_unchanged(local_ref="HEAD", noop=False)
180
+ mock_gitproject.verify_upstream_unchanged(
181
+ local_ref="HEAD", upstream_ref="origin", noop=False
182
+ )
159
183
 
160
184
 
161
185
  def test_verify_upstream_unchanged_detached_head(