222 lines
8.7 KiB
YAML
222 lines
8.7 KiB
YAML
name: Create Release
|
|
|
|
on:
|
|
push:
|
|
branches: [ main ]
|
|
workflow_dispatch:
|
|
|
|
jobs:
|
|
release:
|
|
runs-on: ubuntu-latest
|
|
|
|
permissions:
|
|
contents: write
|
|
pull-requests: write
|
|
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Get latest tag
|
|
id: get_tag
|
|
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 and increment
|
|
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 patch version
|
|
PATCH=$((PATCH + 1))
|
|
NEW_VERSION="v$MAJOR.$MINOR.$PATCH"
|
|
|
|
echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
|
|
echo "New version will be: $NEW_VERSION"
|
|
|
|
- name: Check if release already exists
|
|
id: check_release
|
|
run: |
|
|
if gh release view ${{ steps.get_tag.outputs.new_version }} >/dev/null 2>&1; then
|
|
echo "exists=true" >> $GITHUB_OUTPUT
|
|
echo "Release ${{ steps.get_tag.outputs.new_version }} already exists, skipping..."
|
|
else
|
|
echo "exists=false" >> $GITHUB_OUTPUT
|
|
echo "Release ${{ steps.get_tag.outputs.new_version }} does not exist, proceeding..."
|
|
fi
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- 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")
|
|
{
|
|
echo "# $(echo "$description" | sed 's/\. .*//')"
|
|
echo ""
|
|
echo "$content"
|
|
} > "$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
|
|
if: steps.check_release.outputs.exists == 'false'
|
|
id: release_notes
|
|
run: |
|
|
# Get commits since last tag
|
|
LAST_TAG=${{ steps.get_tag.outputs.latest_tag }}
|
|
if [ "$LAST_TAG" = "v0.0.0" ]; then
|
|
# Check how many commits we have and use that as the limit
|
|
COMMIT_COUNT=$(git rev-list --count HEAD)
|
|
if [ "$COMMIT_COUNT" -gt 10 ]; then
|
|
COMMITS=$(git log --oneline --pretty=format:"- %s" HEAD~10..HEAD)
|
|
else
|
|
COMMITS=$(git log --oneline --pretty=format:"- %s" HEAD~$COMMIT_COUNT..HEAD 2>/dev/null || git log --oneline --pretty=format:"- %s")
|
|
fi
|
|
else
|
|
COMMITS=$(git log --oneline --pretty=format:"- %s" $LAST_TAG..HEAD)
|
|
fi
|
|
|
|
# Create release notes
|
|
cat > release_notes.md << EOF
|
|
Template release ${{ steps.get_tag.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.get_tag.outputs.new_version }}.zip
|
|
- spec-kit-template-claude-${{ steps.get_tag.outputs.new_version }}.zip
|
|
- spec-kit-template-gemini-${{ steps.get_tag.outputs.new_version }}.zip
|
|
EOF
|
|
|
|
echo "Generated release notes:"
|
|
cat release_notes.md
|
|
|
|
- name: Create GitHub Release
|
|
if: steps.check_release.outputs.exists == 'false'
|
|
run: |
|
|
# Remove 'v' prefix from version for release title
|
|
VERSION_NO_V=${{ steps.get_tag.outputs.new_version }}
|
|
VERSION_NO_V=${VERSION_NO_V#v}
|
|
|
|
gh release create ${{ steps.get_tag.outputs.new_version }} \
|
|
spec-kit-template-copilot-${{ steps.get_tag.outputs.new_version }}.zip \
|
|
spec-kit-template-claude-${{ steps.get_tag.outputs.new_version }}.zip \
|
|
spec-kit-template-gemini-${{ steps.get_tag.outputs.new_version }}.zip \
|
|
--title "Spec Kit Templates - $VERSION_NO_V" \
|
|
--notes-file release_notes.md
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Update version in pyproject.toml (for release artifacts only)
|
|
if: steps.check_release.outputs.exists == 'false'
|
|
run: |
|
|
# Update version in pyproject.toml (remove 'v' prefix for Python versioning)
|
|
VERSION=${{ steps.get_tag.outputs.new_version }}
|
|
PYTHON_VERSION=${VERSION#v}
|
|
|
|
if [ -f "pyproject.toml" ]; then
|
|
sed -i "s/version = \".*\"/version = \"$PYTHON_VERSION\"/" pyproject.toml
|
|
echo "Updated pyproject.toml version to $PYTHON_VERSION (for release artifacts only)"
|
|
fi
|
|
|
|
# Note: No longer committing version changes back to main branch
|
|
# The version is only updated in the release artifacts
|