Skip to content
3 changes: 1 addition & 2 deletions .github/workflows/_test_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,5 +83,4 @@ jobs:
repository-url: https://test.pypi.org/legacy/
# This setting ONLY IN CI AND ON TEST PYPI! See https://github.com/pypa/gh-action-pypi-publish#tolerating-release-package-file-duplicates
skip-existing: true
# TODO determine whether to enable attestations later on, and how
attestations: false
attestations: true
43 changes: 41 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ jobs:
outputs:
pkg-name: ${{ steps.check-version.outputs.pkg-name }}
version: ${{ steps.check-version.outputs.version }}
version-exists: ${{ steps.check-pypi.outputs.version-exists }}

steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -61,9 +62,42 @@ jobs:
f.write(f"pkg-name={pkg_name}\n")
f.write(f"version={version}\n")

- name: Check if version exists on PyPI
id: check-pypi
shell: python
env:
PKG_NAME: ${{ steps.check-version.outputs.pkg-name }}
VERSION: ${{ steps.check-version.outputs.version }}
run: |
import os
import urllib.request
import urllib.error

pkg_name = os.environ["PKG_NAME"]
version = os.environ["VERSION"]

try:
url = f"https://pypi.org/pypi/{pkg_name}/{version}/json"
with urllib.request.urlopen(url, timeout=30) as response:
# If we get here, the version exists on PyPI
print(f"Version {version} already exists on PyPI")
version_exists = "true"
except urllib.error.HTTPError as e:
if e.code == 404:
# Version doesn't exist, we can proceed
print(f"Version {version} does not exist on PyPI, proceeding with release")
version_exists = "false"
else:
# Other HTTP error, fail the workflow
raise

with open(os.environ["GITHUB_OUTPUT"], "a") as f:
f.write(f"version-exists={version_exists}\n")

test-pypi-publish:
needs:
- build
if: success() && needs.build.outputs.version-exists == 'false'
uses:
./.github/workflows/_test_release.yml
permissions: write-all
Expand All @@ -75,6 +109,7 @@ jobs:
needs:
- build
- test-pypi-publish
if: success() && needs.build.outputs.version-exists == 'false'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -132,6 +167,7 @@ jobs:
needs:
- build
- test-pypi-publish
if: success() && needs.build.outputs.version-exists == 'false'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -169,8 +205,11 @@ jobs:
- test-pypi-publish
- pre-release-checks
- pre-release-unit-lowest-python
if: success() && needs.build.outputs.version-exists == 'false'
runs-on: ubuntu-latest
# This requires an 'environment' with this name on the github repo (and is best practice to restrict permissions)
# NOTE: Once this trusted publishing workflow is fully verified with actual releases,
# revoke any legacy PyPI API tokens/keys for astrapy for enhanced security.
environment: pypi
permissions:
# Needed by trusted publish: https://blog.pypi.org/posts/2023-04-20-introducing-trusted-publishers/
Expand All @@ -196,8 +235,7 @@ jobs:
packages-dir: dist/
verbose: true
print-hash: true
# TODO determine whether to enable attestations later on, and how
attestations: false
attestations: true

mark-release:
needs:
Expand All @@ -206,6 +244,7 @@ jobs:
- pre-release-checks
- pre-release-unit-lowest-python
- publish
if: success() && needs.build.outputs.version-exists == 'false'
runs-on: ubuntu-latest
permissions:
# Needed by `ncipollo/release-action` for creating the release
Expand Down
Loading