# How the Release Workflow Builds and Attaches the Claude Video Skill Bundle

> Learn how the GitHub Actions release workflow automatically builds and attaches the Claude Video skill bundle as a zip archive to GitHub releases when you push a version tag.

- Repository: [bradautomates/claude-video](https://github.com/bradautomates/claude-video)
- Tags: how-to-guide
- Published: 2026-08-01

---

**The GitHub Actions release workflow automatically packages the `skills/watch` directory into a `.skill` zip archive and attaches it to a GitHub release whenever a version tag is pushed.**

The `bradautomates/claude-video` repository automates its distribution pipeline through a dedicated release workflow. This article explains exactly how the release workflow builds and attaches the skill bundle for Claude Video, covering the trigger conditions, validation logic, and artifact publication process.

## Release Trigger and Checkout Configuration

The workflow defined in [`.github/workflows/release.yml`](https://github.com/bradautomates/claude-video/blob/main/.github/workflows/release.yml) initiates only on specific version tags.

- **Trigger pattern**: The `on.push.tags` filter set to `"v*"` ensures the pipeline runs exclusively when tags like `v1.0.0` or `v2.1.0` are pushed【/cache/repos/github.com/bradautomates/claude-video/main/.github/workflows/release.yml#L4-L6】.
- **Repository history**: The checkout step uses `fetch-depth: 0` to retrieve the complete git history, which is required for the `git archive` command to access the `skills/watch` subtree【/cache/repos/github.com/bradautomates/claude-video/main/.github/workflows/release.yml#L15-L18】.

## Building the Skill Bundle

The core build logic resides in [`skills/watch/scripts/build-skill.sh`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/build-skill.sh), which the workflow invokes during the *"Build .skill artifact"* step【/cache/repos/github.com/bradautomates/claude-video/main/.github/workflows/release.yml#L20-L23】.

### Archive Creation

The script constructs the bundle by archiving the entire `skills/watch` subtree into a zip file with a specific prefix:

```bash
git archive --format=zip --prefix=watch/ --output=dist/watch.skill HEAD:skills/watch

```

This command generates `dist/watch.skill` containing all runtime scripts and the mandatory [`SKILL.md`](https://github.com/bradautomates/claude-video/blob/main/SKILL.md) file, prefixed with a `watch/` directory for proper namespacing【/cache/repos/github.com/bradautomates/claude-video/main/skills/watch/scripts/build-skill.sh#L11-L22】.

### Validation Checks

Before completing, the script enforces two critical constraints required by the Claude AI platform:

- **File count limit**: The bundle must contain **≤ 200 files** to comply with claude.ai upload restrictions.
- **Single manifest requirement**: Exactly one [`SKILL.md`](https://github.com/bradautomates/claude-video/blob/main/SKILL.md) must be present in the archive.

If either check fails, the script aborts with exit code 1 and prevents the workflow from proceeding【/cache/repos/github.com/bradautomates/claude-video/main/skills/watch/scripts/build-skill.sh#L23-L36】.

Upon successful validation, the script outputs the final bundle statistics:

```bash
echo "Built skill bundle: $OUTPUT"
echo "Files: $file_count"
echo "Size: $(du -h "$OUTPUT" | cut -f1)"

```

## Publishing to GitHub Releases

The final step uses `softprops/action-gh-release@v2` to create a non-draft, non-prerelease GitHub release with auto-generated notes. It specifically attaches the validated artifact from the build stage:

```yaml
- name: Create GitHub release
  uses: softprops/action-gh-release@v2
  with:
    files: dist/watch.skill
    generate_release_notes: true
    draft: false
    prerelease: false

```

This configuration publishes the `watch.skill` file as a downloadable release asset, making it available for direct upload through the Claude AI skill UI【/cache/repos/github.com/bradautomates/claude-video/main/.github/workflows/release.yml#L25-L30】.

## Summary

- **Trigger**: The workflow activates on tags matching `v*` to ensure versioned releases only.
- **Build**: The [`build-skill.sh`](https://github.com/bradautomates/claude-video/blob/main/build-skill.sh) script uses `git archive` to create `dist/watch.skill` from the `skills/watch` subtree.
- **Validation**: Enforces a 200-file limit and verifies exactly one [`SKILL.md`](https://github.com/bradautomates/claude-video/blob/main/SKILL.md) exists before allowing completion.
- **Distribution**: The `softprops/action-gh-release` action automatically attaches the bundle to the GitHub release page.

## Frequently Asked Questions

### What file format does the Claude Video skill bundle use?

The bundle is a standard **ZIP archive** with the `.skill` extension. It is generated using `git archive --format=zip` and contains the `skills/watch` directory contents prefixed with a `watch/` folder.

### Can I build the skill bundle locally without using GitHub Actions?

Yes. Run `bash skills/watch/scripts/build-skill.sh` from any location inside the repository. The script creates `dist/watch.skill` and performs the same file count and manifest validation as the CI pipeline.

### Why does the checkout step use `fetch-depth: 0`?

The workflow must fetch the complete git history because the build script relies on `git archive` to extract the `skills/watch` subtree. A shallow clone would prevent the archive command from accessing historical file data required for the bundle.

### What happens if the skill bundle exceeds 200 files?

The [`build-skill.sh`](https://github.com/bradautomates/claude-video/blob/main/build-skill.sh) script detects the violation during validation and exits with an error code, causing the GitHub Actions workflow to fail. This prevents publishing bundles that would be rejected by the claude.ai upload interface.