This document describes the automated release and distribution system that transforms the Spec Kit source code into 32 distributable template packages. The system uses GitHub Actions to detect version changes, build agent-specific variants, and publish release packages to GitHub Releases. Each package contains the complete set of templates, scripts, and agent-specific command files needed for project initialization.
For information about how the CLI downloads and extracts these packages during project initialization, see Project Initialization. For details on the command template structure that feeds into package generation, see Command Template System.
The release system follows a fully automated pipeline triggered by changes to core infrastructure files. The workflow coordinates multiple scripts to perform version detection, package generation, and GitHub release creation.
Sources: .github/workflows/release.yml1-60
The workflow is defined in .github/workflows/release.yml1-60 and executes on two conditions:
main branch affecting memory/, scripts/, templates/, or .github/workflows/ directories .github/workflows/release.yml4-10workflow_dispatch event .github/workflows/release.yml11Each step runs conditionally based on steps.check_release.outputs.exists == 'false' .github/workflows/release.yml38-56 to prevent duplicate releases.
The core of the distribution system is the create-release-packages.sh script, which generates 32 distinct package variants by iterating over all supported AI agents and script types.
| Package Component | Values | Source |
|---|---|---|
| AI Agents | claude, gemini, copilot, cursor-agent, qwen, opencode, windsurf, codex, kilocode, auggie, roo, codebuddy, amp, shai, q, bob, qoder | .github/workflows/scripts/create-release-packages.sh227 |
| Script Types | sh (Bash), ps (PowerShell) | .github/workflows/scripts/create-release-packages.sh228 |
| Package Name | spec-kit-template-{agent}-{script}-{version}.zip | .github/workflows/scripts/create-release-packages.sh222 |
| Build Directory | .genreleases/sdd-{agent}-package-{script}/ | .github/workflows/scripts/create-release-packages.sh127 |
The script accepts optional environment variables to build subsets during development:
Sources: .github/workflows/scripts/create-release-packages.sh8-261
Sources: .github/workflows/scripts/create-release-packages.sh125-270
The build_variant() function orchestrates package creation for a single agent-script combination:
Sources: .github/workflows/scripts/create-release-packages.sh125-224
The generate_commands() function processes command templates into agent-specific formats:
| Step | Operation | Code Reference |
|---|---|---|
| 1. Iterate templates | Process each *.md file in templates/commands/ | .github/workflows/scripts/create-release-packages.sh44 |
| 2. Normalize line endings | Remove carriage returns with tr -d '\r' | .github/workflows/scripts/create-release-packages.sh50 |
| 3. Extract frontmatter | Parse description: and {script_variant}: fields | .github/workflows/scripts/create-release-packages.sh53-59 |
| 4. Extract agent scripts | Parse agent_scripts: {script_variant}: if present | .github/workflows/scripts/create-release-packages.sh62-70 |
| 5. Substitute {SCRIPT} | Replace with script command from frontmatter | .github/workflows/scripts/create-release-packages.sh73 |
| 6. Substitute {AGENT_SCRIPT} | Replace with agent-specific script command | .github/workflows/scripts/create-release-packages.sh75-78 |
| 7. Remove script sections | Strip scripts: and agent_scripts: from YAML | .github/workflows/scripts/create-release-packages.sh81-88 |
| 8. Apply substitutions | Replace {ARGS}, __AGENT__, rewrite paths | .github/workflows/scripts/create-release-packages.sh91 |
| 9. Format output | Write as .md or .toml based on agent | .github/workflows/scripts/create-release-packages.sh93-101 |
Sources: .github/workflows/scripts/create-release-packages.sh41-103
The rewrite_paths() function normalizes template paths to package structure:
Sources: .github/workflows/scripts/create-release-packages.sh33-39
Placeholder substitution varies by agent format:
| Placeholder | Markdown Agents | TOML Agents | Purpose |
|---|---|---|---|
{ARGS} | $ARGUMENTS | {{args}} | Command-line arguments in agent syntax |
{SCRIPT} | Script command from sh: or ps: frontmatter | Script command | Bash or PowerShell script invocation |
{AGENT_SCRIPT} | Agent script from agent_scripts: section | Agent script | Agent-specific script override |
__AGENT__ | Agent identifier (e.g., claude) | Agent identifier | Agent name references |
Markdown agents: claude, copilot, cursor-agent, opencode, windsurf, codex, kilocode, auggie, roo, codebuddy, amp, shai, q, bob, qoder
TOML agents: gemini, qwen
Sources: .github/workflows/scripts/create-release-packages.sh91-221
Each agent requires different directory structures, file formats, and configuration files. The system handles this through switch-case logic in build_variant().
Sources: .github/workflows/scripts/create-release-packages.sh161-221
Copilot requires a dual-file structure with .agent.md files and companion .prompt.md files:
The generate_copilot_prompts() function creates .prompt.md files with agent frontmatter:
Sources: .github/workflows/scripts/create-release-packages.sh105-177
TOML agents require command files with description and prompt fields:
The system escapes backslashes in the body with sed 's/\\/\\\\/g' .github/workflows/scripts/create-release-packages.sh95 and includes agent-specific configuration files like GEMINI.md or QWEN.md .github/workflows/scripts/create-release-packages.sh168-184
Sources: .github/workflows/scripts/create-release-packages.sh93-184
The pipeline uses a multi-step version management process:
Sources: .github/workflows/release.yml25-36
The version must match the semantic versioning pattern ^v[0-9]+\.[0-9]+\.[0-9]+$ enforced in .github/workflows/scripts/create-release-packages.sh21-24
After package generation, the workflow compiles release notes and publishes to GitHub:
| Script | Function | Inputs | Outputs |
|---|---|---|---|
generate-release-notes.sh | Extract commit messages between versions | new_version, latest_tag | Changelog markdown |
create-github-release.sh | Create Git tag, upload packages, publish release | new_version, package zips in .genreleases/ | GitHub Release with download URLs |
update-version.sh | Update pyproject.toml version field | new_version | Updated project metadata |
Sources: .github/workflows/release.yml42-59
The create-github-release.sh script uploads all packages matching the pattern .genreleases/spec-kit-template-*-${NEW_VERSION}.zip using the GitHub CLI (gh release create).
All package generation uses the .genreleases/ directory as a temporary workspace:
Sources: .github/workflows/scripts/create-release-packages.sh29-31
This directory is ignored by Git .gitignore44 along with intermediate build artifacts:
.genreleases/
*.zip
sdd-*/
Sources: .gitignore44-46
The final output of a complete release build:
.genreleases/
├── spec-kit-template-claude-sh-v0.2.0.zip
├── spec-kit-template-claude-ps-v0.2.0.zip
├── spec-kit-template-gemini-sh-v0.2.0.zip
├── spec-kit-template-gemini-ps-v0.2.0.zip
├── spec-kit-template-copilot-sh-v0.2.0.zip
├── spec-kit-template-copilot-ps-v0.2.0.zip
... (32 total packages)
└── sdd-{agent}-package-{script}/ (temporary build directories)
Each zip file contains a complete, ready-to-extract project template for a specific agent and script type combination.
Sources: .github/workflows/scripts/create-release-packages.sh272-273
The released packages are consumed by the specify init command during project initialization. The CLI:
--ai and --script flagshttps://github.com/github/spec-kit/releases/download/{version}/spec-kit-template-{agent}-{script}-{version}.zip--no-git is not specifiedThis completes the distribution loop: source code → release pipeline → GitHub Release → CLI download → project initialization.
For detailed information about the CLI's package download and extraction logic, see GitHub API Integration and Project Initialization.
Sources: .github/workflows/scripts/create-release-packages.sh222
Refresh this wiki