|
| 1 | +.PHONY: test test-live build clean bump-patch bump-minor bump-major set-token-pypi set-token-testpypi release-test release verify-release-test verify-release |
| 2 | + |
| 3 | +test: |
| 4 | + uv run --extra dev pytest |
| 5 | + |
| 6 | +test-live: |
| 7 | + uv run --extra dev pytest -m live |
| 8 | + |
| 9 | +clean: |
| 10 | + rm -rf dist build *.egg-info |
| 11 | + |
| 12 | +build: clean |
| 13 | + uv build |
| 14 | + |
| 15 | +# Version bumps: edits pyproject.toml in place and prints old => new. |
| 16 | +bump-patch: |
| 17 | + uv version --bump patch |
| 18 | + |
| 19 | +bump-minor: |
| 20 | + uv version --bump minor |
| 21 | + |
| 22 | +bump-major: |
| 23 | + uv version --bump major |
| 24 | + |
| 25 | +# Store a PyPI / TestPyPI token in macOS Keychain. Prompts with hidden input |
| 26 | +# (bash `read -rsp`), so the token never appears on screen, in shell history, |
| 27 | +# or in `make` output. Re-running overwrites the existing entry. |
| 28 | +set-token-pypi: |
| 29 | + @bash -c 'read -rsp "Paste PyPI token: " TOKEN && echo && \ |
| 30 | + security delete-generic-password -s pypi-token-pypi >/dev/null 2>&1; \ |
| 31 | + security add-generic-password -a "$$USER" -s pypi-token-pypi -w "$$TOKEN" && \ |
| 32 | + echo "stored in Keychain under service: pypi-token-pypi"' |
| 33 | + |
| 34 | +set-token-testpypi: |
| 35 | + @bash -c 'read -rsp "Paste TestPyPI token: " TOKEN && echo && \ |
| 36 | + security delete-generic-password -s pypi-token-testpypi >/dev/null 2>&1; \ |
| 37 | + security add-generic-password -a "$$USER" -s pypi-token-testpypi -w "$$TOKEN" && \ |
| 38 | + echo "stored in Keychain under service: pypi-token-testpypi"' |
| 39 | + |
| 40 | +# Publish to TestPyPI. Token comes from macOS Keychain (service: pypi-token-testpypi). |
| 41 | +# The `@` on the recipe lines hides the actual command so the token never appears in output. |
| 42 | +release-test: build |
| 43 | + @VERSION=$$(grep '^version' pyproject.toml | head -1 | cut -d'"' -f2) && \ |
| 44 | + STATUS=$$(curl -s -o /dev/null -w "%{http_code}" "https://test.pypi.org/pypi/diffbot-python/$$VERSION/json") && \ |
| 45 | + if [ "$$STATUS" = "200" ]; then \ |
| 46 | + echo "ERROR: diffbot-python $$VERSION is already on TestPyPI. Bump the version in pyproject.toml."; \ |
| 47 | + exit 1; \ |
| 48 | + fi |
| 49 | + @TOKEN=$$(security find-generic-password -s pypi-token-testpypi -w 2>/dev/null) && \ |
| 50 | + if [ -z "$$TOKEN" ]; then \ |
| 51 | + echo "ERROR: no Keychain entry for pypi-token-testpypi. Run 'make set-token-testpypi' first."; \ |
| 52 | + exit 1; \ |
| 53 | + fi && \ |
| 54 | + UV_PUBLISH_TOKEN="$$TOKEN" uv publish --publish-url https://test.pypi.org/legacy/ |
| 55 | + |
| 56 | +# Publish to real PyPI. Confirmation gate before upload (PyPI does not allow re-uploads). |
| 57 | +release: build |
| 58 | + @VERSION=$$(grep '^version' pyproject.toml | head -1 | cut -d'"' -f2) && \ |
| 59 | + STATUS=$$(curl -s -o /dev/null -w "%{http_code}" "https://pypi.org/pypi/diffbot-python/$$VERSION/json") && \ |
| 60 | + if [ "$$STATUS" = "200" ]; then \ |
| 61 | + echo "ERROR: diffbot-python $$VERSION is already on PyPI. Bump the version in pyproject.toml."; \ |
| 62 | + exit 1; \ |
| 63 | + fi && \ |
| 64 | + echo "About to publish diffbot-python $$VERSION to PyPI. This cannot be undone." && \ |
| 65 | + read -p "Type the version to confirm: " CONFIRM && \ |
| 66 | + [ "$$CONFIRM" = "$$VERSION" ] || { echo "Aborted."; exit 1; } |
| 67 | + @TOKEN=$$(security find-generic-password -s pypi-token-pypi -w 2>/dev/null) && \ |
| 68 | + if [ -z "$$TOKEN" ]; then \ |
| 69 | + echo "ERROR: no Keychain entry for pypi-token-pypi. Run 'make set-token-pypi' first."; \ |
| 70 | + exit 1; \ |
| 71 | + fi && \ |
| 72 | + UV_PUBLISH_TOKEN="$$TOKEN" uv publish |
| 73 | + |
| 74 | +# Smoke-test installs from each index in a throwaway venv. |
| 75 | +# `cd $$TMP` before running python so CWD doesn't shadow the venv install with this repo's source. |
| 76 | +# Deps live on prod PyPI, so TestPyPI install needs --extra-index-url. |
| 77 | +verify-release-test: |
| 78 | + @VERSION=$$(grep '^version' pyproject.toml | head -1 | cut -d'"' -f2) && \ |
| 79 | + TMP=$$(mktemp -d) && \ |
| 80 | + uv venv --python 3.12 $$TMP/.venv >/dev/null 2>&1 && \ |
| 81 | + uv pip install --quiet --python $$TMP/.venv/bin/python \ |
| 82 | + --index-url https://test.pypi.org/simple/ \ |
| 83 | + --extra-index-url https://pypi.org/simple/ \ |
| 84 | + "diffbot-python==$$VERSION" && \ |
| 85 | + (cd $$TMP && $$TMP/.venv/bin/python -c "import diffbot; print('TestPyPI install OK:', diffbot.__version__)") && \ |
| 86 | + rm -rf $$TMP |
| 87 | + |
| 88 | +verify-release: |
| 89 | + @VERSION=$$(grep '^version' pyproject.toml | head -1 | cut -d'"' -f2) && \ |
| 90 | + TMP=$$(mktemp -d) && \ |
| 91 | + uv venv --python 3.12 $$TMP/.venv >/dev/null 2>&1 && \ |
| 92 | + uv pip install --quiet --python $$TMP/.venv/bin/python "diffbot-python==$$VERSION" && \ |
| 93 | + (cd $$TMP && $$TMP/.venv/bin/python -c "import diffbot; print('PyPI install OK:', diffbot.__version__)") && \ |
| 94 | + rm -rf $$TMP |
0 commit comments