Skip to content

ci: add an optional TestPyPI dry-run release workflow - #196

Merged
kevincostner17 merged 1 commit into
mainfrom
ci/testpypi-smoke
Sep 14, 2026
Merged

kevincostner17 merged 1 commit into
mainfrom
ci/testpypi-smoke

Conversation

@kevincostner17

Copy link
Copy Markdown
Contributor

Closes #6.

Summary

The release checklist says "Publish to TestPyPI, smoke-test the install", but the only documented route was a manual twine upload with an API token. This adds a manual, token-free dry run.

.github/workflows/testpypi.yml (workflow_dispatch only)

  1. build: reads the version from pyproject.toml and stamps a unique X.Y.Z.dev<run_number><run_attempt> into pyproject.toml and src/freshdata/__init__.py. This only affects the CI checkout; nothing is committed. TestPyPI rejects re-uploading a version, so every run needs its own. The job validates the version with packaging, then runs python -m build and twine check.
  2. publish-testpypi: environment testpypi, id-token: write, and pypa/gh-action-pypi-publish (already SHA-pinned in release.yml) with repository-url: https://test.pypi.org/legacy/. It uses Trusted Publishing (OIDC), so there are no secrets or tokens.
  3. smoke: in a clean venv, installs freshdata-cleaner==<dev version> from https://test.pypi.org/simple/ (with PyPI as the extra index for dependencies), retrying up to 10×30s while the index catches up. It then runs python -c "import freshdata as fd; print(fd.__version__)", asserts the output equals the published version, and runs the same tiny fd.clean smoke as release.yml.

The workflow is limited to FreshCode-Org/freshdata, and it never touches production PyPI or release.yml.

RELEASE.md

  • Checklist step 6 points to the workflow.
  • New TestPyPI dry run (optional) section: how to dispatch and watch it, the manual verification command (pip install --index-url https://test.pypi.org/simple/ … && python -c "import freshdata as fd; print(fd.__version__)"), and the one-time setup.
  • The token-based twine flow stays as the labelled fallback.

Maintainer action required before the first run

The workflow will fail at the publish step until someone with admin access:

  1. Adds a pending trusted publisher on https://test.pypi.org/manage/account/publishing/: project freshdata-cleaner, owner FreshCode-Org, repository freshdata, workflow testpypi.yml, environment testpypi.
  2. Creates the testpypi environment under repository Settings → Environments. It needs no secrets.

Because of that, I haven't dispatched it yet.

Tests

New tests/test_testpypi_workflow.py:

  • The only trigger is workflow_dispatch.
  • Publishing uses id-token: write, the testpypi environment and test.pypi.org/legacy/, with no password and no secrets. anywhere in the file.
  • The smoke job depends on publish, installs from test.pypi.org/simple/ and prints fd.__version__.
  • RELEASE.md contains the verification command.

Results: 4 passed on Python 3.12 and on 3.9. ruff check is clean, and the workflow parses as YAML.

A manual workflow rehearses a release without touching real PyPI or storing
tokens: it builds the current commit as a unique X.Y.Z.dev<run><attempt>
version (TestPyPI never accepts re-uploads), publishes it to TestPyPI with
Trusted Publishing (OIDC, environment `testpypi`), then installs it from
TestPyPI in a clean venv with retries, imports it, prints fd.__version__
and asserts it matches, and runs a tiny fd.clean smoke.

RELEASE.md documents the workflow, the manual verification command and the
one-time maintainer setup (TestPyPI pending publisher + `testpypi`
environment). A contract test pins the dispatch-only trigger, OIDC-only
publishing to test.pypi.org and the version print.
@coderabbitai

coderabbitai Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 22d2e083-c493-493f-bfe4-1431a936923d


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@kevincostner17
kevincostner17 merged commit 0d85e19 into main Sep 14, 2026
18 checks passed
@kevincostner17
kevincostner17 deleted the ci/testpypi-smoke branch September 14, 2026 18:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a TestPyPI smoke-install release step

1 participant