From a57743e3a3f12a71b8f633bf8b7df91fc2368e1b Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Wed, 10 Jun 2026 08:19:59 -0500 Subject: [PATCH 01/13] feat: add PyPI publishing workflow and readme metadata - Add readme = "README.md" to pyproject.toml for PyPI project description - Add manual publish-pypi.yml workflow using trusted publishers (OIDC) - Update release.yml install instructions to prefer PyPI The publish workflow is manually triggered after a release, checks out the specified tag, verifies version consistency, builds with uv, and publishes using trusted publishing (no API tokens required). Prerequisites before first use: - Take ownership of the specify-cli PyPI project (#2908) - Create a 'pypi' environment in repo settings - Configure trusted publisher on PyPI for this repo/workflow Closes #2908 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/publish-pypi.yml | 70 ++++++++++++++++++++++++++++++ .github/workflows/release.yml | 8 +++- pyproject.toml | 1 + 3 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/publish-pypi.yml diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml new file mode 100644 index 0000000000..e5d8ac28fd --- /dev/null +++ b/.github/workflows/publish-pypi.yml @@ -0,0 +1,70 @@ +name: Publish to PyPI + +on: + workflow_dispatch: + inputs: + tag: + description: 'Release tag to publish (e.g., v0.10.1)' + required: true + type: string + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout release tag + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + with: + ref: ${{ inputs.tag }} + + - name: Verify tag is a release + run: | + TAG="${{ inputs.tag }}" + if [[ ! "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Error: '$TAG' is not a valid release tag (expected vX.Y.Z)" + exit 1 + fi + + - name: Verify tag matches package version + run: | + TAG_VERSION="${{ inputs.tag }}" + TAG_VERSION="${TAG_VERSION#v}" + PROJECT_VERSION="$(python3 -c 'import tomllib; print(tomllib.load(open("pyproject.toml","rb"))["project"]["version"])')" + if [[ "$TAG_VERSION" != "$PROJECT_VERSION" ]]; then + echo "Error: Tag version ($TAG_VERSION) does not match pyproject.toml version ($PROJECT_VERSION)" + exit 1 + fi + + - name: Install uv + uses: astral-sh/setup-uv@0c5e2b8115b80b4c7c5ddf6ffdd634974642d182 # v5 + + - name: Build package + run: uv build + + - name: Upload build artifacts + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: dist + path: dist/ + + publish: + needs: build + runs-on: ubuntu-latest + environment: pypi + permissions: + id-token: write + steps: + - name: Download build artifacts + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + with: + name: dist + path: dist/ + + - name: Install uv + uses: astral-sh/setup-uv@0c5e2b8115b80b4c7c5ddf6ffdd634974642d182 # v5 + + - name: Publish to PyPI + run: uv publish --trusted-publishing always diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b35bc30ec2..7b5683881f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -66,10 +66,16 @@ jobs: ## Install \`\`\`bash - uv tool install specify-cli --from git+https://github.com/github/spec-kit.git@${VERSION} + uv tool install specify-cli@latest specify init my-project \`\`\` + Or install from source: + + \`\`\`bash + uv tool install specify-cli --from git+https://github.com/github/spec-kit.git@${VERSION} + \`\`\` + NOTES_EOF echo "## What's Changed" >> release_notes.md diff --git a/pyproject.toml b/pyproject.toml index f8bdc23f91..463d8d8562 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,6 +2,7 @@ name = "specify-cli" version = "0.10.2.dev0" description = "Specify CLI, part of GitHub Spec Kit. A tool to bootstrap your projects for Spec-Driven Development (SDD)." +readme = "README.md" requires-python = ">=3.11" dependencies = [ "typer>=0.24.0", From 6fadb04bfb0104cb1d78fbd41938cddeb0e7b902 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Wed, 10 Jun 2026 08:42:34 -0500 Subject: [PATCH 02/13] fix: address PR review feedback on publish workflow - Add actions: read permission (required for artifact upload/download) - Move version check after uv install and use uv run python (ensures Python >=3.11 with tomllib is available regardless of runner image) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/publish-pypi.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index e5d8ac28fd..2b4e6f9420 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -10,6 +10,7 @@ on: permissions: contents: read + actions: read jobs: build: @@ -28,19 +29,19 @@ jobs: exit 1 fi + - name: Install uv + uses: astral-sh/setup-uv@0c5e2b8115b80b4c7c5ddf6ffdd634974642d182 # v5 + - name: Verify tag matches package version run: | TAG_VERSION="${{ inputs.tag }}" TAG_VERSION="${TAG_VERSION#v}" - PROJECT_VERSION="$(python3 -c 'import tomllib; print(tomllib.load(open("pyproject.toml","rb"))["project"]["version"])')" + PROJECT_VERSION="$(uv run python -c 'import tomllib; print(tomllib.load(open("pyproject.toml","rb"))["project"]["version"])')" if [[ "$TAG_VERSION" != "$PROJECT_VERSION" ]]; then echo "Error: Tag version ($TAG_VERSION) does not match pyproject.toml version ($PROJECT_VERSION)" exit 1 fi - - name: Install uv - uses: astral-sh/setup-uv@0c5e2b8115b80b4c7c5ddf6ffdd634974642d182 # v5 - - name: Build package run: uv build @@ -56,6 +57,7 @@ jobs: environment: pypi permissions: id-token: write + actions: read steps: - name: Download build artifacts uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 From fb6df4cc6fa099b638b7c733b5885cf0ffa3be1e Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Wed, 10 Jun 2026 15:29:20 -0500 Subject: [PATCH 03/13] fix: use absolute URLs for README images (PyPI compatibility) 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: https://github.com/pypi/warehouse/issues/5246 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0a0b4119b2..1d9d7d0887 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@
- Spec Kit Logo + Spec Kit Logo

🌱 Spec Kit

Build high-quality software faster.

@@ -320,7 +320,7 @@ specify init . --force specify init --here --force ``` -![Specify CLI bootstrapping a new project in the terminal](./media/specify_cli.gif) +![Specify CLI bootstrapping a new project in the terminal](https://raw.githubusercontent.com/github/spec-kit/main/media/specify_cli.gif) In an interactive terminal, you will be prompted to select the coding agent integration you are using. In non-interactive sessions, such as CI or piped runs, `specify init` defaults to GitHub Copilot unless you pass `--integration`. You can also proactively specify the integration directly in the terminal: @@ -354,7 +354,7 @@ specify init --integration copilot --ignore-agent-tools Go to the project folder and run your coding agent. In our example, we're using `claude`. -![Bootstrapping Claude Code environment](./media/bootstrap-claude-code.gif) +![Bootstrapping Claude Code environment](https://raw.githubusercontent.com/github/spec-kit/main/media/bootstrap-claude-code.gif) You will know that things are configured correctly if you see the `/speckit.constitution`, `/speckit.specify`, `/speckit.plan`, `/speckit.tasks`, and `/speckit.implement` commands available. From 6d15830c028849845fd0839ab21680654eb03ddb Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Wed, 10 Jun 2026 16:24:04 -0500 Subject: [PATCH 04/13] fix: address second review round - 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> --- .github/workflows/publish-pypi.yml | 4 ++-- .github/workflows/release.yml | 2 +- README.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index 2b4e6f9420..91ef3ef0a8 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -30,7 +30,7 @@ jobs: fi - name: Install uv - uses: astral-sh/setup-uv@0c5e2b8115b80b4c7c5ddf6ffdd634974642d182 # v5 + uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 - name: Verify tag matches package version run: | @@ -66,7 +66,7 @@ jobs: path: dist/ - name: Install uv - uses: astral-sh/setup-uv@0c5e2b8115b80b4c7c5ddf6ffdd634974642d182 # v5 + uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 - name: Publish to PyPI run: uv publish --trusted-publishing always diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7b5683881f..e4af57e0f1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -66,7 +66,7 @@ jobs: ## Install \`\`\`bash - uv tool install specify-cli@latest + uv tool install specify-cli==${VERSION_NO_V} specify init my-project \`\`\` diff --git a/README.md b/README.md index 1d9d7d0887..4a4c8c63ac 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,7 @@ For detailed step-by-step instructions, see our [comprehensive guide](./spec-dri Want to see Spec Kit in action? Watch our [video overview](https://www.youtube.com/watch?v=a9eR1xsfvHg&pp=0gcJCckJAYcqIYzv)! -[![Spec Kit video header](/media/spec-kit-video-header.jpg)](https://www.youtube.com/watch?v=a9eR1xsfvHg&pp=0gcJCckJAYcqIYzv) +[![Spec Kit video header](https://raw.githubusercontent.com/github/spec-kit/main/media/spec-kit-video-header.jpg)](https://www.youtube.com/watch?v=a9eR1xsfvHg&pp=0gcJCckJAYcqIYzv) ## 🌍 Community From 1efe6346a76154ec28e6210827bf2cdf2ce428ef Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Thu, 11 Jun 2026 12:50:58 -0500 Subject: [PATCH 05/13] fix: address third review round - 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> --- .github/workflows/publish-pypi.yml | 3 ++- .github/workflows/release.yml | 10 +++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index 91ef3ef0a8..6cedde6841 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -10,11 +10,12 @@ on: permissions: contents: read - actions: read jobs: build: runs-on: ubuntu-latest + permissions: + actions: write steps: - name: Checkout release tag uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e4af57e0f1..a22c7c34b5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -66,16 +66,24 @@ jobs: ## Install \`\`\`bash - uv tool install specify-cli==${VERSION_NO_V} + uv tool install specify-cli@latest specify init my-project \`\`\` + Or pin to this exact release: + + \`\`\`bash + uv tool install specify-cli==${VERSION_NO_V} + \`\`\` + Or install from source: \`\`\`bash uv tool install specify-cli --from git+https://github.com/github/spec-kit.git@${VERSION} \`\`\` + > **Note:** PyPI publishing runs shortly after this release is created. If the PyPI version is not yet available, use the source install command above. + NOTES_EOF echo "## What's Changed" >> release_notes.md From 465dacbfd61ec43c51fc8310da5f0ac1ca62904d Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Tue, 16 Jun 2026 07:36:56 -0500 Subject: [PATCH 06/13] fix: add contents:read to build job, clarify manual publish - 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> --- .github/workflows/publish-pypi.yml | 1 + .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index 6cedde6841..c59ca9f79b 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -15,6 +15,7 @@ jobs: build: runs-on: ubuntu-latest permissions: + contents: read actions: write steps: - name: Checkout release tag diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a22c7c34b5..b86ff5124b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -82,7 +82,7 @@ jobs: uv tool install specify-cli --from git+https://github.com/github/spec-kit.git@${VERSION} \`\`\` - > **Note:** PyPI publishing runs shortly after this release is created. If the PyPI version is not yet available, use the source install command above. + > **Note:** PyPI publishing is triggered manually after this release. If the PyPI version is not yet available, use the source install command above. NOTES_EOF From 5d7ab7ddad9f11ee33840a7711e490595d9567b5 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Wed, 17 Jun 2026 09:15:55 -0500 Subject: [PATCH 07/13] fix: force tag resolution and validate before checkout 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> --- .github/workflows/publish-pypi.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index c59ca9f79b..d38bd21a66 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -18,12 +18,7 @@ jobs: contents: read actions: write steps: - - name: Checkout release tag - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 - with: - ref: ${{ inputs.tag }} - - - name: Verify tag is a release + - name: Verify tag format run: | TAG="${{ inputs.tag }}" if [[ ! "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then @@ -31,6 +26,11 @@ jobs: exit 1 fi + - name: Checkout release tag + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + with: + ref: refs/tags/${{ inputs.tag }} + - name: Install uv uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 From 121d434af44b872ad5c6bba4454dcd633b8d232c Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Wed, 17 Jun 2026 09:50:09 -0500 Subject: [PATCH 08/13] fix: address review - links, install cmd, python pin - 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> --- .github/workflows/publish-pypi.yml | 5 ++++- .github/workflows/release.yml | 2 +- README.md | 10 +++++----- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index d38bd21a66..cf0b074403 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -34,11 +34,14 @@ jobs: - name: Install uv uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 + - name: Set up Python + run: uv python install 3.13 + - name: Verify tag matches package version run: | TAG_VERSION="${{ inputs.tag }}" TAG_VERSION="${TAG_VERSION#v}" - PROJECT_VERSION="$(uv run python -c 'import tomllib; print(tomllib.load(open("pyproject.toml","rb"))["project"]["version"])')" + PROJECT_VERSION="$(python3 -c 'import tomllib; print(tomllib.load(open("pyproject.toml","rb"))["project"]["version"])')" if [[ "$TAG_VERSION" != "$PROJECT_VERSION" ]]; then echo "Error: Tag version ($TAG_VERSION) does not match pyproject.toml version ($PROJECT_VERSION)" exit 1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b86ff5124b..19f3f6e343 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -66,7 +66,7 @@ jobs: ## Install \`\`\`bash - uv tool install specify-cli@latest + uv tool install specify-cli specify init my-project \`\`\` diff --git a/README.md b/README.md index 4a4c8c63ac..af2064e992 100644 --- a/README.md +++ b/README.md @@ -44,13 +44,13 @@ Spec-Driven Development **flips the script** on traditional software development ### 1. Install Specify CLI -Requires **[uv](https://docs.astral.sh/uv/)** ([install uv](./docs/install/uv.md)). Replace `vX.Y.Z` with the latest tag from [Releases](https://github.com/github/spec-kit/releases): +Requires **[uv](https://docs.astral.sh/uv/)** ([install uv](https://github.com/github/spec-kit/blob/main/docs/install/uv.md)). Replace `vX.Y.Z` with the latest tag from [Releases](https://github.com/github/spec-kit/releases): ```bash uv tool install specify-cli --from git+https://github.com/github/spec-kit.git@vX.Y.Z ``` -See the [Installation Guide](./docs/installation.md) for alternative methods, verification, upgrade, and troubleshooting. +See the [Installation Guide](https://github.com/github/spec-kit/blob/main/docs/installation.md) for alternative methods, verification, upgrade, and troubleshooting. ### 2. Initialize a project @@ -59,7 +59,7 @@ specify init my-project --integration copilot cd my-project ``` -To check for updates or upgrade the installed CLI, use the self-management commands. See the [Upgrade Guide](./docs/upgrade.md) for detailed scenarios and customization options. +To check for updates or upgrade the installed CLI, use the self-management commands. See the [Upgrade Guide](https://github.com/github/spec-kit/blob/main/docs/upgrade.md) for detailed scenarios and customization options. ```bash # Check whether a newer release is available (read-only — does not modify anything) @@ -119,7 +119,7 @@ Use **`/speckit.implement`** to execute all tasks and build your feature accordi /speckit.implement ``` -For detailed step-by-step instructions, see our [comprehensive guide](./spec-driven.md). +For detailed step-by-step instructions, see our [comprehensive guide](https://github.com/github/spec-kit/blob/main/spec-driven.md). ## 📽️ Video Overview @@ -292,7 +292,7 @@ If you encounter issues with an agent, please open an issue so we can refine the ## 📖 Learn More -- **[Complete Spec-Driven Development Methodology](./spec-driven.md)** - Deep dive into the full process +- **[Complete Spec-Driven Development Methodology](https://github.com/github/spec-kit/blob/main/spec-driven.md)** - Deep dive into the full process - **[Detailed Walkthrough](#-detailed-process)** - Step-by-step implementation guide --- From f61c0cea7d93e92126b1ce582fa67dc31760bcbc Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Wed, 17 Jun 2026 11:44:19 -0500 Subject: [PATCH 09/13] fix: address review - python setup, docs alignment, publish flag - 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> --- .github/workflows/publish-pypi.yml | 8 +++++--- .github/workflows/release.yml | 10 +++------- README.md | 8 +++++++- docs/installation.md | 12 +++++++++--- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index cf0b074403..535974e9b3 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -35,13 +35,15 @@ jobs: uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 - name: Set up Python - run: uv python install 3.13 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 + with: + python-version: "3.13" - name: Verify tag matches package version run: | TAG_VERSION="${{ inputs.tag }}" TAG_VERSION="${TAG_VERSION#v}" - PROJECT_VERSION="$(python3 -c 'import tomllib; print(tomllib.load(open("pyproject.toml","rb"))["project"]["version"])')" + PROJECT_VERSION="$(python -c 'import tomllib; print(tomllib.load(open("pyproject.toml","rb"))["project"]["version"])')" if [[ "$TAG_VERSION" != "$PROJECT_VERSION" ]]; then echo "Error: Tag version ($TAG_VERSION) does not match pyproject.toml version ($PROJECT_VERSION)" exit 1 @@ -74,4 +76,4 @@ jobs: uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 - name: Publish to PyPI - run: uv publish --trusted-publishing always + run: uv publish diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 19f3f6e343..c2022fda19 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -65,15 +65,11 @@ jobs: cat > release_notes.md << NOTES_EOF ## Install - \`\`\`bash - uv tool install specify-cli - specify init my-project - \`\`\` - - Or pin to this exact release: + From [PyPI](https://pypi.org/project/specify-cli/): \`\`\`bash uv tool install specify-cli==${VERSION_NO_V} + specify init my-project \`\`\` Or install from source: @@ -82,7 +78,7 @@ jobs: uv tool install specify-cli --from git+https://github.com/github/spec-kit.git@${VERSION} \`\`\` - > **Note:** PyPI publishing is triggered manually after this release. If the PyPI version is not yet available, use the source install command above. + > **Note:** The PyPI package is published after this GitHub release. If the version is not yet available on PyPI, use the source install above. NOTES_EOF diff --git a/README.md b/README.md index af2064e992..8dd6e8011f 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,13 @@ Spec-Driven Development **flips the script** on traditional software development ### 1. Install Specify CLI -Requires **[uv](https://docs.astral.sh/uv/)** ([install uv](https://github.com/github/spec-kit/blob/main/docs/install/uv.md)). Replace `vX.Y.Z` with the latest tag from [Releases](https://github.com/github/spec-kit/releases): +Requires **[uv](https://docs.astral.sh/uv/)** ([install uv](https://github.com/github/spec-kit/blob/main/docs/install/uv.md)): + +```bash +uv tool install specify-cli +``` + +Or install from source using a specific [release](https://github.com/github/spec-kit/releases) tag: ```bash uv tool install specify-cli --from git+https://github.com/github/spec-kit.git@vX.Y.Z diff --git a/docs/installation.md b/docs/installation.md index 3ee2f67b0e..954a4e2062 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -10,16 +10,22 @@ ## Installation -> [!IMPORTANT] -> The only official, maintained packages for Spec Kit come from the [github/spec-kit](https://github.com/github/spec-kit) GitHub repository. Any packages with the same name available on PyPI (e.g. `specify-cli` on pypi.org) are **not** affiliated with this project and are not maintained by the Spec Kit maintainers. For normal installs, use the GitHub-based commands shown below. For offline or air-gapped environments, locally built wheels created from this repository are also valid. +> [!NOTE] +> The official `specify-cli` package is published to [PyPI](https://pypi.org/project/specify-cli/) by the [github/spec-kit](https://github.com/github/spec-kit) maintainers. Source installs from the GitHub repository are also supported. ### Persistent Installation (Recommended) -Install once and use everywhere. Replace `vX.Y.Z` with a tag from [Releases](https://github.com/github/spec-kit/releases): +Install once and use everywhere: > [!NOTE] > The command below requires **[uv](https://docs.astral.sh/uv/)**. If you see `command not found: uv`, [install uv first](./install/uv.md). +```bash +uv tool install specify-cli +``` + +Or install from source using a specific [release](https://github.com/github/spec-kit/releases) tag: + ```bash uv tool install specify-cli --from git+https://github.com/github/spec-kit.git@vX.Y.Z ``` From 1b9e9bbd9c69af3dbed8d1df659de8f346a8046a Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Wed, 17 Jun 2026 13:01:23 -0500 Subject: [PATCH 10/13] fix: clarify PyPI availability timing in docs - 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> --- README.md | 2 +- docs/installation.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8dd6e8011f..bf0a56beff 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ Requires **[uv](https://docs.astral.sh/uv/)** ([install uv](https://github.com/g uv tool install specify-cli ``` -Or install from source using a specific [release](https://github.com/github/spec-kit/releases) tag: +Or install from source using a specific [release](https://github.com/github/spec-kit/releases) tag (useful if the PyPI version is not yet available for a new release): ```bash uv tool install specify-cli --from git+https://github.com/github/spec-kit.git@vX.Y.Z diff --git a/docs/installation.md b/docs/installation.md index 954a4e2062..260139f0fb 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -11,7 +11,7 @@ ## Installation > [!NOTE] -> The official `specify-cli` package is published to [PyPI](https://pypi.org/project/specify-cli/) by the [github/spec-kit](https://github.com/github/spec-kit) maintainers. Source installs from the GitHub repository are also supported. +> The official `specify-cli` package is published to [PyPI](https://pypi.org/project/specify-cli/) by the [github/spec-kit](https://github.com/github/spec-kit) maintainers. PyPI publishing follows each GitHub release and may lag briefly. Source installs from the GitHub repository are always available immediately. ### Persistent Installation (Recommended) From 892ecea9c23913c44563f7847402d720962ab68d Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Wed, 17 Jun 2026 13:58:41 -0500 Subject: [PATCH 11/13] fix: quote version specifier in release notes install command 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> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c2022fda19..6932d95e6b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -68,7 +68,7 @@ jobs: From [PyPI](https://pypi.org/project/specify-cli/): \`\`\`bash - uv tool install specify-cli==${VERSION_NO_V} + uv tool install 'specify-cli==${VERSION_NO_V}' specify init my-project \`\`\` From 5f427238d5079f36a8137cc797b60071eee3dfed Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Wed, 17 Jun 2026 14:19:40 -0500 Subject: [PATCH 12/13] fix: use specify-cli@latest consistently 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> --- .github/workflows/release.yml | 2 +- README.md | 2 +- docs/installation.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6932d95e6b..d12e2a6787 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -68,7 +68,7 @@ jobs: From [PyPI](https://pypi.org/project/specify-cli/): \`\`\`bash - uv tool install 'specify-cli==${VERSION_NO_V}' + uv tool install specify-cli@latest specify init my-project \`\`\` diff --git a/README.md b/README.md index bf0a56beff..44ec94bf84 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ Spec-Driven Development **flips the script** on traditional software development Requires **[uv](https://docs.astral.sh/uv/)** ([install uv](https://github.com/github/spec-kit/blob/main/docs/install/uv.md)): ```bash -uv tool install specify-cli +uv tool install specify-cli@latest ``` Or install from source using a specific [release](https://github.com/github/spec-kit/releases) tag (useful if the PyPI version is not yet available for a new release): diff --git a/docs/installation.md b/docs/installation.md index 260139f0fb..b34d27b720 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -21,7 +21,7 @@ Install once and use everywhere: > The command below requires **[uv](https://docs.astral.sh/uv/)**. If you see `command not found: uv`, [install uv first](./install/uv.md). ```bash -uv tool install specify-cli +uv tool install specify-cli@latest ``` Or install from source using a specific [release](https://github.com/github/spec-kit/releases) tag: From 9da00e37746312c5e5b32fbac87d0ed54a2a5026 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Wed, 17 Jun 2026 14:40:52 -0500 Subject: [PATCH 13/13] fix: pin release notes to exact version, clarify manual publish 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> --- .github/workflows/release.yml | 2 +- docs/installation.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d12e2a6787..6932d95e6b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -68,7 +68,7 @@ jobs: From [PyPI](https://pypi.org/project/specify-cli/): \`\`\`bash - uv tool install specify-cli@latest + uv tool install 'specify-cli==${VERSION_NO_V}' specify init my-project \`\`\` diff --git a/docs/installation.md b/docs/installation.md index b34d27b720..92cf1f0f4d 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -11,7 +11,7 @@ ## Installation > [!NOTE] -> The official `specify-cli` package is published to [PyPI](https://pypi.org/project/specify-cli/) by the [github/spec-kit](https://github.com/github/spec-kit) maintainers. PyPI publishing follows each GitHub release and may lag briefly. Source installs from the GitHub repository are always available immediately. +> The official `specify-cli` package is published to [PyPI](https://pypi.org/project/specify-cli/) by the [github/spec-kit](https://github.com/github/spec-kit) maintainers. PyPI publishing is performed after each GitHub release and may lag briefly. Source installs from the GitHub repository are always available immediately. ### Persistent Installation (Recommended)