Merge pull request #48 from commjoen/copilot/fix-47 #4
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Create Release | ||
| # Note: If this workflow fails due to branch protection or rulesets, | ||
| # create a Personal Access Token (PAT) with 'Contents: Write' and 'Metadata: Read' permissions | ||
| # and add it as a secret named PAT_TOKEN to bypass branch protection rules. | ||
| on: | ||
| workflow_dispatch: | ||
| inputs: | ||
| version_type: | ||
| description: 'Version bump type' | ||
| required: true | ||
| default: 'patch' | ||
| type: choice | ||
| options: | ||
| - patch | ||
| - minor | ||
| - major | ||
| custom_version: | ||
| description: 'Custom version (optional, overrides version_type if provided)' | ||
| required: false | ||
| type: string | ||
| prerelease: | ||
| description: 'Mark as pre-release' | ||
| required: false | ||
| default: false | ||
| type: boolean | ||
| permissions: | ||
| contents: write | ||
| pull-requests: read | ||
| actions: read | ||
| metadata: read | ||
| id-token: write | ||
| jobs: | ||
| create-release: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Check authorized user | ||
| run: | | ||
| if [ "${{ github.actor }}" != "commjoen" ]; then | ||
| echo "❌ Unauthorized user: ${{ github.actor }}" | ||
| echo "This workflow can only be triggered by @commjoen" | ||
| exit 1 | ||
| fi | ||
| echo "✅ Authorized user: ${{ github.actor }}" | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
| # Use PAT_TOKEN if available for bypassing branch protection, fallback to GITHUB_TOKEN | ||
| token: ${{ secrets.PAT_TOKEN || secrets.GITHUB_TOKEN }} | ||
| persist-credentials: true | ||
| - name: Setup Node.js | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: '22' | ||
| cache: 'npm' | ||
| - name: Install dependencies | ||
| run: npm ci | ||
| - name: Run tests | ||
| run: npm test | ||
| - name: Run build | ||
| run: npm run build | ||
| - name: Configure Git | ||
| run: | | ||
| git config user.name "github-actions[bot]" | ||
| git config user.email "github-actions[bot]@users.noreply.github.com" | ||
| git config --global init.defaultBranch main | ||
| - name: Get current version | ||
| id: current_version | ||
| run: | | ||
| CURRENT_VERSION=$(node -p "require('./package.json').version") | ||
| echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT | ||
| echo "Current version: $CURRENT_VERSION" | ||
| - name: Calculate new version | ||
| id: new_version | ||
| run: | | ||
| CURRENT_VERSION="${{ steps.current_version.outputs.version }}" | ||
| CUSTOM_VERSION="${{ github.event.inputs.custom_version }}" | ||
| VERSION_TYPE="${{ github.event.inputs.version_type }}" | ||
| if [ -n "$CUSTOM_VERSION" ]; then | ||
| # Use custom version if provided | ||
| NEW_VERSION="$CUSTOM_VERSION" | ||
| echo "Using custom version: $NEW_VERSION" | ||
| else | ||
| # Calculate semantic version bump | ||
| IFS='.' read -ra VERSION_PARTS <<< "$CURRENT_VERSION" | ||
| MAJOR=${VERSION_PARTS[0]} | ||
| MINOR=${VERSION_PARTS[1]} | ||
| PATCH=${VERSION_PARTS[2]} | ||
| case "$VERSION_TYPE" in | ||
| "major") | ||
| MAJOR=$((MAJOR + 1)) | ||
| MINOR=0 | ||
| PATCH=0 | ||
| ;; | ||
| "minor") | ||
| MINOR=$((MINOR + 1)) | ||
| PATCH=0 | ||
| ;; | ||
| "patch") | ||
| PATCH=$((PATCH + 1)) | ||
| ;; | ||
| esac | ||
| NEW_VERSION="$MAJOR.$MINOR.$PATCH" | ||
| echo "Calculated $VERSION_TYPE version bump: $NEW_VERSION" | ||
| fi | ||
| echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT | ||
| echo "New version will be: $NEW_VERSION" | ||
| - name: Update package.json version | ||
| run: | | ||
| NEW_VERSION="${{ steps.new_version.outputs.version }}" | ||
| npm version "$NEW_VERSION" --no-git-tag-version | ||
| echo "Updated package.json to version $NEW_VERSION" | ||
| - name: Commit version update | ||
| run: | | ||
| NEW_VERSION="${{ steps.new_version.outputs.version }}" | ||
| git add package.json package-lock.json | ||
| git commit -m "bump version to $NEW_VERSION" | ||
| echo "Committed version update" | ||
| - name: Create and push tag | ||
| env: | ||
| GITHUB_TOKEN: ${{ secrets.PAT_TOKEN || secrets.GITHUB_TOKEN }} | ||
| run: | | ||
| NEW_VERSION="${{ steps.new_version.outputs.version }}" | ||
| TAG_NAME="v$NEW_VERSION" | ||
| # Configure git to use the token for authentication | ||
| git remote set-url origin https://x-access-token:${GITHUB_TOKEN}@github.com/${{ github.repository }}.git | ||
| git tag -a "$TAG_NAME" -m "Release $TAG_NAME" | ||
| git push origin "$TAG_NAME" | ||
| git push origin main | ||
| echo "Created and pushed tag: $TAG_NAME" | ||
| - name: Generate release notes | ||
| id: release_notes | ||
| run: | | ||
| NEW_VERSION="${{ steps.new_version.outputs.version }}" | ||
| TAG_NAME="v$NEW_VERSION" | ||
| # Get the previous tag (if any) | ||
| PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD~1 2>/dev/null || echo "") | ||
| if [ -z "$PREVIOUS_TAG" ]; then | ||
| echo "## What's New in $TAG_NAME" > release_notes.md | ||
| echo "" >> release_notes.md | ||
| echo "This is the first tagged release of the Generated Game Experiment!" >> release_notes.md | ||
| echo "" >> release_notes.md | ||
| echo "### 🎮 Features" >> release_notes.md | ||
| echo "- Browser-based side-scrolling platformer game" >> release_notes.md | ||
| echo "- Procedural level generation" >> release_notes.md | ||
| echo "- Collectibles and power-ups system" >> release_notes.md | ||
| echo "- Optional multiplayer support via WebSocket" >> release_notes.md | ||
| echo "- Real-time leaderboard" >> release_notes.md | ||
| echo "- Mobile-friendly controls" >> release_notes.md | ||
| echo "- Docker containerization for easy deployment" >> release_notes.md | ||
| echo "" >> release_notes.md | ||
| echo "### 🚀 Deployment" >> release_notes.md | ||
| echo "- **Play Online:** [GitHub Pages](https://commjoen.github.io/generated-game-experiment/) (Singleplayer)" >> release_notes.md | ||
| echo "- **Play Multiplayer:** [Render](https://generated-game-experiment.onrender.com/)" >> release_notes.md | ||
| echo "- **Docker:** \`docker pull ghcr.io/commjoen/generated-game-experiment:$NEW_VERSION\`" >> release_notes.md | ||
| else | ||
| echo "## What's Changed in $TAG_NAME" > release_notes.md | ||
| echo "" >> release_notes.md | ||
| echo "### 📋 Commits since $PREVIOUS_TAG" >> release_notes.md | ||
| git log "$PREVIOUS_TAG..HEAD" --pretty=format:"- %s (%h)" >> release_notes.md | ||
| fi | ||
| echo "" >> release_notes.md | ||
| echo "### 🔧 Technical Details" >> release_notes.md | ||
| echo "- **Version:** $NEW_VERSION" >> release_notes.md | ||
| echo "- **Node.js:** $(node --version)" >> release_notes.md | ||
| echo "- **Built:** $(date -u +"%Y-%m-%d %H:%M:%S UTC")" >> release_notes.md | ||
| echo "- **Commit:** ${{ github.sha }}" >> release_notes.md | ||
| # Store the release notes content | ||
| { | ||
| echo 'notes<<EOF' | ||
| cat release_notes.md | ||
| echo EOF | ||
| } >> $GITHUB_OUTPUT | ||
| - name: Create GitHub Release | ||
| env: | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| run: | | ||
| NEW_VERSION="${{ steps.new_version.outputs.version }}" | ||
| TAG_NAME="v$NEW_VERSION" | ||
| PRERELEASE_FLAG="" | ||
| if [ "${{ github.event.inputs.prerelease }}" = "true" ]; then | ||
| PRERELEASE_FLAG="--prerelease" | ||
| fi | ||
| gh release create "$TAG_NAME" \ | ||
| --title "Release $TAG_NAME" \ | ||
| --notes-file release_notes.md \ | ||
| $PRERELEASE_FLAG | ||
| - name: Generate summary | ||
| run: | | ||
| NEW_VERSION="${{ steps.new_version.outputs.version }}" | ||
| TAG_NAME="v$NEW_VERSION" | ||
| echo "## 🎉 Release Created Successfully!" >> $GITHUB_STEP_SUMMARY | ||
| echo "" >> $GITHUB_STEP_SUMMARY | ||
| echo "**Version:** \`$NEW_VERSION\`" >> $GITHUB_STEP_SUMMARY | ||
| echo "**Tag:** \`$TAG_NAME\`" >> $GITHUB_STEP_SUMMARY | ||
| echo "**Pre-release:** ${{ github.event.inputs.prerelease }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "" >> $GITHUB_STEP_SUMMARY | ||
| echo "### 🔗 Links" >> $GITHUB_STEP_SUMMARY | ||
| echo "- [Release Page](https://github.com/${{ github.repository }}/releases/tag/$TAG_NAME)" >> $GITHUB_STEP_SUMMARY | ||
| echo "- [Docker Image](https://ghcr.io/${{ github.repository }}:$NEW_VERSION)" >> $GITHUB_STEP_SUMMARY | ||
| echo "" >> $GITHUB_STEP_SUMMARY | ||
| echo "### 🚀 Docker Usage" >> $GITHUB_STEP_SUMMARY | ||
| echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY | ||
| echo "docker pull ghcr.io/${{ github.repository }}:$NEW_VERSION" >> $GITHUB_STEP_SUMMARY | ||
| echo "docker run -p 8080:80 -p 3001:3001 ghcr.io/${{ github.repository }}:$NEW_VERSION" >> $GITHUB_STEP_SUMMARY | ||
| echo "\`\`\`" >> $GITHUB_STEP_SUMMARY | ||
| echo "" >> $GITHUB_STEP_SUMMARY | ||
| echo "### ⚡ What happens next" >> $GITHUB_STEP_SUMMARY | ||
| echo "- Docker images will be built automatically via existing workflows" >> $GITHUB_STEP_SUMMARY | ||
| echo "- Release will be available on GitHub Releases page" >> $GITHUB_STEP_SUMMARY | ||
| echo "- Docker Hub release (if configured) will be triggered" >> $GITHUB_STEP_SUMMARY | ||