Skip to content

feat: add PyPI publishing workflow and readme metadata#2915

Merged
mnriem merged 20 commits into
mainfrom
mnriem/feat-2908-pypi-publishing
Jun 22, 2026
Merged

feat: add PyPI publishing workflow and readme metadata#2915
mnriem merged 20 commits into
mainfrom
mnriem/feat-2908-pypi-publishing

Conversation

@mnriem

@mnriem mnriem commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds infrastructure for publishing specify-cli to PyPI, addressing #2908.

Changes

  1. pyproject.toml — adds readme = "README.md" so PyPI displays the project description
  2. .github/workflows/publish-pypi.yml — new manual workflow for publishing to PyPI

No changes to existing workflows, README, or documentation. PyPI install instructions will be added to docs in a follow-up PR after the first successful publish.

Publish Workflow Design

  • Manual trigger (workflow_dispatch) — run after the release workflow completes
  • Tag input — specify which release tag to publish (e.g., v0.10.1)
  • Validation — verifies tag format before checkout, uses refs/tags/ prefix, and confirms tag matches pyproject.toml version
  • Trusted publishers (OIDC) — no API tokens needed; uses id-token: write permission
  • Protected environment — requires a pypi GitHub environment for deployment gating
  • Two-job split — build (with actions: write + contents: read) → publish (OIDC + actions: read)
  • Python 3.13 pinned via actions/setup-python for deterministic builds

Prerequisites Before First Use

Testing

This workflow won't run until manually triggered with a valid tag, so it's safe to merge ahead of the PyPI ownership transfer.

Copilot AI review requested due to automatic review settings June 10, 2026 13:20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds release infrastructure to publish specify-cli to PyPI and improve the package’s PyPI description rendering, aligning with the goal that uv tool install specify-cli@latest works reliably.

Changes:

  • Add readme = "README.md" to pyproject.toml so PyPI renders the README.
  • Introduce a manual GitHub Actions workflow to build and publish to PyPI via trusted publishing (OIDC).
  • Update release notes generation to prefer uv tool install specify-cli@latest, with a source-install fallback.
Show a summary per file
File Description
pyproject.toml Adds README metadata for PyPI rendering.
.github/workflows/publish-pypi.yml New manual build+publish workflow using artifacts + OIDC trusted publishing.
.github/workflows/release.yml Updates generated release install instructions to prefer PyPI installs.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 3/3 changed files
  • Comments generated: 3

Comment thread .github/workflows/publish-pypi.yml
Comment thread .github/workflows/publish-pypi.yml
Comment thread .github/workflows/publish-pypi.yml
@youngjoel

Copy link
Copy Markdown

Note that PyPI does not host image files, so relative image paths from your local repository (e.g., My Image) will appear broken. To fix this, you must change your image URLs to absolute paths pointing to an external file host, such as the ://githubusercontent.com URL for your repository.

You can see this here: https://pypi.org/project/specify-cli/ , where the Spec Kit logo isn't rendered.

pypi/warehouse#5246

Copilot AI review requested due to automatic review settings June 10, 2026 20:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 4/4 changed files
  • Comments generated: 4

Comment thread README.md Outdated
Comment thread .github/workflows/release.yml Outdated
Comment thread .github/workflows/publish-pypi.yml Outdated
Comment thread .github/workflows/publish-pypi.yml Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 4/4 changed files
  • Comments generated: 3

Comment thread .github/workflows/publish-pypi.yml
Comment thread .github/workflows/release.yml Outdated
Comment thread .github/workflows/release.yml

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 4/4 changed files
  • Comments generated: 2

Comment thread .github/workflows/publish-pypi.yml
Comment thread .github/workflows/release.yml Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Not ready to approve

The new publish workflow should force checkout of refs/tags/<tag> (not a potentially ambiguous ref) to avoid publishing from an unintended branch with the same name.

Copilot's findings
  • Files reviewed: 4/4 changed files
  • Comments generated: 1

Note

Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.

Comment thread .github/workflows/publish-pypi.yml Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Not ready to approve

The release notes currently recommend an invalid uv tool install ...@latest command, and the publish workflow would benefit from pinning Python explicitly for deterministic builds/version parsing.

Copilot's findings
  • Files reviewed: 4/4 changed files
  • Comments generated: 3

Note

Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.

Comment thread .github/workflows/release.yml Outdated
Comment thread README.md Outdated
Comment thread .github/workflows/publish-pypi.yml

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Not ready to approve

The new publish workflow likely won’t run as written (uv publish --trusted-publishing always), and the updated release notes can direct users to install an unaffiliated PyPI package prior to ownership transfer (supply-chain risk).

Copilot's findings
  • Files reviewed: 4/4 changed files
  • Comments generated: 6

Note

Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.

Comment thread .github/workflows/publish-pypi.yml Outdated
Comment thread .github/workflows/publish-pypi.yml Outdated
Comment thread .github/workflows/publish-pypi.yml Outdated
Comment thread .github/workflows/release.yml Outdated
Comment thread README.md Outdated
Comment thread .github/workflows/release.yml

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Not ready to approve

