From ee6b83c1dd94fec0b48b4203853549ce860ede9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Den=20Delimarsky=20=F0=9F=8C=BA?= <53200638+localden@users.noreply.github.com> Date: Thu, 11 Sep 2025 22:59:36 -0700 Subject: [PATCH] Consolidate script creation --- .github/workflows/manual-release.yml | 191 --------------------------- .github/workflows/release.yml | 90 +------------ scripts/create-release-packages.sh | 115 ++++++++++++++++ 3 files changed, 117 insertions(+), 279 deletions(-) delete mode 100644 .github/workflows/manual-release.yml create mode 100644 scripts/create-release-packages.sh diff --git a/.github/workflows/manual-release.yml b/.github/workflows/manual-release.yml deleted file mode 100644 index 0251517..0000000 --- a/.github/workflows/manual-release.yml +++ /dev/null @@ -1,191 +0,0 @@ -name: Manual Release - -on: - workflow_dispatch: - inputs: - version_bump: - description: 'Version bump type' - required: true - default: 'patch' - type: choice - options: - - patch - - minor - - major - -jobs: - manual_release: - runs-on: ubuntu-latest - - permissions: - contents: write - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Calculate new version - id: version - run: | - # Get the latest tag, or use v0.0.0 if no tags exist - LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") - echo "latest_tag=$LATEST_TAG" >> $GITHUB_OUTPUT - - # Extract version number - VERSION=$(echo $LATEST_TAG | sed 's/v//') - IFS='.' read -ra VERSION_PARTS <<< "$VERSION" - MAJOR=${VERSION_PARTS[0]:-0} - MINOR=${VERSION_PARTS[1]:-0} - PATCH=${VERSION_PARTS[2]:-0} - - # Increment based on input - case "${{ github.event.inputs.version_bump }}" in - "major") - MAJOR=$((MAJOR + 1)) - MINOR=0 - PATCH=0 - ;; - "minor") - MINOR=$((MINOR + 1)) - PATCH=0 - ;; - "patch") - PATCH=$((PATCH + 1)) - ;; - esac - - NEW_VERSION="v$MAJOR.$MINOR.$PATCH" - echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT - echo "New version will be: $NEW_VERSION (was $LATEST_TAG)" - - - name: Create release package - run: | - # Create base package directory structure - mkdir -p sdd-package-base - - # Copy common folders to base - echo "Packaging SDD common components..." - - if [ -d "memory" ]; then - cp -r memory sdd-package-base/ - echo "✓ Copied memory folder ($(find memory -type f | wc -l) files)" - else - echo "⚠️ memory folder not found" - fi - - if [ -d "scripts" ]; then - cp -r scripts sdd-package-base/ - echo "✓ Copied scripts folder ($(find scripts -type f | wc -l) files)" - else - echo "⚠️ scripts folder not found" - fi - - # Create Claude Code package - echo "Creating Claude Code package..." - mkdir -p sdd-claude-package - cp -r sdd-package-base/* sdd-claude-package/ - if [ -d "agent_templates/claude" ]; then - cp -r agent_templates/claude sdd-claude-package/.claude - echo "✓ Added Claude Code commands ($(find agent_templates/claude -type f | wc -l) files)" - else - echo "⚠️ agent_templates/claude folder not found" - fi - - # Create Gemini CLI package - echo "Creating Gemini CLI package..." - mkdir -p sdd-gemini-package - cp -r sdd-package-base/* sdd-gemini-package/ - if [ -d "agent_templates/gemini" ]; then - cp -r agent_templates/gemini sdd-gemini-package/.gemini - # Move GEMINI.md to root for easier access - if [ -f "sdd-gemini-package/.gemini/GEMINI.md" ]; then - mv sdd-gemini-package/.gemini/GEMINI.md sdd-gemini-package/GEMINI.md - echo "✓ Moved GEMINI.md to root of Gemini package" - fi - # Remove empty .gemini folder if it only contained GEMINI.md - if [ -d "sdd-gemini-package/.gemini" ] && [ -z "$(find sdd-gemini-package/.gemini -type f)" ]; then - rm -rf sdd-gemini-package/.gemini - echo "✓ Removed empty .gemini folder" - fi - echo "✓ Added Gemini CLI commands ($(find agent_templates/gemini -type f | wc -l) files)" - else - echo "⚠️ agent_templates/gemini folder not found" - fi - - # Create GitHub Copilot package - echo "Creating GitHub Copilot package..." - mkdir -p sdd-copilot-package - cp -r sdd-package-base/* sdd-copilot-package/ - if [ -d "agent_templates/copilot" ]; then - mkdir -p sdd-copilot-package/.github - cp -r agent_templates/copilot/* sdd-copilot-package/.github/ - echo "✓ Added Copilot instructions to .github ($(find agent_templates/copilot -type f | wc -l) files)" - else - echo "⚠️ agent_templates/copilot folder not found" - fi - - # Create archive files for each package - echo "Creating archive files..." - cd sdd-claude-package && zip -r ../spec-kit-template-claude-${{ steps.version.outputs.new_version }}.zip . && cd .. - - cd sdd-gemini-package && zip -r ../spec-kit-template-gemini-${{ steps.version.outputs.new_version }}.zip . && cd .. - - cd sdd-copilot-package && zip -r ../spec-kit-template-copilot-${{ steps.version.outputs.new_version }}.zip . && cd .. - - echo "" - echo "📦 Packages created:" - echo "Claude: $(ls -lh spec-kit-template-claude-*.zip | awk '{print $5}')" - echo "Gemini: $(ls -lh spec-kit-template-gemini-*.zip | awk '{print $5}')" - echo "Copilot: $(ls -lh spec-kit-template-copilot-*.zip | awk '{print $5}')" - echo "Copilot: $(ls -lh sdd-template-copilot-*.zip | awk '{print $5}')" - - - name: Generate detailed release notes - run: | - LAST_TAG=${{ steps.version.outputs.latest_tag }} - - # Get commit range - if [ "$LAST_TAG" = "v0.0.0" ]; then - COMMIT_RANGE="HEAD~10..HEAD" - COMMITS=$(git log --oneline --pretty=format:"- %s" $COMMIT_RANGE 2>/dev/null || echo "- Initial release") - else - COMMIT_RANGE="$LAST_TAG..HEAD" - COMMITS=$(git log --oneline --pretty=format:"- %s" $COMMIT_RANGE 2>/dev/null || echo "- No changes since last release") - fi - - # Count files in each directory - CLAUDE_COUNT=$(find agent_templates/claude -type f 2>/dev/null | wc -l || echo "0") - GEMINI_COUNT=$(find agent_templates/gemini -type f 2>/dev/null | wc -l || echo "0") - COPILOT_COUNT=$(find agent_templates/copilot -type f 2>/dev/null | wc -l || echo "0") - MEMORY_COUNT=$(find memory -type f 2>/dev/null | wc -l || echo "0") - SCRIPTS_COUNT=$(find scripts -type f 2>/dev/null | wc -l || echo "0") - - cat > release_notes.md << EOF - Template release ${{ steps.version.outputs.new_version }} - - Updated specification-driven development templates for GitHub Copilot, Claude Code, and Gemini CLI. - - Download the template for your preferred AI assistant: - - spec-kit-template-copilot-${{ steps.version.outputs.new_version }}.zip - - spec-kit-template-claude-${{ steps.version.outputs.new_version }}.zip - - spec-kit-template-gemini-${{ steps.version.outputs.new_version }}.zip - - Changes since $LAST_TAG: - $COMMITS - EOF - - - name: Create GitHub Release - run: | - # Remove 'v' prefix from version for release title - VERSION_NO_V=${{ steps.version.outputs.new_version }} - VERSION_NO_V=${VERSION_NO_V#v} - - gh release create ${{ steps.version.outputs.new_version }} \ - spec-kit-template-copilot-${{ steps.version.outputs.new_version }}.zip \ - spec-kit-template-claude-${{ steps.version.outputs.new_version }}.zip \ - spec-kit-template-gemini-${{ steps.version.outputs.new_version }}.zip \ - --title "Spec Kit Templates - $VERSION_NO_V" \ - --notes-file release_notes.md - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index efa13f3..b2897d4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -61,94 +61,8 @@ jobs: - name: Create release package if: steps.check_release.outputs.exists == 'false' run: | - # Create base package directory structure - mkdir -p sdd-package-base - - # Copy common folders to base - if [ -d "memory" ]; then - cp -r memory sdd-package-base/ - echo "Copied memory folder" - fi - - if [ -d "scripts" ]; then - cp -r scripts sdd-package-base/ - echo "Copied scripts folder" - fi - - if [ -d "templates" ]; then - mkdir -p sdd-package-base/templates - # Copy templates folder but exclude the commands directory - find templates -type f -not -path "templates/commands/*" -exec cp --parents {} sdd-package-base/ \; - echo "Copied templates folder (excluding commands directory)" - fi - - # Generate command files for each agent from source templates - generate_commands() { - local agent=$1 - local ext=$2 - local arg_format=$3 - local output_dir=$4 - - mkdir -p "$output_dir" - - for template in templates/commands/*.md; do - if [[ -f "$template" ]]; then - name=$(basename "$template" .md) - description=$(awk '/^description:/ {gsub(/^description: *"?/, ""); gsub(/"$/, ""); print; exit}' "$template" | tr -d '\r') - content=$(awk '/^---$/{if(++count==2) start=1; next} start' "$template" | sed "s/{ARGS}/$arg_format/g") - case $ext in - "toml") - { echo "description = \"$description\""; echo ""; echo "prompt = \"\"\""; echo "$content"; echo "\"\"\""; } > "$output_dir/$name.$ext" ;; - "md") - echo "$content" > "$output_dir/$name.$ext" ;; - "prompt.md") - # Preserve original front matter + body with argument substitution for Copilot - # Simply copy the entire template, replacing {ARGS} - # This keeps YAML so tooling can parse metadata - sed "s/{ARGS}/$arg_format/g" "$template" > "$output_dir/$name.$ext" ;; - esac - fi - done - } - - # Create Claude Code package - mkdir -p sdd-claude-package - cp -r sdd-package-base/* sdd-claude-package/ - mkdir -p sdd-claude-package/.claude/commands - generate_commands "claude" "md" "\$ARGUMENTS" "sdd-claude-package/.claude/commands" - echo "Created Claude Code package" - - # Create Gemini CLI package - mkdir -p sdd-gemini-package - cp -r sdd-package-base/* sdd-gemini-package/ - mkdir -p sdd-gemini-package/.gemini/commands - generate_commands "gemini" "toml" "{{args}}" "sdd-gemini-package/.gemini/commands" - if [ -f "agent_templates/gemini/GEMINI.md" ]; then - cp agent_templates/gemini/GEMINI.md sdd-gemini-package/GEMINI.md - fi - echo "Created Gemini CLI package" - - # Create GitHub Copilot package - mkdir -p sdd-copilot-package - cp -r sdd-package-base/* sdd-copilot-package/ - mkdir -p sdd-copilot-package/.github/prompts - generate_commands "copilot" "prompt.md" "\$ARGUMENTS" "sdd-copilot-package/.github/prompts" - echo "Created GitHub Copilot package" - - # Create archive files for each package - cd sdd-claude-package && zip -r ../spec-kit-template-claude-${{ steps.get_tag.outputs.new_version }}.zip . && cd .. - - cd sdd-gemini-package && zip -r ../spec-kit-template-gemini-${{ steps.get_tag.outputs.new_version }}.zip . && cd .. - - cd sdd-copilot-package && zip -r ../spec-kit-template-copilot-${{ steps.get_tag.outputs.new_version }}.zip . && cd .. - - # List contents for verification - echo "Claude package contents:" - unzip -l spec-kit-template-claude-${{ steps.get_tag.outputs.new_version }}.zip | head -10 - echo "Gemini package contents:" - unzip -l spec-kit-template-gemini-${{ steps.get_tag.outputs.new_version }}.zip | head -10 - echo "Copilot package contents:" - unzip -l spec-kit-template-copilot-${{ steps.get_tag.outputs.new_version }}.zip | head -10 + chmod +x scripts/create-release-packages.sh + ./scripts/create-release-packages.sh ${{ steps.get_tag.outputs.new_version }} - name: Generate release notes if: steps.check_release.outputs.exists == 'false' diff --git a/scripts/create-release-packages.sh b/scripts/create-release-packages.sh new file mode 100644 index 0000000..9f1380f --- /dev/null +++ b/scripts/create-release-packages.sh @@ -0,0 +1,115 @@ +#!/usr/bin/env bash +set -euo pipefail + +# create-release-packages.sh +# Build Spec Kit template release archives for each supported AI assistant. +# Usage: ./scripts/create-release-packages.sh +# should include the leading 'v' (e.g. v0.0.4) + +if [[ $# -ne 1 ]]; then + echo "Usage: $0 " >&2 + exit 1 +fi + +NEW_VERSION="$1" +if [[ ! $NEW_VERSION =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Version must look like v0.0.0" >&2 + exit 1 +fi + +echo "Building release packages for $NEW_VERSION" + +# Clean any previous build dirs +rm -rf sdd-package-base sdd-claude-package sdd-gemini-package sdd-copilot-package \ + spec-kit-template-claude-${NEW_VERSION}.zip \ + spec-kit-template-gemini-${NEW_VERSION}.zip \ + spec-kit-template-copilot-${NEW_VERSION}.zip || true + +mkdir -p sdd-package-base + +# Copy common folders to base +if [[ -d memory ]]; then + cp -r memory sdd-package-base/ + echo "Copied memory folder" +fi + +if [[ -d scripts ]]; then + # Exclude this script itself from being copied + rsync -a --exclude 'create-release-packages.sh' scripts/ sdd-package-base/scripts/ + echo "Copied scripts folder (excluding create-release-packages.sh)" +fi + +if [[ -d templates ]]; then + mkdir -p sdd-package-base/templates + # Copy all template files excluding commands (processed separately per assistant) + find templates -type f -not -path "templates/commands/*" -exec cp --parents {} sdd-package-base/ \; + echo "Copied templates folder (excluding commands directory)" +fi + +# Function to generate assistant command files/prompts +# Args: agent ext arg_format output_dir +generate_commands() { + local agent=$1 + local ext=$2 + local arg_format=$3 + local output_dir=$4 + mkdir -p "$output_dir" + for template in templates/commands/*.md; do + [[ -f "$template" ]] || continue + local name + name=$(basename "$template" .md) + local description + description=$(awk '/^description:/ {gsub(/^description: *"?/, ""); gsub(/"$/, ""); print; exit}' "$template" | tr -d '\r') + local content + content=$(awk '/^---$/{if(++count==2) start=1; next} start' "$template" | sed "s/{ARGS}/$arg_format/g") + case $ext in + "toml") + { + echo "description = \"$description\""; echo ""; echo "prompt = \"\"\""; echo "$content"; echo "\"\"\""; + } > "$output_dir/$name.$ext" + ;; + "md") + echo "$content" > "$output_dir/$name.$ext" + ;; + "prompt.md") + # Preserve front matter exactly, just substitute {ARGS} + sed "s/{ARGS}/$arg_format/g" "$template" > "$output_dir/$name.$ext" + ;; + esac + done +} + +# Claude package +mkdir -p sdd-claude-package +cp -r sdd-package-base/* sdd-claude-package/ +mkdir -p sdd-claude-package/.claude/commands +generate_commands "claude" "md" "\$ARGUMENTS" "sdd-claude-package/.claude/commands" +echo "Created Claude Code package" + +# Gemini package +mkdir -p sdd-gemini-package +cp -r sdd-package-base/* sdd-gemini-package/ +mkdir -p sdd-gemini-package/.gemini/commands +generate_commands "gemini" "toml" "{{args}}" "sdd-gemini-package/.gemini/commands" +if [[ -f agent_templates/gemini/GEMINI.md ]]; then + cp agent_templates/gemini/GEMINI.md sdd-gemini-package/GEMINI.md +fi +echo "Created Gemini CLI package" + +# Copilot package +mkdir -p sdd-copilot-package +cp -r sdd-package-base/* sdd-copilot-package/ +mkdir -p sdd-copilot-package/.github/prompts +generate_commands "copilot" "prompt.md" "\$ARGUMENTS" "sdd-copilot-package/.github/prompts" +echo "Created GitHub Copilot package" + +# Archives +( cd sdd-claude-package && zip -r ../spec-kit-template-claude-${NEW_VERSION}.zip . ) +( cd sdd-gemini-package && zip -r ../spec-kit-template-gemini-${NEW_VERSION}.zip . ) +( cd sdd-copilot-package && zip -r ../spec-kit-template-copilot-${NEW_VERSION}.zip . ) + +echo "Package archives created:" +ls -1 spec-kit-template-*-${NEW_VERSION}.zip + +# Basic verification snippet +unzip -l spec-kit-template-copilot-${NEW_VERSION}.zip | head -10 || true