Files
Chris Farhood 6310b56f26 ci: package skill as installable zip via Gitea Actions
Add a reproducible way to build the Claude-skill package and publish it:

- scripts/build-skill-zip.sh: stages SKILL.md + README + references/ + assets/
  into a zip whose single top-level cycling-training/ folder is the layout
  Claude Desktop / claude.ai import expects. Validates SKILL.md frontmatter.
- .gitea/workflows/release-skill.yml: on tag v* builds the zip and attaches it
  to a Gitea release (via the API using the automatic token); on manual
  dispatch uploads it as a run artifact.
- README: document the packaging/release flow and Claude Desktop zip-import.
- .gitignore: ignore dist/ build output.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TqrhBhC3GEcKyaw8RTk8G6
2026-07-20 19:23:37 -04:00

49 lines
1.7 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# Package the cycling-training skill into a zip that installs as a Claude skill
# (Claude Desktop / claude.ai "Skills", or Claude Code).
#
# The archive contains a single top-level `cycling-training/` directory holding
# SKILL.md + supporting docs — the layout Claude expects when importing a skill.
#
# Usage:
# scripts/build-skill-zip.sh [version]
# Example:
# scripts/build-skill-zip.sh v1.0.0 -> dist/cycling-training-v1.0.0.zip
# scripts/build-skill-zip.sh -> dist/cycling-training-dev.zip
#
set -euo pipefail
SKILL_NAME="cycling-training"
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
VERSION="${1:-dev}"
OUT_DIR="${ROOT}/dist"
STAGE="${OUT_DIR}/${SKILL_NAME}"
ZIP_NAME="${SKILL_NAME}-${VERSION}.zip"
# The files that make up the installable skill (repo/CI cruft is excluded).
INCLUDE=(SKILL.md README.md references assets)
rm -rf "${OUT_DIR}"
mkdir -p "${STAGE}"
for item in "${INCLUDE[@]}"; do
if [ ! -e "${ROOT}/${item}" ]; then
echo "ERROR: expected '${item}' not found at repo root" >&2
exit 1
fi
cp -R "${ROOT}/${item}" "${STAGE}/"
done
# Sanity checks: a skill is only valid with a SKILL.md that has name + description.
test -f "${STAGE}/SKILL.md" || { echo "ERROR: SKILL.md missing from package" >&2; exit 1; }
grep -q "^name:" "${STAGE}/SKILL.md" || { echo "ERROR: SKILL.md has no 'name:' frontmatter" >&2; exit 1; }
grep -q "^description:" "${STAGE}/SKILL.md" || { echo "ERROR: SKILL.md has no 'description:' frontmatter" >&2; exit 1; }
# Build the zip with the skill folder as the single top-level entry.
( cd "${OUT_DIR}" && zip -r -q "${ZIP_NAME}" "${SKILL_NAME}" -x '*.DS_Store' )
echo "Built ${OUT_DIR}/${ZIP_NAME}"
echo "Contents:"
( cd "${OUT_DIR}" && unzip -l "${ZIP_NAME}" )