The Automated Release Pipeline is a GitHub Actions-based continuous deployment system that automatically packages and publishes Spec Kit releases. When changes are pushed to critical directories (memory/, scripts/, templates/, .github/workflows/), the pipeline executes a multi-stage process: version detection, duplicate prevention, package generation for all 32 variants (16 AI agents × 2 script types), release note compilation, and GitHub Release publishing.
This document covers the workflow orchestration, triggers, conditional execution, and integration with supporting scripts. For package structure and variant generation details, see Multi-Platform Package Generation. For version numbering and changelog management, see Version Management and Changelog.
The release pipeline is defined in .github/workflows/release.yml1-61 and executes as a single GitHub Actions job with six sequential steps. Each step is conditionally executed based on the outcome of prior validation checks.
Pipeline Execution Flow
Sources: .github/workflows/release.yml13-60
The workflow responds to two types of triggers, both defined in the on section of the workflow file.
The pipeline activates on pushes to the main branch when changes affect specific directories. This optimization prevents unnecessary builds when unrelated files change.
Monitored Paths
| Path Pattern | Purpose |
|---|---|
memory/** | Constitution and memory artifacts |
scripts/** | Feature creation and agent context scripts |
templates/** | Command templates and spec templates |
.github/workflows/** | Workflow and pipeline scripts |
Changes to other directories (e.g., src/specify_cli/, docs/, README.md) do not trigger releases. This design assumes that CLI code changes require separate deployment through Python package managers.
Sources: .github/workflows/release.yml3-10
The workflow_dispatch event enables manual release triggering from the GitHub Actions UI. This provides an escape hatch for emergency releases or testing without requiring a git push.
Sources: .github/workflows/release.yml11
The workflow uses actions/checkout@v4 with full history (fetch-depth: 0) to enable git tag inspection and changelog generation across the entire commit history.
Checkout Configuration
The GITHUB_TOKEN secret provides authenticated access for subsequent git operations and GitHub API calls.
Sources: .github/workflows/release.yml20-24
The get-next-version.sh script determines the next semantic version tag by examining existing git tags. It outputs two values:
new_version: The computed next version (e.g., v0.2.0)latest_tag: The most recent existing tag (e.g., v0.1.9)Version Detection Step
The script is made executable via chmod +x before execution, a pattern repeated for all custom scripts in the pipeline.
Sources: .github/workflows/release.yml25-29
Before proceeding with package creation, the check-release-exists.sh script queries the GitHub API to verify that a release with the computed version tag does not already exist. This prevents duplicate releases and unnecessary builds.
Release Existence Check
The script sets a boolean output variable exists that controls conditional execution of all subsequent steps:
This conditional appears on steps 4, 5, 6, and 7. If a release exists, the workflow completes immediately without generating artifacts.
Sources: .github/workflows/release.yml30-36
The create-release-packages.sh script is the most complex stage, responsible for creating all 32 release variants. It receives the version number as a command-line argument:
The script executes a nested loop over all AI agents and script types, generating agent-specific directory structures and command files for each combination. Output artifacts (.zip files) are written to the .genreleases/ directory (see .gitignore44).
Sources: .github/workflows/release.yml37-41
The generate-release-notes.sh script compiles a changelog by analyzing commits between the current and previous release tags. It receives both version numbers:
The script outputs formatted release notes that are consumed by the subsequent release creation step.
Sources: .github/workflows/release.yml42-47
The create-github-release.sh script creates a GitHub Release via the GitHub API, attaching all generated .zip files as release assets. It requires the GITHUB_TOKEN secret for authentication:
The release is created as a draft or pre-release depending on version numbering conventions.
Sources: .github/workflows/release.yml48-54
The update-version.sh script modifies pyproject.toml to update the version number recorded in the Python package metadata. This ensures that the CLI tool can report the correct version via specify version.
Note: This step updates version metadata for release artifacts only. It does not commit the change back to the repository, as the version is primarily used for CLI display purposes.
Sources: .github/workflows/release.yml55-59
All custom scripts in the pipeline follow a consistent execution pattern:
Script Invocation Pattern
Scripts communicate with the GitHub Actions runtime via output variables, which are set using the special syntax:
These outputs are referenced in subsequent steps using the syntax:
${{ steps.step_id.outputs.variable_name }}
Sources: .github/workflows/release.yml13-60
The workflow requires elevated permissions to create releases and push tags:
contents: write: Enables creating releases, uploading assets, and creating tagspull-requests: write: Reserved for future automation (e.g., auto-generating release PRs)The GITHUB_TOKEN secret is automatically provided by GitHub Actions and scoped to the repository. It is passed to scripts via environment variables.
Sources: .github/workflows/release.yml16-18
The pipeline uses a single boolean flag (exists) from the duplicate check to control execution of all subsequent steps. This creates two possible execution paths:
Execution Paths
This design prevents partial releases or duplicate work. If the release exists, the workflow consumes minimal resources (< 30 seconds) by skipping all expensive operations.
Sources: .github/workflows/release.yml38-59
The pipeline employs several strategies to ensure reliable execution:
GitHub Actions defaults to fail-fast behavior: if any step fails, subsequent steps are skipped and the workflow fails. This prevents publishing incomplete releases.
The fetch-depth: 0 parameter ensures that all git history is available for tag analysis and changelog generation. Without this, the version detection script might produce incorrect results on shallow clones.
Each script is explicitly made executable (chmod +x) before invocation, ensuring that the pipeline works even if file permissions are not preserved during git operations.
The GITHUB_TOKEN is scoped to the repository and expires after the workflow completes, minimizing security risks from token exposure.
Sources: .github/workflows/release.yml13-60
The pipeline produces two categories of artifacts:
| Artifact | Location | Lifecycle |
|---|---|---|
.zip packages | .genreleases/ directory | Deleted after upload to GitHub Release |
| Release notes | Temporary file | Consumed during release creation |
| Version metadata | pyproject.toml modification | Not committed to repository |
These artifacts exist only during workflow execution and are excluded from version control via .gitignore44-45
| Asset Type | Example Filename | Purpose |
|---|---|---|
| Agent-Script Packages | spec-kit-template-claude-sh-v0.2.0.zip | Downloaded by specify init |
| Release Notes | Embedded in GitHub Release | User documentation |
| Git Tag | v0.2.0 | Version reference |
Published assets are permanent and publicly accessible via GitHub Releases.
Sources: .github/workflows/release.yml37-59 .gitignore44-46
The pipeline integrates with several external systems:
System Integration Map
Sources: .github/workflows/release.yml25-59
The pipeline execution time varies based on the conditional path:
| Scenario | Duration | Network Operations |
|---|---|---|
| Release exists | ~30 seconds | 2 API calls (checkout, check existence) |
| New release | ~3-5 minutes | 10+ API calls (checkout, existence check, asset uploads) |
The path-based trigger filtering reduces unnecessary builds by ~80% compared to triggering on all pushes to main.
Sources: .github/workflows/release.yml3-10
Refresh this wiki