diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1d7930dfc..c6889acb4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Setup | Checkout Repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 @@ -38,19 +38,19 @@ jobs: steps: - name: Setup | Checkout Repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 - name: Evaluate | Check common file types for changes id: core-changed-files - uses: tj-actions/changed-files@e0021407031f5be11a464abee9a0776171c79891 #v47.0.1 + uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 #v47.0.6 with: files_yaml_from_source_file: .github/changed-files-spec.yml - name: Evaluate | Check specific file types for changes id: ci-changed-files - uses: tj-actions/changed-files@e0021407031f5be11a464abee9a0776171c79891 #v47.0.1 + uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 #v47.0.6 with: files_yaml: | ci: diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 49d5f7cf4..ee476daf7 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -20,20 +20,20 @@ jobs: steps: - name: Setup | Checkout Repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 - name: Evaluate | Check common file types for changes id: core-changed-files - uses: tj-actions/changed-files@e0021407031f5be11a464abee9a0776171c79891 #v47.0.1 + uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 #v47.0.6 with: base_sha: ${{ github.event.push.before }} files_yaml_from_source_file: .github/changed-files-spec.yml - name: Evaluate | Check specific file types for changes id: ci-changed-files - uses: tj-actions/changed-files@e0021407031f5be11a464abee9a0776171c79891 #v47.0.1 + uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 #v47.0.6 with: base_sha: ${{ github.event.push.before }} files_yaml: | @@ -115,7 +115,7 @@ jobs: # possible that the branch was updated while the workflow was running. This # prevents accidentally releasing un-evaluated changes. - name: Setup | Checkout Repository on Release Branch - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.ref_name }} fetch-depth: 0 @@ -125,7 +125,7 @@ jobs: git reset --hard ${{ github.sha }} - name: Setup | Download Build Artifacts - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 id: artifact-download with: name: ${{ needs.validate.outputs.distribution-artifacts }} @@ -179,7 +179,7 @@ jobs: steps: - name: Setup | Download Build Artifacts - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 id: artifact-download with: name: ${{ needs.validate.outputs.distribution-artifacts }} @@ -188,7 +188,7 @@ jobs: # see https://docs.pypi.org/trusted-publishers/ - name: Publish package distributions to PyPI id: pypi-publish - uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0 + uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0 with: packages-dir: dist print-hash: true diff --git a/.github/workflows/manual.yml b/.github/workflows/manual.yml index 67d256fea..06df9f85f 100644 --- a/.github/workflows/manual.yml +++ b/.github/workflows/manual.yml @@ -65,7 +65,7 @@ jobs: steps: - name: Setup | Install Python ${{ env.COMMON_PYTHON_VERSION }} - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version: ${{ env.COMMON_PYTHON_VERSION }} diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index ba5c00d1c..6b9c9ec62 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -28,7 +28,7 @@ jobs: steps: - name: Stale Issues/PRs - uses: actions/stale@997185467fa4f803885201cee163a9f38240193d # v10.1.1 + uses: actions/stale@eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899 # v10.3.0 with: # default: 30, GitHub Actions API Rate limit is 1000/hr operations-per-run: ${{ env.OPERATIONS_RATE_LIMIT }} @@ -67,7 +67,7 @@ jobs: # that point the submitter has 14 days before a reminder/warning is given. If # no response has been received within 3 weeks, the issue is closed. There are # no exemptions besides removing the awaiting-reply label. - uses: actions/stale@997185467fa4f803885201cee163a9f38240193d # v10.1.1 + uses: actions/stale@eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899 # v10.3.0 with: # GitHub Actions API Rate limit is 1000/hr operations-per-run: ${{ env.OPERATIONS_RATE_LIMIT }} @@ -97,7 +97,7 @@ jobs: # forgotten completely, this job will post a reminder message to the maintainers # No closures will occur and there are no exemptions besides removing the confirmed # label. - uses: actions/stale@997185467fa4f803885201cee163a9f38240193d # v10.1.1 + uses: actions/stale@eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899 # v10.3.0 with: # GitHub Actions API Rate limit is 1000/hr operations-per-run: ${{ env.OPERATIONS_RATE_LIMIT }} diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 4ee55db53..2623eccdf 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -90,7 +90,7 @@ jobs: steps: - name: Setup | Checkout Repository at workflow sha - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.sha }} fetch-depth: 0 @@ -100,7 +100,7 @@ jobs: git checkout -B ${{ github.ref_name }} - name: Setup | Install Python ${{ env.COMMON_PYTHON_VERSION }} - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version: ${{ env.COMMON_PYTHON_VERSION }} cache: 'pip' @@ -139,7 +139,7 @@ jobs: printf '%s\n' "artifacts_name=dist" >> $GITHUB_OUTPUT - name: Upload | Distribution Artifacts - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ${{ steps.build.outputs.artifacts_name }} path: ${{ steps.build.outputs.dist_dir }} @@ -161,13 +161,13 @@ jobs: steps: - name: Setup | Checkout Repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.sha }} fetch-depth: 1 - name: Setup | Install Python ${{ env.LOWEST_PYTHON_VERSION }} - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version: ${{ env.LOWEST_PYTHON_VERSION }} cache: 'pip' @@ -195,7 +195,7 @@ jobs: --junit-xml=tests/reports/pytest-results.xml - name: Report | Upload Test Results - uses: mikepenz/action-junit-report@e08919a3b1fb83a78393dfb775a9c37f17d8eea6 # v6.0.1 + uses: mikepenz/action-junit-report@d9f48fc87bc235f7e214acf696ca5abc0a986f16 # v6.4.2 if: ${{ always() && steps.tests.outcome != 'skipped' }} with: report_paths: ./tests/reports/*.xml @@ -217,19 +217,19 @@ jobs: steps: - name: Setup | Checkout Repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.sha }} fetch-depth: 1 - name: Setup | Install Python ${{ matrix.python-version }} - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version: ${{ matrix.python-version }} cache: 'pip' - name: Setup | Download Distribution Artifacts - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: ${{ needs.build.outputs.distribution-artifacts }} path: ./dist @@ -265,7 +265,7 @@ jobs: --junit-xml=tests/reports/pytest-results.xml - name: Report | Upload Cached Repos on Failure - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 if: ${{ failure() && steps.tests.outcome == 'failure' }} with: name: ${{ format('cached-repos-{0}-{1}', matrix.os, matrix.python-version) }} @@ -275,7 +275,7 @@ jobs: retention-days: 1 - name: Report | Upload Tested Repos on Failure - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 if: ${{ failure() && steps.tests.outcome == 'failure' }} with: name: ${{ format('tested-repos-{0}-{1}', matrix.os, matrix.python-version) }} @@ -285,7 +285,7 @@ jobs: retention-days: 1 - name: Report | Upload Test Results - uses: mikepenz/action-junit-report@e08919a3b1fb83a78393dfb775a9c37f17d8eea6 # v6.0.1 + uses: mikepenz/action-junit-report@d9f48fc87bc235f7e214acf696ca5abc0a986f16 # v6.4.2 if: ${{ always() && steps.tests.outcome != 'skipped' }} with: report_paths: ./tests/reports/*.xml @@ -306,19 +306,19 @@ jobs: steps: - name: Setup | Checkout Repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.sha }} fetch-depth: 1 - name: Setup | Install Python ${{ matrix.python-version }} - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version: ${{ matrix.python-version }} cache: 'pip' - name: Setup | Download Distribution Artifacts - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: ${{ needs.build.outputs.distribution-artifacts }} path: dist @@ -363,7 +363,7 @@ jobs: `--junit-xml=tests/reports/pytest-results.xml - name: Report | Upload Cached Repos on Failure - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 if: ${{ failure() && steps.tests.outcome == 'failure' }} with: name: ${{ format('cached-repos-{0}-{1}', matrix.os, matrix.python-version) }} @@ -373,7 +373,7 @@ jobs: retention-days: 1 - name: Report | Upload Tested Repos on Failure - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 if: ${{ failure() && steps.tests.outcome == 'failure' }} with: name: ${{ format('tested-repos-{0}-{1}', matrix.os, matrix.python-version) }} @@ -383,7 +383,7 @@ jobs: retention-days: 1 - name: Report | Upload Test Results - uses: mikepenz/action-junit-report@e08919a3b1fb83a78393dfb775a9c37f17d8eea6 # v6.0.1 + uses: mikepenz/action-junit-report@d9f48fc87bc235f7e214acf696ca5abc0a986f16 # v6.4.2 if: ${{ always() && steps.tests.outcome != 'skipped' }} with: report_paths: ./tests/reports/*.xml @@ -404,13 +404,13 @@ jobs: steps: - name: Setup | Checkout Repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 1 ref: ${{ github.sha }} - name: Setup | Download Distribution Artifacts - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: ${{ needs.build.outputs.distribution-artifacts }} path: ${{ env.ACTION_SRC_DIR }} @@ -427,7 +427,7 @@ jobs: - name: Build | Action Container id: container-builder - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 + uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0 with: context: ${{ env.ACTION_SRC_DIR }} load: true # add to `docker images` @@ -446,13 +446,13 @@ jobs: steps: - name: Setup | Checkout Repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.sha }} fetch-depth: 1 - name: Setup | Install Python ${{ env.COMMON_PYTHON_VERSION }} - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version: ${{ env.COMMON_PYTHON_VERSION }} cache: 'pip' diff --git a/CHANGELOG.rst b/CHANGELOG.rst index ff44a7ec7..5decef8f5 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,67 @@ CHANGELOG ========= +.. _changelog-v10.6.0: + +v10.6.0 (2026-07-04) +==================== + +✨ Features +----------- + +* **cmd-version**: Add file replacement variant for ``version_variables``, closes `#1375`_ + (`PR#1391`_, `95ce7ec`_) + +* **parser-emoji**: Adds more non-release triggering emojis to the default emoji parser (`PR#1410`_, + `2833aa9`_) + +🪲 Bug Fixes +------------ + +* **cmd-config-generate**: Fix config output for Microsoft Windows UTF-8 encoding, closes `#702`_ + (`PR#1400`_, `0343194`_) + +* **cmd-publish**: Fix handling of asset uploading errors on publish, closes `#1395`_ (`PR#1397`_, + `81a0f98`_) + +* **github**: Fix bubble up errors of asset uploads for GitHub (`PR#1397`_, `81a0f98`_) + +* **hvcs**: Mask git credential URL in very verbose debug logs, closes `#1426`_ (`PR#1445`_, + `811afb0`_) + +📖 Documentation +---------------- + +* **cmd-config-generate**: Add Windows PowerShell specific ``generate-config`` usage example + (`PR#1400`_, `0343194`_) + +* **configuration**: Modify ``version_variables`` definition to include new file replacement + (`PR#1391`_, `95ce7ec`_) + +* **examples**: Update references to github actions for hash references (`PR#1449`_, `873da58`_) + +* **package**: Change package changelog link to doc website (`PR#1434`_, `05f897f`_) + +.. _#1375: https://github.com/python-semantic-release/python-semantic-release/issues/1375 +.. _#1395: https://github.com/python-semantic-release/python-semantic-release/issues/1395 +.. _#1426: https://github.com/python-semantic-release/python-semantic-release/issues/1426 +.. _#702: https://github.com/python-semantic-release/python-semantic-release/issues/702 +.. _0343194: https://github.com/python-semantic-release/python-semantic-release/commit/03431947833b4e3f3fc79b09fc626e0f30508a2b +.. _05f897f: https://github.com/python-semantic-release/python-semantic-release/commit/05f897f4d5c6d91495c1bf55cc704815be887d69 +.. _2833aa9: https://github.com/python-semantic-release/python-semantic-release/commit/2833aa943a6a016b8208146a89f7b4ec0efa6cd0 +.. _811afb0: https://github.com/python-semantic-release/python-semantic-release/commit/811afb00de382ff425b766b97c83d2246f9cfb16 +.. _81a0f98: https://github.com/python-semantic-release/python-semantic-release/commit/81a0f98b0f36b65df5039ab335760295322bfd9c +.. _873da58: https://github.com/python-semantic-release/python-semantic-release/commit/873da5894a2b03283e93019801e3012c045f361a +.. _95ce7ec: https://github.com/python-semantic-release/python-semantic-release/commit/95ce7ecdbab0fc0986d1fcf442cd8cf99a4b6e4f +.. _PR#1391: https://github.com/python-semantic-release/python-semantic-release/pull/1391 +.. _PR#1397: https://github.com/python-semantic-release/python-semantic-release/pull/1397 +.. _PR#1400: https://github.com/python-semantic-release/python-semantic-release/pull/1400 +.. _PR#1410: https://github.com/python-semantic-release/python-semantic-release/pull/1410 +.. _PR#1434: https://github.com/python-semantic-release/python-semantic-release/pull/1434 +.. _PR#1445: https://github.com/python-semantic-release/python-semantic-release/pull/1445 +.. _PR#1449: https://github.com/python-semantic-release/python-semantic-release/pull/1449 + + .. _changelog-v10.5.3: v10.5.3 (2025-12-14) diff --git a/docs/configuration/automatic-releases/github-actions.rst b/docs/configuration/automatic-releases/github-actions.rst index 683cf1bfc..7a7f7ad7f 100644 --- a/docs/configuration/automatic-releases/github-actions.rst +++ b/docs/configuration/automatic-releases/github-actions.rst @@ -882,7 +882,7 @@ to the GitHub Release Assets as well. # while the workflow was running, which prevents accidentally releasing un-evaluated # changes. - name: Setup | Checkout Repository on Release Branch - uses: actions/checkout@v4 + uses: actions/checkout@COMMIT_HASH # v6 with: ref: ${{ github.ref_name }} @@ -893,21 +893,21 @@ 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.3 + uses: python-semantic-release/python-semantic-release@COMMIT_HASH # v10.6.0 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.3 + uses: python-semantic-release/publish-action@COMMIT_HASH # v10.6.0 if: steps.release.outputs.released == 'true' with: github_token: ${{ secrets.GITHUB_TOKEN }} tag: ${{ steps.release.outputs.tag }} - name: Upload | Distribution Artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@COMMIT_HASH # v4.X.X with: name: distribution-artifacts path: dist @@ -931,7 +931,7 @@ to the GitHub Release Assets as well. steps: - name: Setup | Download Build Artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@COMMIT_HASH # v4.X.X id: artifact-download with: name: distribution-artifacts @@ -947,7 +947,7 @@ to the GitHub Release Assets as well. # see https://docs.pypi.org/trusted-publishers/ - name: Publish package distributions to PyPI - uses: pypa/gh-action-pypi-publish@@SHA1_HASH # vX.X.X + uses: pypa/gh-action-pypi-publish@COMMIT_HASH # vX.X.X with: packages-dir: dist print-hash: true @@ -971,7 +971,7 @@ to the GitHub Release Assets as well. .. note:: As of v10.5.0, Python Semantic Release automatically detects and converts shallow clones to full clones when needed. While you can still use ``fetch-depth: 0`` - with ``actions/checkout@v4`` to fetch the full history upfront, it is no longer + with ``actions/checkout`` to fetch the full history upfront, it is no longer required. If you use the default shallow clone, Python Semantic Release will automatically fetch the full history before evaluating commits. If you are using an older version of PSR, you will need to unshallow the repository prior to use. @@ -1107,13 +1107,13 @@ Publish Action. # ------------------------------------------------------------------- # - name: Publish | Upload package 1 to PyPI - uses: pypa/gh-action-pypi-publish@SHA1_HASH # vX.X.X + uses: pypa/gh-action-pypi-publish@COMMIT_HASH # vX.X.X if: steps.release-submod-1.outputs.released == 'true' with: packages-dir: ${{ format('{}/dist', env.SUBMODULE_1_DIR) }} - name: Publish | Upload package 2 to PyPI - uses: pypa/gh-action-pypi-publish@SHA1_HASH # vX.X.X + uses: pypa/gh-action-pypi-publish@COMMIT_HASH # vX.X.X if: steps.release-submod-2.outputs.released == 'true' with: packages-dir: ${{ format('{}/dist', env.SUBMODULE_2_DIR) }} diff --git a/docs/configuration/configuration-guides/uv_integration.rst b/docs/configuration/configuration-guides/uv_integration.rst index ac9f2359e..5bbb8ed52 100644 --- a/docs/configuration/configuration-guides/uv_integration.rst +++ b/docs/configuration/configuration-guides/uv_integration.rst @@ -158,7 +158,7 @@ look like this: lock_file_artifact: uv.lock steps: - name: Setup | Checkout Repository at workflow sha - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@COMMIT_HASH # vX.X.X with: ref: ${{ github.sha }} @@ -166,7 +166,7 @@ look like this: run: git checkout -B ${{ github.ref_name }} - name: Setup | Install uv - uses: asdf-vm/actions/install@1902764435ca0dd2f3388eea723a4f92a4eb8302 # v4.0.2 + uses: asdf-vm/actions/install@COMMIT_HASH # v4.X.X - name: Setup | Install Python & Project dependencies run: uv sync --extra build @@ -179,7 +179,7 @@ look like this: - name: Upload | Distribution Artifacts if: ${{ steps.version.outputs.released == 'true' }} - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@COMMIT_HASH # v4.X.X with: name: ${{ env.dist_artifacts_name }} path: ${{ format('{0}/**', env.dist_artifacts_dir) }} @@ -188,7 +188,7 @@ look like this: - name: Upload | Lock File Artifact if: ${{ steps.version.outputs.released == 'true' }} - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@COMMIT_HASH # v4.X.X with: name: ${{ env.lock_file_artifact }} path: ${{ env.lock_file_artifact }} @@ -209,13 +209,13 @@ look like this: runs-on: ubuntu-latest steps: - name: Setup | Checkout Repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@COMMIT_HASH # vX.X.X with: ref: ${{ github.sha }} fetch-depth: 1 - name: Setup | Download Distribution Artifacts - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + uses: actions/download-artifact@COMMIT_HASH # v4.X.X if: ${{ needs.build.outputs.new-release-detected == 'true' }} id: artifact-download with: @@ -223,7 +223,7 @@ look like this: path: ./dist - name: Setup | Install uv - uses: asdf-vm/actions/install@1902764435ca0dd2f3388eea723a4f92a4eb8302 # v4.0.2 + uses: asdf-vm/actions/install@COMMIT_HASH # v4.X.X - name: Setup | Install Python & Project dependencies run: uv sync --extra test @@ -255,7 +255,7 @@ look like this: steps: - name: Setup | Checkout Repository on Release Branch - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@COMMIT_HASH # vX.X.X with: ref: ${{ github.ref_name }} @@ -263,20 +263,20 @@ look like this: run: git reset --hard ${{ github.sha }} - name: Setup | Install uv - uses: asdf-vm/actions/install@1902764435ca0dd2f3388eea723a4f92a4eb8302 # v4.0.2 + uses: asdf-vm/actions/install@COMMIT_HASH # v4.X.X - name: Setup | Install Python & Project dependencies run: uv sync --extra build - name: Setup | Download Build Artifacts - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + uses: actions/download-artifact@COMMIT_HASH # v4.X.X id: artifact-download with: name: ${{ needs.build.outputs.distribution-artifacts }} path: dist - name: Setup | Download Lock File Artifact - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + uses: actions/download-artifact@COMMIT_HASH # v4.X.X with: name: ${{ needs.build.outputs.lock-file-artifact }} @@ -315,14 +315,14 @@ look like this: steps: - name: Setup | Download Build Artifacts - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + uses: actions/download-artifact@COMMIT_HASH # v4.X.X id: artifact-download with: name: ${{ needs.build.outputs.distribution-artifacts }} path: dist - name: Publish package distributions to PyPI - uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # v1.12.4 + uses: pypa/gh-action-pypi-publish@COMMIT_HASH # v1.X.X with: packages-dir: dist print-hash: true diff --git a/docs/configuration/configuration.rst b/docs/configuration/configuration.rst index 74e7638ba..d81369fbc 100644 --- a/docs/configuration/configuration.rst +++ b/docs/configuration/configuration.rst @@ -1326,7 +1326,7 @@ colon-separated definition with either 2 or 3 parts. The 2-part definition inclu the file path and the variable name. Newly with v9.20.0, it also accepts an optional 3rd part to allow configuration of the format type. -As of ${NEW_RELEASE_TAG}, the ``version_variables`` option also supports entire file +As of v10.6.0, the ``version_variables`` option also supports entire file replacement by using an asterisk (``*``) as the pattern/variable name. This is useful for files that contain only a version number, such as ``VERSION`` files. diff --git a/docs/upgrading/08-upgrade.rst b/docs/upgrading/08-upgrade.rst index a6ce7a652..a618f58b0 100644 --- a/docs/upgrading/08-upgrade.rst +++ b/docs/upgrading/08-upgrade.rst @@ -50,13 +50,13 @@ This workflow is written to use Python Semantic Release v7.33.5: concurrency: release steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@COMMIT_HASH # v3.0.0 with: fetch-depth: 0 # This action uses Python Semantic Release v7 - name: Python Semantic Release - uses: python-semantic-release/python-semantic-release@v7.33.5 + uses: python-semantic-release/python-semantic-release@323ebf700ac0878aedfa899bcb0492f6d579986c # v7.33.5 with: github_token: ${{ secrets.GITHUB_TOKEN }} repository_username: __token__ @@ -84,25 +84,25 @@ GitHub Action: id-token: write steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@COMMIT_HASH # v3.0.0 with: fetch-depth: 0 # This action uses Python Semantic Release v8 - name: Python Semantic Release id: release - uses: python-semantic-release/python-semantic-release@v8.7.0 + uses: python-semantic-release/python-semantic-release@COMMIT_HASH # v8.0.0 with: github_token: ${{ secrets.GITHUB_TOKEN }} - name: Publish package distributions to PyPI - uses: pypa/gh-action-pypi-publish@v1 + uses: pypa/gh-action-pypi-publish@COMMIT_HASH # v1.0.0 # NOTE: DO NOT wrap the conditional in ${{ }} as it will always evaluate to true. # See https://github.com/actions/runner/issues/1173 if: steps.release.outputs.released == 'true' - name: Publish package distributions to GitHub Releases - uses: python-semantic-release/upload-to-gh-release@v8.7.0 + uses: python-semantic-release/upload-to-gh-release@COMMIT_HASH # v8.0.0 if: steps.release.outputs.released == 'true' with: github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/pyproject.toml b/pyproject.toml index 19b636cb7..8b3034531 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta" [project] name = "python-semantic-release" -version = "10.5.3" +version = "10.6.0" description = "Automatic Semantic Versioning for Python projects" requires-python = "~= 3.8" license = { text = "MIT" } @@ -48,7 +48,7 @@ semantic-release = "semantic_release.__main__:main" psr = "semantic_release.__main__:main" [project.urls] -changelog = "https://github.com/python-semantic-release/python-semantic-release/blob/master/CHANGELOG.md" +changelog = "https://python-semantic-release.readthedocs.io/en/stable/misc/psr_changelog.html" documentation = "https://python-semantic-release.readthedocs.io" homepage = "https://python-semantic-release.readthedocs.io" issues = "https://github.com/python-semantic-release/python-semantic-release/issues" @@ -425,8 +425,8 @@ build_command = """ major_on_zero = true version_variables = [ "src/gh_action/requirements.txt:python-semantic-release:nf", - "docs/configuration/automatic-releases/github-actions.rst:python-semantic-release/python-semantic-release:tf", - "docs/configuration/automatic-releases/github-actions.rst:python-semantic-release/publish-action:tf", + "docs/configuration/automatic-releases/github-actions.rst:python-semantic-release/python-semantic-release@COMMIT_HASH #:tf", + "docs/configuration/automatic-releases/github-actions.rst:python-semantic-release/publish-action@COMMIT_HASH #:tf", ] version_toml = ["pyproject.toml:project.version"] diff --git a/src/gh_action/requirements.txt b/src/gh_action/requirements.txt index c25d6fc5a..88acf11bb 100644 --- a/src/gh_action/requirements.txt +++ b/src/gh_action/requirements.txt @@ -1 +1 @@ -python-semantic-release == 10.5.3 +python-semantic-release == 10.6.0 diff --git a/src/semantic_release/helpers.py b/src/semantic_release/helpers.py index c50369575..8ec505a16 100644 --- a/src/semantic_release/helpers.py +++ b/src/semantic_release/helpers.py @@ -9,7 +9,7 @@ from pathlib import Path, PurePosixPath from re import IGNORECASE, compile as regexp from typing import TYPE_CHECKING, Any, Callable, NamedTuple, Sequence, TypeVar -from urllib.parse import urlsplit +from urllib.parse import urlsplit, urlunsplit from semantic_release.globals import logger @@ -215,6 +215,16 @@ class ParsedGitUrl(NamedTuple): repo_name: str +def _hide_credentials_in_url(url: str) -> str: + url_parts = urlsplit(url) + + if not url_parts.scheme or "@" not in url_parts.netloc: + return url + + _, _, host = url_parts.netloc.rpartition("@") + return urlunsplit(url_parts._replace(netloc=f"@{host}")) + + @lru_cache(maxsize=512) def parse_git_url(url: str) -> ParsedGitUrl: """ @@ -242,7 +252,7 @@ def parse_git_url(url: str) -> ParsedGitUrl: Raises ValueError if the url can't be parsed. """ - logger.debug("Parsing git url %r", url) + logger.debug("Parsing git url %r", _hide_credentials_in_url(url)) # Normalizers are a list of tuples of (pattern, replacement) normalizers = [ diff --git a/tests/unit/semantic_release/test_helpers.py b/tests/unit/semantic_release/test_helpers.py index 4877d3892..56d645f09 100644 --- a/tests/unit/semantic_release/test_helpers.py +++ b/tests/unit/semantic_release/test_helpers.py @@ -2,6 +2,7 @@ import pytest +from semantic_release.globals import logger from semantic_release.helpers import ParsedGitUrl, parse_git_url, sort_numerically @@ -120,6 +121,30 @@ def test_parse_valid_git_urls(url: str, expected: ParsedGitUrl): assert expected == parse_git_url(url) +def test_parse_git_url_does_not_log_credentials(caplog: pytest.LogCaptureFixture): + """Test that credentials in git urls are masked before logging.""" + username = "x-oauth-basic" + secret = "ghp_secret_token" + url = f"https://{username}:{secret}@github.example.com/owner/project.git" + + parse_git_url.cache_clear() + caplog.set_level("DEBUG", logger=logger.name) + + expected_parsed_url = ParsedGitUrl( + "https", + f"{username}:{secret}@github.example.com", + "owner", + "project", + ) + + actual_parsed_url = parse_git_url(url) + + assert expected_parsed_url == actual_parsed_url + assert username not in caplog.text + assert secret not in caplog.text + assert "@github.example.com" in caplog.text + + @pytest.mark.parametrize( "url", [