From 3670b81baa8e59bce6906a66618993fa11f90501 Mon Sep 17 00:00:00 2001 From: codejedi365 Date: Mon, 10 Nov 2025 10:40:06 -0700 Subject: [PATCH 1/8] test(config): streamline error logging & prevent duplicate logging during testing --- tests/conftest.py | 10 +++++++++- tests/util.py | 33 ++++++++++++++------------------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 7a00b8dad..df4e2f82d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -206,6 +206,10 @@ def _run_cli( invoke_kwargs: dict[str, Any] | None = None, ) -> Result: from semantic_release.cli.commands.main import main + from semantic_release.globals import logger + + # Prevent logs from being propagated to the root logger (pytest) + logger.propagate = False cli_runner = CliRunner(mix_stderr=False) env_vars = {**clean_os_environment, **(env or {})} @@ -213,7 +217,11 @@ def _run_cli( with mock.patch.dict(os.environ, env_vars, clear=True): # run the CLI with the provided arguments - return cli_runner.invoke(main, args=args, **(invoke_kwargs or {})) + result = cli_runner.invoke(main, args=args, **(invoke_kwargs or {})) + # Force the output to be printed to stdout which will be captured by pytest + sys.stdout.write(result.stdout) + sys.stderr.write(result.stderr) + return result return _run_cli diff --git a/tests/util.py b/tests/util.py index 8d529a769..d97e04845 100644 --- a/tests/util.py +++ b/tests/util.py @@ -58,26 +58,21 @@ def get_func_qual_name(func: Callable) -> str: def assert_exit_code( exit_code: int, result: ClickInvokeResult, cli_cmd: list[str] ) -> bool: - if result.exit_code != exit_code: - raise AssertionError( - str.join( - os.linesep, - [ - f"{result.exit_code} != {exit_code} (actual != expected)", - "", - # Explain what command failed - "Unexpected exit code from command:", - indent(f"'{str.join(' ', cli_cmd)}'", " " * 2), - "", - # Add indentation to each line for stdout & stderr - "stdout:", - indent(result.stdout, " " * 2) if result.stdout.strip() else "", - "stderr:", - indent(result.stderr, " " * 2) if result.stderr.strip() else "", - ], - ) + if result.exit_code == exit_code: + return True + + raise AssertionError( + str.join( + os.linesep, + [ + f"{result.exit_code} != {exit_code} (actual != expected)", + "", + # Explain what command failed + "Unexpected exit code from command:", + indent(f"'{str.join(' ', cli_cmd)}'", " " * 2), + ], ) - return True + ) def assert_successful_exit_code(result: ClickInvokeResult, cli_cmd: list[str]) -> bool: From bc3fa04ee87cee0cad9bc040c754a5b8f3273407 Mon Sep 17 00:00:00 2001 From: codejedi365 Date: Mon, 10 Nov 2025 11:48:59 -0700 Subject: [PATCH 2/8] test(cmd-version): update `--print*` tests to assert on click test runner's result --- tests/e2e/cmd_version/test_version_print.py | 27 ++------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/tests/e2e/cmd_version/test_version_print.py b/tests/e2e/cmd_version/test_version_print.py index c9a9bd034..cd4ed2406 100644 --- a/tests/e2e/cmd_version/test_version_print.py +++ b/tests/e2e/cmd_version/test_version_print.py @@ -105,7 +105,6 @@ def test_version_print_next_version( next_release_version: str, file_in_repo: str, run_cli: RunCliFn, - mocked_git_fetch: MagicMock, mocked_git_push: MagicMock, post_mocker: Mocker, ): @@ -270,7 +269,6 @@ def test_version_print_tag_prints_next_tag( get_cfg_value_from_def: GetCfgValueFromDefFn, file_in_repo: str, run_cli: RunCliFn, - mocked_git_fetch: MagicMock, mocked_git_push: MagicMock, post_mocker: Mocker, ): @@ -386,7 +384,6 @@ def test_version_print_tag_prints_next_tag_no_zero_versions( get_cfg_value_from_def: GetCfgValueFromDefFn, file_in_repo: str, run_cli: RunCliFn, - mocked_git_fetch: MagicMock, mocked_git_push: MagicMock, post_mocker: Mocker, ): @@ -450,7 +447,6 @@ def test_version_print_last_released_prints_version( repo_result: BuiltRepoResult, get_versions_from_repo_build_def: GetVersionsFromRepoBuildDefFn, run_cli: RunCliFn, - mocked_git_fetch: MagicMock, mocked_git_push: MagicMock, post_mocker: Mocker, strip_logging_messages: StripLoggingMessagesFn, @@ -502,7 +498,6 @@ def test_version_print_last_released_prints_released_if_commits( get_versions_from_repo_build_def: GetVersionsFromRepoBuildDefFn, commits: list[str], run_cli: RunCliFn, - mocked_git_fetch: MagicMock, mocked_git_push: MagicMock, post_mocker: Mocker, file_in_repo: str, @@ -552,10 +547,8 @@ def test_version_print_last_released_prints_released_if_commits( def test_version_print_last_released_prints_nothing_if_no_tags( repo_result: BuiltRepoResult, run_cli: RunCliFn, - mocked_git_fetch: MagicMock, mocked_git_push: MagicMock, post_mocker: Mocker, - caplog: pytest.LogCaptureFixture, ): repo = repo_result["repo"] @@ -577,10 +570,7 @@ def test_version_print_last_released_prints_nothing_if_no_tags( # Evaluate (no release actions should have occurred on print) assert_successful_exit_code(result, cli_cmd) assert result.stdout == "" - - # must use capture log to see this, because we use the logger to print this message - # not click's output - assert "No release tags found." in caplog.text + assert "No release tags found." in result.stderr # assert nothing else happened (no code changes, no commit, no tag, no push, no vcs release) assert repo_status_before == repo_status_after @@ -598,7 +588,6 @@ def test_version_print_last_released_on_detached_head( repo_result: BuiltRepoResult, get_versions_from_repo_build_def: GetVersionsFromRepoBuildDefFn, run_cli: RunCliFn, - mocked_git_fetch: MagicMock, mocked_git_push: MagicMock, post_mocker: Mocker, strip_logging_messages: StripLoggingMessagesFn, @@ -647,7 +636,6 @@ def test_version_print_last_released_on_nonrelease_branch( repo_result: BuiltRepoResult, get_versions_from_repo_build_def: GetVersionsFromRepoBuildDefFn, run_cli: RunCliFn, - mocked_git_fetch: MagicMock, mocked_git_push: MagicMock, post_mocker: Mocker, strip_logging_messages: StripLoggingMessagesFn, @@ -705,7 +693,6 @@ def test_version_print_last_released_tag_prints_correct_tag( get_cfg_value_from_def: GetCfgValueFromDefFn, get_versions_from_repo_build_def: GetVersionsFromRepoBuildDefFn, run_cli: RunCliFn, - mocked_git_fetch: MagicMock, mocked_git_push: MagicMock, post_mocker: Mocker, strip_logging_messages: StripLoggingMessagesFn, @@ -766,7 +753,6 @@ def test_version_print_last_released_tag_prints_released_if_commits( get_versions_from_repo_build_def: GetVersionsFromRepoBuildDefFn, commits: list[str], run_cli: RunCliFn, - mocked_git_fetch: MagicMock, mocked_git_push: MagicMock, post_mocker: Mocker, file_in_repo: str, @@ -817,10 +803,8 @@ def test_version_print_last_released_tag_prints_released_if_commits( def test_version_print_last_released_tag_prints_nothing_if_no_tags( repo_result: BuiltRepoResult, run_cli: RunCliFn, - mocked_git_fetch: MagicMock, mocked_git_push: MagicMock, post_mocker: Mocker, - caplog: pytest.LogCaptureFixture, ): repo = repo_result["repo"] @@ -842,10 +826,7 @@ def test_version_print_last_released_tag_prints_nothing_if_no_tags( # Evaluate (no release actions should have occurred on print) assert_successful_exit_code(result, cli_cmd) assert result.stdout == "" - - # must use capture log to see this, because we use the logger to print this message - # not click's output - assert "No release tags found." in caplog.text + assert "No release tags found." in result.stderr # assert nothing else happened (no code changes, no commit, no tag, no push, no vcs release) assert repo_status_before == repo_status_after @@ -872,7 +853,6 @@ def test_version_print_last_released_tag_on_detached_head( get_cfg_value_from_def: GetCfgValueFromDefFn, get_versions_from_repo_build_def: GetVersionsFromRepoBuildDefFn, run_cli: RunCliFn, - mocked_git_fetch: MagicMock, mocked_git_push: MagicMock, post_mocker: Mocker, strip_logging_messages: StripLoggingMessagesFn, @@ -931,7 +911,6 @@ def test_version_print_last_released_tag_on_nonrelease_branch( get_cfg_value_from_def: GetCfgValueFromDefFn, get_versions_from_repo_build_def: GetVersionsFromRepoBuildDefFn, run_cli: RunCliFn, - mocked_git_fetch: MagicMock, mocked_git_push: MagicMock, post_mocker: Mocker, strip_logging_messages: StripLoggingMessagesFn, @@ -989,7 +968,6 @@ def test_version_print_next_version_fails_on_detached_head( simulate_change_commits_n_rtn_changelog_entry: SimulateChangeCommitsNReturnChangelogEntryFn, get_commit_def_fn: GetCommitDefFn[CommitParser[ParseResult, ParserOptions]], default_parser: CommitParser[ParseResult, ParserOptions], - mocked_git_fetch: MagicMock, mocked_git_push: MagicMock, post_mocker: Mocker, strip_logging_messages: StripLoggingMessagesFn, @@ -1052,7 +1030,6 @@ def test_version_print_next_tag_fails_on_detached_head( simulate_change_commits_n_rtn_changelog_entry: SimulateChangeCommitsNReturnChangelogEntryFn, get_commit_def_fn: GetCommitDefFn[CommitParser[ParseResult, ParserOptions]], default_parser: CommitParser[ParseResult, ParserOptions], - mocked_git_fetch: MagicMock, mocked_git_push: MagicMock, post_mocker: Mocker, strip_logging_messages: StripLoggingMessagesFn, From e0b3b7075a4c98cd7af97e0b8470872c11e7aeb9 Mon Sep 17 00:00:00 2001 From: codejedi365 Date: Mon, 10 Nov 2025 12:06:25 -0700 Subject: [PATCH 3/8] fix(cmd-version): toggle verify upstream off when no version commit is made (#1370) * test(cmd-version): add e2e test case to check for no upstream check when no version commit --- src/semantic_release/cli/commands/version.py | 1 + .../test_version_upstream_check.py | 159 ++++++++++++++++++ 2 files changed, 160 insertions(+) diff --git a/src/semantic_release/cli/commands/version.py b/src/semantic_release/cli/commands/version.py index f02e9a505..d96e0d8ab 100644 --- a/src/semantic_release/cli/commands/version.py +++ b/src/semantic_release/cli/commands/version.py @@ -722,6 +722,7 @@ def version( # noqa: C901 ) except GitCommitEmptyIndexError: logger.info("No local changes to add to any commit, skipping") + commit_changes = False # Tag the version after potentially creating a new HEAD commit. # This way if no source code is modified, i.e. all metadata updates diff --git a/tests/e2e/cmd_version/test_version_upstream_check.py b/tests/e2e/cmd_version/test_version_upstream_check.py index 646eeded0..a2b29425a 100644 --- a/tests/e2e/cmd_version/test_version_upstream_check.py +++ b/tests/e2e/cmd_version/test_version_upstream_check.py @@ -291,6 +291,165 @@ def test_version_upstream_check_success_no_changes_untracked_branch( assert expected_vcs_url_post == post_mocker.call_count # one vcs release created +@pytest.mark.parametrize( + "repo_fixture_name, build_repo_fn", + [ + ( + repo_fixture_name, + lazy_fixture(build_repo_fn_name), + ) + for repo_fixture_name, build_repo_fn_name in [ + ( + repo_w_trunk_only_conventional_commits.__name__, + build_trunk_only_repo_w_tags.__name__, + ), + ] + ], +) +@pytest.mark.usefixtures(change_to_ex_proj_dir.__name__) +def test_version_no_upstream_check_on_no_version_commit( + repo_fixture_name: str, + run_cli: RunCliFn, + build_repo_fn: BuildSpecificRepoFn, + example_project_dir: ExProjectDir, + git_repo_for_directory: GetGitRepo4DirFn, + post_mocker: Mocker, + get_cfg_value_from_def: GetCfgValueFromDefFn, + get_versions_from_repo_build_def: GetVersionsFromRepoBuildDefFn, + pyproject_toml_file: Path, + update_pyproject_toml: UpdatePyprojectTomlFn, +): + """ + Test that PSR succeeds when no version commit is needed, so the upstream check is skipped. + + This replicates the scenario that occurred on python-semantic-release/publish-action@v10.5.1 + where the version command was run and no version commit was needed, but it failed because + it attempted to check the upstream branch anyway and we hard coded HEAD~1 because it expects + a version commit to be created. This is the only reason why you would check the upstream branch + because pushing a tag to the remote can happen even if the upstream branch has changed. + """ + remote_name = "origin" + # Create a bare remote (simulating origin) + local_origin = Repo.init(str(example_project_dir / "local_origin"), bare=True) + + # build target repo into a temporary directory + target_repo_dir = example_project_dir / repo_fixture_name + commit_type: CommitConvention = ( + repo_fixture_name.split("commits", 1)[0].split("_")[-2] # type: ignore[assignment] + ) + target_repo_definition = build_repo_fn( + repo_name=repo_fixture_name, + commit_type=commit_type, + dest_dir=target_repo_dir, + ) + target_git_repo = git_repo_for_directory(target_repo_dir) + + # Configure the source repo to use the bare remote (removing any existing 'origin') + with contextlib.suppress(AttributeError): + target_git_repo.delete_remote(target_git_repo.remotes[remote_name]) + + target_git_repo.create_remote(remote_name, str(local_origin.working_dir)) + + # Remove last release before pushing to upstream + tag_format_str = cast( + "str", get_cfg_value_from_def(target_repo_definition, "tag_format_str") + ) + latest_tag = tag_format_str.format( + version=get_versions_from_repo_build_def(target_repo_definition)[-1] + ) + target_git_repo.git.tag("-d", latest_tag) + target_git_repo.git.reset("--hard", "HEAD~1") + + # Remove any version variables to ensure no version commit is needed + update_pyproject_toml( + "tool.semantic_release.version_variables", + None, + target_repo_dir / pyproject_toml_file, + ) + update_pyproject_toml( + "tool.semantic_release.version_toml", + None, + target_repo_dir / pyproject_toml_file, + ) + # TODO: when available, switch this to use hvcs=none or similar config to avoid token use for push + update_pyproject_toml( + "tool.semantic_release.remote.ignore_token_for_push", + True, + target_repo_dir / pyproject_toml_file, + ) + target_git_repo.git.commit(amend=True, no_edit=True, all=True) + + # push the current state to establish the remote (cannot push tags and branches at the same time) + target_git_repo.git.push(remote_name, all=True) # all branches + target_git_repo.git.push(remote_name, tags=True) # all tags + + # ensure bare remote HEAD points to the active branch so clones can checkout + local_origin.git.symbolic_ref( + "HEAD", f"refs/heads/{target_git_repo.active_branch.name}" + ) + + # Simulate CI environment after someone pushes to the repo + ci_commit_sha = target_git_repo.head.commit.hexsha + ci_branch = target_git_repo.active_branch.name + + # current remote tags + remote_origin_tags_before = {tag.name for tag in local_origin.tags} + + # Simulate a CI environment by fetching the repo to a new location + test_repo = Repo.init(str(example_project_dir / "ci_repo")) + with test_repo.config_writer("repository") as config: + config.set_value("core", "hookspath", "") + config.set_value("commit", "gpgsign", False) + config.set_value("tag", "gpgsign", False) + + # Configure and retrieve the repository (see GitHub actions/checkout@v5) + test_repo.git.remote( + "add", + remote_name, + f"file:///{PureWindowsPath(local_origin.working_dir).as_posix()}", + ) + test_repo.git.fetch("--depth=1", remote_name, ci_commit_sha) + + # Simulate CI environment and recommended workflow (in docs) + # NOTE: this could be done in 1 step, but most CI pipelines are doing it in 2 steps + # 1. Checkout the commit sha (detached head) + test_repo.git.checkout(ci_commit_sha, force=True) + # 2. Forcefully set the branch to the current detached head + test_repo.git.checkout("-B", ci_branch) + + # Act: run PSR on the cloned repo - it should verify upstream and succeed + with temporary_working_directory(str(test_repo.working_dir)): + # We don't use `--no-commit` here because we want to test that the upstream check is skipped + # when PSR determines that no version commit is needed. If we used `--no-commit`, it would skip the + # upstream check because it would think that a version commit was not needed. + cli_cmd = [ + MAIN_PROG_NAME, + "--strict", + VERSION_SUBCMD, + "--no-changelog", + "--skip-build", + ] + result = run_cli(cli_cmd[1:], env={Github.DEFAULT_ENV_TOKEN_NAME: "1234"}) + + remote_origin_tags_after = {tag.name for tag in local_origin.tags} + + # Evaluate + assert_successful_exit_code(result, cli_cmd) + + # Verify release occurred as expected + with test_repo: + assert latest_tag in test_repo.tags, "Expected release tag to be created" + assert ( + ci_commit_sha == test_repo.head.commit.hexsha + ), "Expected no new commit to be created on HEAD" + different_tags = remote_origin_tags_after.difference(remote_origin_tags_before) + assert latest_tag in different_tags, "Expected new tag to be pushed to remote" + + # Verify VCS release was created + expected_vcs_url_post = 1 + assert expected_vcs_url_post == post_mocker.call_count # one vcs release created + + @pytest.mark.parametrize( "repo_fixture_name, build_repo_fn", [ From 02f2a5c74dbb6aa2989f10fc4af12cd8e6bf025f Mon Sep 17 00:00:00 2001 From: semantic-release Date: Mon, 10 Nov 2025 19:21:31 +0000 Subject: [PATCH 4/8] chore: release v10.5.2 Automatically generated by python-semantic-release --- CHANGELOG.rst | 15 +++++++++++++++ .../automatic-releases/github-actions.rst | 14 +++++++------- pyproject.toml | 2 +- src/gh_action/requirements.txt | 2 +- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index ee676dc19..98a3fcd5e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,21 @@ CHANGELOG ========= +.. _changelog-v10.5.2: + +v10.5.2 (2025-11-10) +==================== + +🪲 Bug Fixes +------------ + +* **cmd-version**: Toggle verify upstream off when no version commit is made (`PR#1370`_, + `e0b3b70`_) + +.. _e0b3b70: https://github.com/python-semantic-release/python-semantic-release/commit/e0b3b7075a4c98cd7af97e0b8470872c11e7aeb9 +.. _PR#1370: https://github.com/python-semantic-release/python-semantic-release/pull/1370 + + .. _changelog-v10.5.1: v10.5.1 (2025-11-10) diff --git a/docs/configuration/automatic-releases/github-actions.rst b/docs/configuration/automatic-releases/github-actions.rst index 578bd3dc8..d1469ffb3 100644 --- a/docs/configuration/automatic-releases/github-actions.rst +++ b/docs/configuration/automatic-releases/github-actions.rst @@ -893,14 +893,14 @@ to the GitHub Release Assets as well. - name: Action | Semantic Version Release id: release # Adjust tag with desired version if applicable. - uses: python-semantic-release/python-semantic-release@v10.5.1 + uses: python-semantic-release/python-semantic-release@v10.5.2 with: github_token: ${{ secrets.GITHUB_TOKEN }} git_committer_name: "github-actions" git_committer_email: "actions@users.noreply.github.com" - name: Publish | Upload to GitHub Release Assets - uses: python-semantic-release/publish-action@v10.5.1 + uses: python-semantic-release/publish-action@v10.5.2 if: steps.release.outputs.released == 'true' with: github_token: ${{ secrets.GITHUB_TOKEN }} @@ -1005,7 +1005,7 @@ The equivalent GitHub Action configuration would be: - name: Action | Semantic Version Release # Adjust tag with desired version if applicable. - uses: python-semantic-release/python-semantic-release@v10.5.1 + uses: python-semantic-release/python-semantic-release@v10.5.2 with: github_token: ${{ secrets.GITHUB_TOKEN }} force: patch @@ -1064,14 +1064,14 @@ Publish Action. - name: Release submodule 1 id: release-submod-1 - uses: python-semantic-release/python-semantic-release@v10.5.1 + uses: python-semantic-release/python-semantic-release@v10.5.2 with: directory: ${{ env.SUBMODULE_1_DIR }} github_token: ${{ secrets.GITHUB_TOKEN }} - name: Release submodule 2 id: release-submod-2 - uses: python-semantic-release/python-semantic-release@v10.5.1 + uses: python-semantic-release/python-semantic-release@v10.5.2 with: directory: ${{ env.SUBMODULE_2_DIR }} github_token: ${{ secrets.GITHUB_TOKEN }} @@ -1083,7 +1083,7 @@ Publish Action. # ------------------------------------------------------------------- # - name: Publish | Upload package 1 to GitHub Release Assets - uses: python-semantic-release/publish-action@v10.5.1 + uses: python-semantic-release/publish-action@v10.5.2 if: steps.release-submod-1.outputs.released == 'true' with: directory: ${{ env.SUBMODULE_1_DIR }} @@ -1091,7 +1091,7 @@ Publish Action. tag: ${{ steps.release-submod-1.outputs.tag }} - name: Publish | Upload package 2 to GitHub Release Assets - uses: python-semantic-release/publish-action@v10.5.1 + uses: python-semantic-release/publish-action@v10.5.2 if: steps.release-submod-2.outputs.released == 'true' with: directory: ${{ env.SUBMODULE_2_DIR }} diff --git a/pyproject.toml b/pyproject.toml index 4fc233d69..71c8e9a6c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta" [project] name = "python-semantic-release" -version = "10.5.1" +version = "10.5.2" description = "Automatic Semantic Versioning for Python projects" requires-python = "~= 3.8" license = { text = "MIT" } diff --git a/src/gh_action/requirements.txt b/src/gh_action/requirements.txt index f0ae366af..9e4eb9193 100644 --- a/src/gh_action/requirements.txt +++ b/src/gh_action/requirements.txt @@ -1 +1 @@ -python-semantic-release == 10.5.1 +python-semantic-release == 10.5.2 From c5d30424667ca7344efe39e7f84ecf231b462a26 Mon Sep 17 00:00:00 2001 From: codejedi365 Date: Mon, 10 Nov 2025 13:02:57 -0700 Subject: [PATCH 5/8] ci(deps): bump `python-semantic-release@v10.4.1` action to `v10.5.2` --- .github/workflows/cicd.yml | 2 +- .github/workflows/validate.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index c7d1033c5..fceeb4713 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -148,7 +148,7 @@ jobs: - name: Release | Python Semantic Release id: release - uses: python-semantic-release/python-semantic-release@4d4cb0ab842247caea1963132c242c62aab1e4d5 # v10.4.1 + uses: python-semantic-release/python-semantic-release@02f2a5c74dbb6aa2989f10fc4af12cd8e6bf025f # v10.5.2 with: github_token: ${{ secrets.GITHUB_TOKEN }} verbosity: 1 diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 6f447d461..ddb32cb1c 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -112,7 +112,7 @@ jobs: - name: Build | Build next version artifacts id: version - uses: python-semantic-release/python-semantic-release@4d4cb0ab842247caea1963132c242c62aab1e4d5 # v10.4.1 + uses: python-semantic-release/python-semantic-release@02f2a5c74dbb6aa2989f10fc4af12cd8e6bf025f # v10.5.2 with: github_token: "" verbosity: 1 From c355bc2757a0eb61638d95fec5cb090fc0aa5e08 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Nov 2025 19:58:49 +0000 Subject: [PATCH 6/8] ci(deps): bump `python-semantic-release/publish-action@v10.4.1` to `v10.5.2` --- .github/workflows/cicd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index fceeb4713..591e9636a 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -155,7 +155,7 @@ jobs: build: false - name: Release | Add distribution artifacts to GitHub Release Assets - uses: python-semantic-release/publish-action@ae6462adc12bd3d1738070d784b65b5189b955a9 # v10.4.1 + uses: python-semantic-release/publish-action@948bb8fccc5e8072f2c52464b45c76a8bb3878e6 # v10.5.2 if: steps.release.outputs.released == 'true' with: github_token: ${{ secrets.GITHUB_TOKEN }} From 9bb4ac9fd929c53e14d4d982ab628fbfc9bd6613 Mon Sep 17 00:00:00 2001 From: codejedi365 Date: Mon, 10 Nov 2025 13:20:01 -0700 Subject: [PATCH 7/8] ci(release): remove verify upstream job step as PSR handles it internally (#1372) --- .github/workflows/cicd.yml | 6 ----- .github/workflows/verify_upstream.sh | 33 ---------------------------- 2 files changed, 39 deletions(-) delete mode 100644 .github/workflows/verify_upstream.sh diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 591e9636a..863413a05 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -140,12 +140,6 @@ jobs: python -m scripts.bump_version_in_docs git add docs/* - - name: Evaluate | Verify upstream has NOT changed - # Last chance to abort before causing an error as another PR/push was applied to the upstream branch - # while this workflow was running. This is important because we are committing a version change - shell: bash - run: bash .github/workflows/verify_upstream.sh - - name: Release | Python Semantic Release id: release uses: python-semantic-release/python-semantic-release@02f2a5c74dbb6aa2989f10fc4af12cd8e6bf025f # v10.5.2 diff --git a/.github/workflows/verify_upstream.sh b/.github/workflows/verify_upstream.sh deleted file mode 100644 index 8444eba57..000000000 --- a/.github/workflows/verify_upstream.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash - -set -eu +o pipefail - -# Example output of `git status -sb`: -# ## master...origin/master [behind 1] -# M .github/workflows/verify_upstream.sh -UPSTREAM_BRANCH_NAME="$(git status -sb | head -n 1 | awk -F '\\.\\.\\.' '{print $2}' | cut -d ' ' -f1)" -printf '%s\n' "Upstream branch name: $UPSTREAM_BRANCH_NAME" - -set -o pipefail - -if [ -z "$UPSTREAM_BRANCH_NAME" ]; then - printf >&2 '%s\n' "::error::Unable to determine upstream branch name!" - exit 1 -fi - -git fetch "${UPSTREAM_BRANCH_NAME%%/*}" - -if ! UPSTREAM_SHA="$(git rev-parse "$UPSTREAM_BRANCH_NAME")"; then - printf >&2 '%s\n' "::error::Unable to determine upstream branch sha!" - exit 1 -fi - -HEAD_SHA="$(git rev-parse HEAD)" - -if [ "$HEAD_SHA" != "$UPSTREAM_SHA" ]; then - printf >&2 '%s\n' "[HEAD SHA] $HEAD_SHA != $UPSTREAM_SHA [UPSTREAM SHA]" - printf >&2 '%s\n' "::error::Upstream has changed, aborting release..." - exit 1 -fi - -printf '%s\n' "Verified upstream branch has not changed, continuing with release..." From 2dd8be7b1ae5f0504b5c4ac44e74608802e20066 Mon Sep 17 00:00:00 2001 From: codejedi365 Date: Mon, 10 Nov 2025 13:34:16 -0700 Subject: [PATCH 8/8] chore(release): switch to major and minor partial tags via PSR (#1368) * chore(release): set `add_partial_tags` to true for PSR releases * ci(release): remove job steps to create partial tags --- .github/workflows/cicd.yml | 22 ---------------------- pyproject.toml | 1 + 2 files changed, 1 insertion(+), 22 deletions(-) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 863413a05..28ff7f332 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -155,28 +155,6 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} tag: ${{ steps.release.outputs.tag }} - - name: Release | Update Minor Release Tag Reference - if: steps.release.outputs.released == 'true' && steps.release.outputs.is_prerelease == 'false' - env: - FULL_VERSION_TAG: ${{ steps.release.outputs.tag }} - GIT_COMMITTER_NAME: ${{ env.GITHUB_ACTIONS_AUTHOR_NAME }} - GIT_COMMITTER_EMAIL: ${{ env.GITHUB_ACTIONS_AUTHOR_EMAIL }} - run: | - MINOR_VERSION_TAG="$(echo "$FULL_VERSION_TAG" | cut -d. -f1,2)" - git tag --force --annotate "$MINOR_VERSION_TAG" "${FULL_VERSION_TAG}^{}" -m "$MINOR_VERSION_TAG" - git push -u origin "$MINOR_VERSION_TAG" --force - - - name: Release | Update Major Release Tag Reference - if: steps.release.outputs.released == 'true' && steps.release.outputs.is_prerelease == 'false' - env: - FULL_VERSION_TAG: ${{ steps.release.outputs.tag }} - GIT_COMMITTER_NAME: ${{ env.GITHUB_ACTIONS_AUTHOR_NAME }} - GIT_COMMITTER_EMAIL: ${{ env.GITHUB_ACTIONS_AUTHOR_EMAIL }} - run: | - MAJOR_VERSION_TAG="$(echo "$FULL_VERSION_TAG" | cut -d. -f1)" - git tag --force --annotate "$MAJOR_VERSION_TAG" "${FULL_VERSION_TAG}^{}" -m "$MAJOR_VERSION_TAG" - git push -u origin "$MAJOR_VERSION_TAG" --force - outputs: released: ${{ steps.release.outputs.released || 'false' }} new-release-version: ${{ steps.release.outputs.version }} diff --git a/pyproject.toml b/pyproject.toml index 71c8e9a6c..0af0ef360 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -409,6 +409,7 @@ sections = { "tests" = ["tests"] } ignore_names = ["change_to_ex_proj_dir", "init_example_project"] [tool.semantic_release] +add_partial_tags = true logging_use_named_masks = true commit_parser = "conventional" commit_parser_options = { parse_squash_commits = true, ignore_merge_commits = true }