Compare commits

...

14 Commits

Author SHA1 Message Date
Manfred Riem f80a18a893 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>
2026-06-18 07:38:47 -05:00
Manfred Riem 9da00e3774 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>
2026-06-17 14:40:52 -05:00
Manfred Riem 5f427238d5 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>
2026-06-17 14:19:40 -05:00
Manfred Riem 892ecea9c2 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>
2026-06-17 13:58:41 -05:00
Manfred Riem 1b9e9bbd9c 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>
2026-06-17 13:01:23 -05:00
Manfred Riem f61c0cea7d 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>
2026-06-17 11:44:19 -05:00
Manfred Riem 121d434af4 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>
2026-06-17 09:50:09 -05:00
Manfred Riem 5d7ab7ddad 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>
2026-06-17 09:15:55 -05:00
Manfred Riem 465dacbfd6 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>
2026-06-16 07:36:56 -05:00
Manfred Riem 1efe6346a7 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>
2026-06-11 12:50:58 -05:00
Manfred Riem 6d15830c02 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>
2026-06-10 16:24:04 -05:00
Manfred Riem fb6df4cc6f 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>
2026-06-10 15:29:20 -05:00
Manfred Riem 6fadb04bfb 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>
2026-06-10 08:42:34 -05:00
Manfred Riem a57743e3a3 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>
2026-06-10 08:19:59 -05:00
5 changed files with 109 additions and 11 deletions
+79
View File
@@ -0,0 +1,79 @@
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
permissions:
contents: read
actions: write
steps:
- name: Verify tag format
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: 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
- name: Set up Python
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="$(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: 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
actions: read
steps:
- name: Download build artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
name: dist
path: dist/
- name: Install uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
- name: Publish to PyPI
run: uv publish
+6
View File
@@ -70,6 +70,12 @@ jobs:
specify init my-project
\`\`\`
Or from [PyPI](https://pypi.org/project/specify-cli/) (may lag briefly after release):
\`\`\`bash
uv tool install 'specify-cli==${VERSION_NO_V}'
\`\`\`
NOTES_EOF
echo "## What's Changed" >> release_notes.md
+15 -9
View File
@@ -1,5 +1,5 @@
<div align="center">
<img src="./media/logo_large.webp" alt="Spec Kit Logo" width="200" height="200"/>
<img src="https://raw.githubusercontent.com/github/spec-kit/main/media/logo_large.webp" alt="Spec Kit Logo" width="200" height="200"/>
<h1>🌱 Spec Kit</h1>
<h3><em>Build high-quality software faster.</em></h3>
</div>
@@ -44,13 +44,19 @@ 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.
Or install from [PyPI](https://pypi.org/project/specify-cli/) (may lag briefly after a new release):
```bash
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.
### 2. Initialize a project
@@ -59,7 +65,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,13 +125,13 @@ 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
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
@@ -292,7 +298,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
---
@@ -320,7 +326,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 +360,7 @@ specify init <project_name> --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.
+8 -2
View File
@@ -10,8 +10,8 @@
## 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 `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)
@@ -24,6 +24,12 @@ Install once and use everywhere. Replace `vX.Y.Z` with a tag from [Releases](htt
uv tool install specify-cli --from git+https://github.com/github/spec-kit.git@vX.Y.Z
```
Or install from PyPI:
```bash
uv tool install specify-cli@latest
```
Then initialize a project:
```bash
+1
View File
@@ -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",