The updated docs/README wording implies PyPI availability/ownership immediately, but the PR itself describes prerequisites and a post-release publish step—documentation should be conditioned to avoid misleading installs right after merge.

Copilot's findings
  • Files reviewed: 5/5 changed files
  • Comments generated: 2

Note

Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.

Comment thread README.md Outdated
Comment thread docs/installation.md Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Not ready to approve

The generated release notes use an invalid uv tool install version pin syntax (==), which is likely to fail when users follow the instructions.

Copilot's findings
  • Files reviewed: 5/5 changed files
  • Comments generated: 1

Note

Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.

Comment thread .github/workflows/release.yml
mnriem and others added 16 commits June 22, 2026 14:01
PyPI does not host images from the repository, so relative paths like
./media/logo.webp render as broken images. Switch to absolute
raw.githubusercontent.com URLs so images display on both GitHub and PyPI.

Ref: pypi/warehouse#5246

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Convert remaining /media/ image path to absolute URL for PyPI
- Pin release install to specific version (specify-cli==X.Y.Z)
- Align setup-uv to v8.2.0 matching rest of CI

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Use job-level permissions: actions:write on build (for upload-artifact),
  actions:read on publish (for download-artifact)
- Include both @latest and pinned version in release notes
- Add note that PyPI may lag behind the GitHub release

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Build job needs contents:read for checkout (job-level perms replace
  workflow-level)
- Clarify that PyPI publishing is manually triggered, not automatic

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Move tag format validation before checkout and use refs/tags/ prefix
to ensure we always check out a tag, not a branch with the same name.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Convert all relative .md links in README to absolute GitHub URLs
  for PyPI rendering compatibility
- Fix release notes: use 'uv tool install specify-cli' (no @latest)
- Pin Python 3.13 via uv python install for deterministic builds
  and use python3 directly instead of uv run

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Use actions/setup-python (pinned v6, Python 3.13) instead of
  uv python install for deterministic builds
- Use python instead of python3 for setup-python compatibility
- Remove unsupported --trusted-publishing always flag from uv publish
  (OIDC is auto-detected with id-token: write)
- Update README install to lead with PyPI, source as fallback
- Update installation guide: replace PyPI disclaimer with official
  package note, add PyPI as primary install method
- Release notes: pin to exact version, clarify PyPI timing

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- README: note source install is useful when PyPI version lags
- Installation guide: explain PyPI follows GitHub releases and may
  lag briefly; source installs are always immediately available

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
uv tool install accepts PEP 508 specifiers when quoted. Add quotes
around 'specify-cli==VERSION' so users can copy-paste directly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use @latest to force a fresh PyPI resolve (bypasses uv's cached tool
version), matching the issue acceptance criteria. Source install remains
as fallback when PyPI lags.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Release notes (versioned changelog) must always reference the specific
release version, not @latest. Use 'specify-cli==VERSION' for
reproducibility.

Also clarify that PyPI publishing is 'performed after' (not 'follows')
each release, making the manual nature clearer.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Until PyPI ownership is fully transferred and first publish is
confirmed, source installs from GitHub remain the primary recommended
method. PyPI install is listed as a convenient alternative.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Align actions/checkout to v7.0.0 (same SHA as test.yml/release.yml)
- Remove assertion that PyPI is published by maintainers (ownership
  transfer still pending); keep as availability statement
- Use 'once published for this release' wording in release notes
- Convert remaining relative links in README to absolute URLs for
  PyPI rendering

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- docs/installation.md: qualify PyPI as available 'once official
  publishing is enabled' (ownership transfer still pending)
- release.yml: use specify-cli@VERSION syntax (consistent with
  README/docs @latest form)
- PR description updated to match

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The release.yml release notes template should not change in this PR.
PyPI install instructions can be added to release notes in a future
PR once publishing is confirmed working.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Do not mention PyPI in documentation until the first official PyPI
release has been published. This PR only adds the workflow and readme
metadata in pyproject.toml.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 22, 2026 19:01
@mnriem mnriem force-pushed the mnriem/feat-2908-pypi-publishing branch from 38fdf33 to 2fec9c4 Compare June 22, 2026 19:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 1

Comment thread .github/workflows/publish-pypi.yml
Add if-no-files-found: error to upload-artifact so a missing/empty
dist/ directory fails the build job immediately rather than causing
a confusing failure in the publish job.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 2

Comment thread .github/workflows/publish-pypi.yml Outdated
Comment thread .github/workflows/publish-pypi.yml Outdated
Update upload-artifact to v7.0.1 and download-artifact to v8.0.1,
matching the pins used in the repo's gh-aw workflow lockfiles.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 2

Comment thread .github/workflows/publish-pypi.yml
Comment thread .github/workflows/publish-pypi.yml
@mnriem mnriem merged commit a233f3a into main Jun 22, 2026
13 checks passed
@mnriem mnriem deleted the mnriem/feat-2908-pypi-publishing branch June 22, 2026 20: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.

3 participants