# How the Garden Skills Release Pipeline Works: End-to-End Automation

> Discover how the Garden Skills release pipeline automates workflows. Learn about tag-driven GitHub Actions, manifest validation, artifact packaging, and release generation for seamless updates.

- Repository: [ConardLi/garden-skills](https://github.com/ConardLi/garden-skills)
- Tags: internals
- Published: 2026-09-01

---

**TL;DR:** Garden Skills uses a tag-driven GitHub Actions workflow that automatically parses semantic version tags, validates skill manifests, packs artifacts with SHA-256 checksums, creates GitHub releases with generated notes, and synchronizes download links across all localized READMEs.

The `ConardLi/garden-skills` repository implements a fully automated **release pipeline** that eliminates manual steps for publishing new skill versions. When a maintainer pushes a Git tag matching the `*-v*` pattern, the system orchestrates validation, packaging, distribution, and documentation updates through a single cohesive workflow.

## Overview of the Tag-Driven Workflow

The entire process is defined in [`.github/workflows/release-skill.yml`](https://github.com/ConardLi/garden-skills/blob/main/.github/workflows/release-skill.yml). The pipeline triggers on any tag push and executes four distinct stages: extracting skill identity and version from the tag, validating and packing the skill directory, creating a GitHub Release with artifacts, and synchronizing localized README files to reflect the new download URLs.

## Stage 1: Tag Parsing and Validation

The workflow initiates by parsing the Git tag to identify which skill to release. In [`release-skill.yml`](https://github.com/ConardLi/garden-skills/blob/main/release-skill.yml) (lines 48-62), the pipeline extracts the **skill name** and **semantic version** from tags following the `*-v*` pattern.

For example, pushing `web-design-engineer-v1.2.0` tells the system to process the `web-design-engineer` skill at version `1.2.0`. The workflow then verifies that [`skills/web-design-engineer/manifest.json`](https://github.com/ConardLi/garden-skills/blob/main/skills/web-design-engineer/manifest.json) exists and that its declared version matches the tag version exactly.

## Stage 2: Skill Packing and Manifest Validation

Once validated, the pipeline executes `npm run pack`, which invokes `scripts/release/pack-skill.mjs`. The `packOne()` function (lines 74-90) performs several critical operations:

- Validates the [`manifest.json`](https://github.com/ConardLi/garden-skills/blob/main/manifest.json) structure and version consistency against the Git tag
- Checks the skill directory structure for required files
- Creates a deterministic zip file named `<skill>-<version>.zip`
- Generates a SHA-256 checksum file with the `.sha256` extension

The artifacts are written to `dist/release/`, producing files like `web-design-engineer-1.2.0.zip` and `web-design-engineer-1.2.0.zip.sha256`.

## Stage 3: Release Notes and GitHub Release Creation

With packed artifacts ready, the pipeline generates release notes by analyzing Git history since the previous tag for that specific skill. As implemented in [`release-skill.yml`](https://github.com/ConardLi/garden-skills/blob/main/release-skill.yml) (lines 81-106), the workflow creates a GitHub Release that automatically attaches the zip file and its checksum.

If no previous tag exists for the skill, the notes indicate an "initial release." The release creation step (lines 25-33) uses the GitHub API to publish the release with the generated notes and artifacts attached.

## Stage 4: Automated README Synchronization

The final stage ensures documentation stays current. After the GitHub Release publishes, the workflow switches back to the default branch and executes `scripts/release/update-readme.mjs`. The `rewrite()` function (lines 72-90) scans all localized README files (e.g., [`README.md`](https://github.com/ConardLi/garden-skills/blob/main/README.md), [`README.zh-CN.md`](https://github.com/ConardLi/garden-skills/blob/main/README.zh-CN.md), [`README.ja-JP.md`](https://github.com/ConardLi/garden-skills/blob/main/README.ja-JP.md)) for HTML comment blocks matching `<!-- DOWNLOAD:<skill>:start -->` and `<!-- DOWNLOAD:<skill>:end -->`.

The script updates these blocks to reference the newly published zip URL, then commits the changes directly to the default branch. This ensures users always see correct download links regardless of which language version they view.

## Key Source Files and Their Roles

Understanding the release pipeline requires familiarity with these specific files:

- **[`.github/workflows/release-skill.yml`](https://github.com/ConardLi/garden-skills/blob/main/.github/workflows/release-skill.yml)**: The orchestration layer that triggers on tag pushes and coordinates all four pipeline stages.
- **`scripts/release/pack-skill.mjs`**: Contains the `packOne()` function that validates manifests, compresses directories, and generates SHA-256 checksums.
- **`scripts/release/update-readme.mjs`**: Implements the `rewrite()` function that synchronizes download links across localized documentation.
- **`scripts/release/cut-release.mjs`**: A maintainer utility that bumps manifest versions, runs README updates, and pushes tags.
- **`skills/<skill>/manifest.json`**: The source of truth for skill metadata that the pipeline validates against Git tags.

## Local Development and Testing Commands

While the pipeline runs automatically on tags, you can execute individual stages locally for testing.

### Tagging a Skill to Trigger Release

```bash
git tag web-design-engineer-v1.2.0
git push origin web-design-engineer-v1.2.0

```

*Pushing the tag immediately triggers the complete release pipeline without further intervention.*

### Manually Packing a Skill

```bash
npm run pack -- --skill web-design-engineer --version 1.2.0 --out dist/release

```

*This executes `scripts/release/pack-skill.mjs` directly, producing the same zip and checksum files generated during CI.*

### Verifying README Synchronization

```bash
node scripts/release/update-readme.mjs --check

```

*Exit code 0 indicates all download blocks are current; non-zero identifies out-of-date documentation that needs updating.*

## Summary

- The **Garden Skills release pipeline** is a fully automated, tag-driven GitHub Actions workflow defined in [`.github/workflows/release-skill.yml`](https://github.com/ConardLi/garden-skills/blob/main/.github/workflows/release-skill.yml).
- Tags must follow the `*-v*` pattern (e.g., `skillname-v1.2.0`) to trigger the pipeline.
- The `pack-skill.mjs` script validates manifests and creates deterministic zip artifacts with SHA-256 checksums.
- `update-readme.mjs` automatically synchronizes download links across localized README files after each release.
- Local testing is supported through `npm run pack` and the `--check` flag on the README update script.

## Frequently Asked Questions

### What tag format triggers the Garden Skills release pipeline?

The pipeline triggers exclusively on tags matching the `*-v*` glob pattern, such as `web-design-engineer-v1.2.0` or `data-analyst-v2.0.0-beta.1`. The workflow parses these tags in [`release-skill.yml`](https://github.com/ConardLi/garden-skills/blob/main/release-skill.yml) (lines 48-62) to extract the skill directory name and semantic version, rejecting tags that do not follow this convention.

### How does the pipeline validate skill integrity before release?

Validation occurs in `scripts/release/pack-skill.mjs` within the `packOne()` function (lines 74-90). The script confirms the skill directory exists, verifies the [`manifest.json`](https://github.com/ConardLi/garden-skills/blob/main/manifest.json) is valid JSON, checks that the manifest version matches the Git tag version, and ensures the directory structure conforms to expected layouts before creating the zip archive.

### Can I test the release process without creating a GitHub release?

Yes. Run `npm run pack -- --skill <name> --version <ver> --out dist/release` locally to execute the packing and validation logic without triggering the full GitHub Actions workflow. Additionally, use `node scripts/release/update-readme.mjs --check` to verify README synchronization state without committing changes.

### Which files are modified during the README synchronization step?

The `update-readme.mjs` script modifies all localized README files in the repository root, specifically [`README.md`](https://github.com/ConardLi/garden-skills/blob/main/README.md), [`README.zh-CN.md`](https://github.com/ConardLi/garden-skills/blob/main/README.zh-CN.md), and [`README.ja-JP.md`](https://github.com/ConardLi/garden-skills/blob/main/README.ja-JP.md). It searches for HTML comment blocks formatted as `<!-- DOWNLOAD:<skill>:start -->` and `<!-- DOWNLOAD:<skill>:end -->`, updating only the content between these markers to reflect the latest release download URLs.