Consolidate script creation
This commit is contained in:
191
.github/workflows/manual-release.yml
vendored
191
.github/workflows/manual-release.yml
vendored
@@ -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 }}
|
|
||||||
90
.github/workflows/release.yml
vendored
90
.github/workflows/release.yml
vendored
@@ -61,94 +61,8 @@ jobs:
|
|||||||
- name: Create release package
|
- name: Create release package
|
||||||
if: steps.check_release.outputs.exists == 'false'
|
if: steps.check_release.outputs.exists == 'false'
|
||||||
run: |
|
run: |
|
||||||
# Create base package directory structure
|
chmod +x scripts/create-release-packages.sh
|
||||||
mkdir -p sdd-package-base
|
./scripts/create-release-packages.sh ${{ steps.get_tag.outputs.new_version }}
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
- name: Generate release notes
|
- name: Generate release notes
|
||||||
if: steps.check_release.outputs.exists == 'false'
|
if: steps.check_release.outputs.exists == 'false'
|
||||||
|
|||||||
115
scripts/create-release-packages.sh
Normal file
115
scripts/create-release-packages.sh
Normal file
@@ -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 <version>
|
||||||
|
# <version> should include the leading 'v' (e.g. v0.0.4)
|
||||||
|
|
||||||
|
if [[ $# -ne 1 ]]; then
|
||||||
|
echo "Usage: $0 <version-with-v-prefix>" >&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
|
||||||
Reference in New Issue
Block a user