From a57743e3a3f12a71b8f633bf8b7df91fc2368e1b Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Wed, 10 Jun 2026 08:19:59 -0500 Subject: [PATCH 01/14] 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/14] 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/14] 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/14] 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/14] 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/14] 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/14] 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/14] 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/14] 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/14] 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/14] 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/14] 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/14] 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) From f80a18a89385dbf3fc1fb4280e0201bc5ab5a345 Mon Sep 17 00:00:00 2001 From: Manfred Riem Date: Thu, 18 Jun 2026 07:38:47 -0500 Subject: [PATCH 14/14] fix: keep source install as primary, PyPI as alternative 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> --- .github/workflows/release.yml | 10 +++------- README.md | 8 ++++---- docs/installation.md | 10 +++++----- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6932d95e6b..8b7839f029 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -65,21 +65,17 @@ jobs: cat > release_notes.md << NOTES_EOF ## Install - From [PyPI](https://pypi.org/project/specify-cli/): - \`\`\`bash - uv tool install 'specify-cli==${VERSION_NO_V}' + uv tool install specify-cli --from git+https://github.com/github/spec-kit.git@${VERSION} specify init my-project \`\`\` - Or install from source: + Or from [PyPI](https://pypi.org/project/specify-cli/) (may lag briefly after release): \`\`\`bash - uv tool install specify-cli --from git+https://github.com/github/spec-kit.git@${VERSION} + uv tool install 'specify-cli==${VERSION_NO_V}' \`\`\` - > **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 echo "## What's Changed" >> release_notes.md diff --git a/README.md b/README.md index 44ec94bf84..0d89538da7 100644 --- a/README.md +++ b/README.md @@ -44,16 +44,16 @@ 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)): +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@latest +uv tool install specify-cli --from git+https://github.com/github/spec-kit.git@vX.Y.Z ``` -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): +Or install from [PyPI](https://pypi.org/project/specify-cli/) (may lag briefly after a new release): ```bash -uv tool install specify-cli --from git+https://github.com/github/spec-kit.git@vX.Y.Z +uv tool install specify-cli@latest ``` See the [Installation Guide](https://github.com/github/spec-kit/blob/main/docs/installation.md) for alternative methods, verification, upgrade, and troubleshooting. diff --git a/docs/installation.md b/docs/installation.md index 92cf1f0f4d..c44c3570f3 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -11,23 +11,23 @@ ## 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 is performed after each GitHub release and may lag briefly. Source installs from the GitHub repository are always available immediately. +> The `specify-cli` package is also available on [PyPI](https://pypi.org/project/specify-cli/), published 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) -Install once and use everywhere: +Install once and use everywhere. Replace `vX.Y.Z` with a tag from [Releases](https://github.com/github/spec-kit/releases): > [!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@latest +uv tool install specify-cli --from git+https://github.com/github/spec-kit.git@vX.Y.Z ``` -Or install from source using a specific [release](https://github.com/github/spec-kit/releases) tag: +Or install from PyPI: ```bash -uv tool install specify-cli --from git+https://github.com/github/spec-kit.git@vX.Y.Z +uv tool install specify-cli@latest ``` Then initialize a project: