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 }}