diff --git a/.github/actions/reusable-python-download_dist_release/action.yml b/.github/actions/reusable-python-download_dist_release/action.yml new file mode 100644 index 00000000..06de4005 --- /dev/null +++ b/.github/actions/reusable-python-download_dist_release/action.yml @@ -0,0 +1,27 @@ +name: Download Python distribution files (GitHub release) +description: > + Download built distribution files from a GitHub release into a local + "dist-download" directory, ready to be published. +inputs: + release-tag: + description: Tag of the GitHub release to download assets from + required: true + type: string + github-token: + description: Token used to download release assets via "gh release download" + required: true + type: string + +runs: + using: composite + steps: + - name: Download release assets + shell: bash + env: + GITHUB_TOKEN: ${{ inputs.github-token }} + GH_REPO: ${{ github.repository }} + INPUTS_RELEASE_TAG: ${{ inputs.release-tag }} + run: | + mkdir -p dist-download + cd dist-download + gh release download "${INPUTS_RELEASE_TAG}" -p '*.tar.gz' -p '*.whl' diff --git a/.github/actions/reusable-python-publish_to_artifactory/action.yml b/.github/actions/reusable-python-publish_to_artifactory/action.yml index 8cab4a62..cd6dd914 100644 --- a/.github/actions/reusable-python-publish_to_artifactory/action.yml +++ b/.github/actions/reusable-python-publish_to_artifactory/action.yml @@ -22,7 +22,9 @@ runs: using: composite steps: - name: Setup JFrog CLI - uses: jfrog/setup-jfrog-cli@v4.4.1 + uses: jfrog/setup-jfrog-cli@68c0efdc951dd2359bbbfa15c48bc67b3ae8e4d6 # v5.2.0 + with: + disable-auto-build-publish: true env: JF_URL: https://${{ inputs.JFROG_ARTIFACTORY_URL }} JF_ACCESS_TOKEN: ${{ inputs.JFROG_ARTIFACTORY_TOKEN }} diff --git a/.github/workflows/reusable-python-build_poetry_package.yml b/.github/workflows/reusable-python-build_poetry_package.yml index 85b439d0..f07807ed 100644 --- a/.github/workflows/reusable-python-build_poetry_package.yml +++ b/.github/workflows/reusable-python-build_poetry_package.yml @@ -87,8 +87,10 @@ jobs: exit 1 fi echo "version=${VERSION}" >> $GITHUB_OUTPUT - - uses: jfrog/setup-jfrog-cli@279b1f629f43dd5bc658d8361ac4802a7ef8d2d5 # v4.9.1 + - uses: jfrog/setup-jfrog-cli@68c0efdc951dd2359bbbfa15c48bc67b3ae8e4d6 # v5.2.0 name: Setup JFrog CLI + with: + disable-auto-build-publish: true env: JF_URL: https://${{ secrets.JFROG_ARTIFACTORY_URL }} JF_ACCESS_TOKEN: ${{ secrets.JFROG_ARTIFACTORY_TOKEN }} diff --git a/.github/workflows/reusable-python-build_setuptools_package.yml b/.github/workflows/reusable-python-build_setuptools_package.yml index b140c299..313b6589 100644 --- a/.github/workflows/reusable-python-build_setuptools_package.yml +++ b/.github/workflows/reusable-python-build_setuptools_package.yml @@ -82,8 +82,10 @@ jobs: exit 1 fi echo "version=${VERSION}" >> $GITHUB_OUTPUT - - uses: jfrog/setup-jfrog-cli@279b1f629f43dd5bc658d8361ac4802a7ef8d2d5 # v4.9.1 + - uses: jfrog/setup-jfrog-cli@68c0efdc951dd2359bbbfa15c48bc67b3ae8e4d6 # v5.2.0 name: Setup JFrog CLI + with: + disable-auto-build-publish: true env: JF_URL: https://${{ secrets.JFROG_ARTIFACTORY_URL }} JF_ACCESS_TOKEN: ${{ secrets.JFROG_ARTIFACTORY_TOKEN }} diff --git a/.github/workflows/reusable-python-publish_pypi_package.yml b/.github/workflows/reusable-python-publish_pypi_package.yml index c9e1e786..dafb5ff4 100644 --- a/.github/workflows/reusable-python-publish_pypi_package.yml +++ b/.github/workflows/reusable-python-publish_pypi_package.yml @@ -22,7 +22,9 @@ on: type: boolean default: true virtual-repo-names: - description: 'List of virtual repository names to publish to (e.g. ["public-pypi-dev", "geophysics-pypi-dev"])' + description: > + List of virtual repository names to publish to (e.g. ["public-pypi-dev", "geophysics-pypi-dev"]). + "pypi" and "test-pypi" are not supported: publish to PyPI from the calling workflow. required: true type: string os: @@ -54,6 +56,10 @@ on: PYPI_TOKEN: description: PyPI Token required: false + outputs: + is-publishable: + description: Whether the version is publishable (same check that gates the publish job) + value: ${{ jobs.is_publishable.outputs.is-publishable }} permissions: contents: read @@ -139,14 +145,13 @@ jobs: artifactory-dir-path: ${{ matrix.virtual-repo-name }}/${{ inputs.package-name }}/${{ env.version }} JFROG_ARTIFACTORY_URL: ${{ secrets.JFROG_ARTIFACTORY_URL }} JFROG_ARTIFACTORY_TOKEN: ${{ secrets.JFROG_ARTIFACTORY_TOKEN }} - - name: Publish package to PyPI - if: ${{ matrix.virtual-repo-name == 'pypi' || matrix.virtual-repo-name == 'test-pypi'}} - uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1 - with: - verbose: true - packages-dir: ${{ env.build-dir-path }}/ - repository-url: https://${{ matrix.virtual-repo-name == 'test-pypi' && 'test.pypi' || 'upload.pypi'}}.org/legacy/ - password: ${{ secrets.PYPI_TOKEN }} + - name: Fail on PyPI/TestPyPI virtual-repo-name + if: ${{ matrix.virtual-repo-name == 'pypi' || matrix.virtual-repo-name == 'test-pypi' }} + env: + VIRTUAL_REPO_NAME: ${{ matrix.virtual-repo-name }} + run: | + echo "::error::Not publishing '${VIRTUAL_REPO_NAME}' here: PyPI trusted publishing must run as a direct step in the caller's top-level workflow, not through this reusable workflow. See the 'virtual-repo-names' input description." + exit 1 add_release_asset: name: Add release asset diff --git a/.github/workflows/reusable-python-release_pypi_assets.yml b/.github/workflows/reusable-python-release_pypi_assets.yml index 54ccd7bd..ee1e52c4 100644 --- a/.github/workflows/reusable-python-release_pypi_assets.yml +++ b/.github/workflows/reusable-python-release_pypi_assets.yml @@ -9,8 +9,8 @@ on: type: string virtual-repo-names: description: > - List of repository names to publish to - (e.g. ["public-pypi-prod", "geophysics-pypi-prod"]) + List of repository names to publish to (e.g. ["public-pypi-prod", "geophysics-pypi-prod"]). + "pypi" and "test-pypi" are not supported: publish to PyPI from the calling workflow. required: true type: string release-tag: @@ -69,11 +69,10 @@ jobs: artifactory-dir-path: ${{ matrix.virtual-repo-name }}/${{ inputs.package-name }}/${{ inputs.release-tag }} JFROG_ARTIFACTORY_URL: ${{ secrets.JFROG_ARTIFACTORY_URL }} JFROG_ARTIFACTORY_TOKEN: ${{ secrets.JFROG_ARTIFACTORY_TOKEN }} - - name: Publish package to PyPI - if: ${{ matrix.virtual-repo-name == 'pypi' || matrix.virtual-repo-name == 'test-pypi'}} - uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1 - with: - verbose: true - packages-dir: download-assets/ - repository-url: https://${{ matrix.virtual-repo-name == 'test-pypi' && 'test.pypi' || 'upload.pypi'}}.org/legacy/ - password: ${{ secrets.PYPI_TOKEN }} + - name: Fail on PyPI/TestPyPI virtual-repo-name + if: ${{ matrix.virtual-repo-name == 'pypi' || matrix.virtual-repo-name == 'test-pypi' }} + env: + VIRTUAL_REPO_NAME: ${{ matrix.virtual-repo-name }} + run: | + echo "::error::Not publishing '${VIRTUAL_REPO_NAME}' here: PyPI trusted publishing must run as a direct step in the caller's top-level workflow, not through this reusable workflow. See the 'virtual-repo-names' input description." + exit 1