Skip to content

Commit 28c983c

Browse files
authored
Merge pull request #46 from commjoen/copilot/fix-45
Add release workflow for creating semver tags and GitHub releases
2 parents 96cbb12 + a356a8f commit 28c983c

4 files changed

Lines changed: 320 additions & 1 deletion

File tree

.github/workflows/release.yml

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
name: Create Release
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
version_type:
7+
description: 'Version bump type'
8+
required: true
9+
default: 'patch'
10+
type: choice
11+
options:
12+
- patch
13+
- minor
14+
- major
15+
custom_version:
16+
description: 'Custom version (optional, overrides version_type if provided)'
17+
required: false
18+
type: string
19+
prerelease:
20+
description: 'Mark as pre-release'
21+
required: false
22+
default: false
23+
type: boolean
24+
25+
permissions:
26+
contents: write
27+
pull-requests: read
28+
29+
jobs:
30+
create-release:
31+
runs-on: ubuntu-latest
32+
33+
steps:
34+
- name: Check authorized user
35+
run: |
36+
if [ "${{ github.actor }}" != "commjoen" ]; then
37+
echo "❌ Unauthorized user: ${{ github.actor }}"
38+
echo "This workflow can only be triggered by @commjoen"
39+
exit 1
40+
fi
41+
echo "✅ Authorized user: ${{ github.actor }}"
42+
43+
- name: Checkout repository
44+
uses: actions/checkout@v4
45+
with:
46+
fetch-depth: 0
47+
token: ${{ secrets.GITHUB_TOKEN }}
48+
49+
- name: Setup Node.js
50+
uses: actions/setup-node@v4
51+
with:
52+
node-version: '22'
53+
cache: 'npm'
54+
55+
- name: Install dependencies
56+
run: npm ci
57+
58+
- name: Run tests
59+
run: npm test
60+
61+
- name: Run build
62+
run: npm run build
63+
64+
- name: Configure Git
65+
run: |
66+
git config user.name "github-actions[bot]"
67+
git config user.email "github-actions[bot]@users.noreply.github.com"
68+
69+
- name: Get current version
70+
id: current_version
71+
run: |
72+
CURRENT_VERSION=$(node -p "require('./package.json').version")
73+
echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
74+
echo "Current version: $CURRENT_VERSION"
75+
76+
- name: Calculate new version
77+
id: new_version
78+
run: |
79+
CURRENT_VERSION="${{ steps.current_version.outputs.version }}"
80+
CUSTOM_VERSION="${{ github.event.inputs.custom_version }}"
81+
VERSION_TYPE="${{ github.event.inputs.version_type }}"
82+
83+
if [ -n "$CUSTOM_VERSION" ]; then
84+
# Use custom version if provided
85+
NEW_VERSION="$CUSTOM_VERSION"
86+
echo "Using custom version: $NEW_VERSION"
87+
else
88+
# Calculate semantic version bump
89+
IFS='.' read -ra VERSION_PARTS <<< "$CURRENT_VERSION"
90+
MAJOR=${VERSION_PARTS[0]}
91+
MINOR=${VERSION_PARTS[1]}
92+
PATCH=${VERSION_PARTS[2]}
93+
94+
case "$VERSION_TYPE" in
95+
"major")
96+
MAJOR=$((MAJOR + 1))
97+
MINOR=0
98+
PATCH=0
99+
;;
100+
"minor")
101+
MINOR=$((MINOR + 1))
102+
PATCH=0
103+
;;
104+
"patch")
105+
PATCH=$((PATCH + 1))
106+
;;
107+
esac
108+
109+
NEW_VERSION="$MAJOR.$MINOR.$PATCH"
110+
echo "Calculated $VERSION_TYPE version bump: $NEW_VERSION"
111+
fi
112+
113+
echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT
114+
echo "New version will be: $NEW_VERSION"
115+
116+
- name: Update package.json version
117+
run: |
118+
NEW_VERSION="${{ steps.new_version.outputs.version }}"
119+
npm version "$NEW_VERSION" --no-git-tag-version
120+
echo "Updated package.json to version $NEW_VERSION"
121+
122+
- name: Commit version update
123+
run: |
124+
NEW_VERSION="${{ steps.new_version.outputs.version }}"
125+
git add package.json package-lock.json
126+
git commit -m "bump version to $NEW_VERSION"
127+
echo "Committed version update"
128+
129+
- name: Create and push tag
130+
run: |
131+
NEW_VERSION="${{ steps.new_version.outputs.version }}"
132+
TAG_NAME="v$NEW_VERSION"
133+
git tag -a "$TAG_NAME" -m "Release $TAG_NAME"
134+
git push origin "$TAG_NAME"
135+
git push origin main
136+
echo "Created and pushed tag: $TAG_NAME"
137+
138+
- name: Generate release notes
139+
id: release_notes
140+
run: |
141+
NEW_VERSION="${{ steps.new_version.outputs.version }}"
142+
TAG_NAME="v$NEW_VERSION"
143+
144+
# Get the previous tag (if any)
145+
PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD~1 2>/dev/null || echo "")
146+
147+
if [ -z "$PREVIOUS_TAG" ]; then
148+
echo "## What's New in $TAG_NAME" > release_notes.md
149+
echo "" >> release_notes.md
150+
echo "This is the first tagged release of the Generated Game Experiment!" >> release_notes.md
151+
echo "" >> release_notes.md
152+
echo "### 🎮 Features" >> release_notes.md
153+
echo "- Browser-based side-scrolling platformer game" >> release_notes.md
154+
echo "- Procedural level generation" >> release_notes.md
155+
echo "- Collectibles and power-ups system" >> release_notes.md
156+
echo "- Optional multiplayer support via WebSocket" >> release_notes.md
157+
echo "- Real-time leaderboard" >> release_notes.md
158+
echo "- Mobile-friendly controls" >> release_notes.md
159+
echo "- Docker containerization for easy deployment" >> release_notes.md
160+
echo "" >> release_notes.md
161+
echo "### 🚀 Deployment" >> release_notes.md
162+
echo "- **Play Online:** [GitHub Pages](https://commjoen.github.io/generated-game-experiment/) (Singleplayer)" >> release_notes.md
163+
echo "- **Play Multiplayer:** [Render](https://generated-game-experiment.onrender.com/)" >> release_notes.md
164+
echo "- **Docker:** \`docker pull ghcr.io/commjoen/generated-game-experiment:$NEW_VERSION\`" >> release_notes.md
165+
else
166+
echo "## What's Changed in $TAG_NAME" > release_notes.md
167+
echo "" >> release_notes.md
168+
echo "### 📋 Commits since $PREVIOUS_TAG" >> release_notes.md
169+
git log "$PREVIOUS_TAG..HEAD" --pretty=format:"- %s (%h)" >> release_notes.md
170+
fi
171+
172+
echo "" >> release_notes.md
173+
echo "### 🔧 Technical Details" >> release_notes.md
174+
echo "- **Version:** $NEW_VERSION" >> release_notes.md
175+
echo "- **Node.js:** $(node --version)" >> release_notes.md
176+
echo "- **Built:** $(date -u +"%Y-%m-%d %H:%M:%S UTC")" >> release_notes.md
177+
echo "- **Commit:** ${{ github.sha }}" >> release_notes.md
178+
179+
# Store the release notes content
180+
{
181+
echo 'notes<<EOF'
182+
cat release_notes.md
183+
echo EOF
184+
} >> $GITHUB_OUTPUT
185+
186+
- name: Create GitHub Release
187+
env:
188+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
189+
run: |
190+
NEW_VERSION="${{ steps.new_version.outputs.version }}"
191+
TAG_NAME="v$NEW_VERSION"
192+
PRERELEASE_FLAG=""
193+
194+
if [ "${{ github.event.inputs.prerelease }}" = "true" ]; then
195+
PRERELEASE_FLAG="--prerelease"
196+
fi
197+
198+
gh release create "$TAG_NAME" \
199+
--title "Release $TAG_NAME" \
200+
--notes-file release_notes.md \
201+
$PRERELEASE_FLAG
202+
203+
- name: Generate summary
204+
run: |
205+
NEW_VERSION="${{ steps.new_version.outputs.version }}"
206+
TAG_NAME="v$NEW_VERSION"
207+
208+
echo "## 🎉 Release Created Successfully!" >> $GITHUB_STEP_SUMMARY
209+
echo "" >> $GITHUB_STEP_SUMMARY
210+
echo "**Version:** \`$NEW_VERSION\`" >> $GITHUB_STEP_SUMMARY
211+
echo "**Tag:** \`$TAG_NAME\`" >> $GITHUB_STEP_SUMMARY
212+
echo "**Pre-release:** ${{ github.event.inputs.prerelease }}" >> $GITHUB_STEP_SUMMARY
213+
echo "" >> $GITHUB_STEP_SUMMARY
214+
echo "### 🔗 Links" >> $GITHUB_STEP_SUMMARY
215+
echo "- [Release Page](https://github.com/${{ github.repository }}/releases/tag/$TAG_NAME)" >> $GITHUB_STEP_SUMMARY
216+
echo "- [Docker Image](https://ghcr.io/${{ github.repository }}:$NEW_VERSION)" >> $GITHUB_STEP_SUMMARY
217+
echo "" >> $GITHUB_STEP_SUMMARY
218+
echo "### 🚀 Docker Usage" >> $GITHUB_STEP_SUMMARY
219+
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
220+
echo "docker pull ghcr.io/${{ github.repository }}:$NEW_VERSION" >> $GITHUB_STEP_SUMMARY
221+
echo "docker run -p 8080:80 -p 3001:3001 ghcr.io/${{ github.repository }}:$NEW_VERSION" >> $GITHUB_STEP_SUMMARY
222+
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
223+
echo "" >> $GITHUB_STEP_SUMMARY
224+
echo "### ⚡ What happens next" >> $GITHUB_STEP_SUMMARY
225+
echo "- Docker images will be built automatically via existing workflows" >> $GITHUB_STEP_SUMMARY
226+
echo "- Release will be available on GitHub Releases page" >> $GITHUB_STEP_SUMMARY
227+
echo "- Docker Hub release (if configured) will be triggered" >> $GITHUB_STEP_SUMMARY

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
[![Test](https://github.com/commjoen/generated-game-experiment/actions/workflows/test.yml/badge.svg)](https://github.com/commjoen/generated-game-experiment/actions/workflows/test.yml)
44
[![Deploy to GitHub Pages](https://github.com/commjoen/generated-game-experiment/actions/workflows/deploy.yml/badge.svg)](https://github.com/commjoen/generated-game-experiment/actions/workflows/deploy.yml)
55
[![Docker Build and Release](https://github.com/commjoen/generated-game-experiment/actions/workflows/docker-release.yml/badge.svg)](https://github.com/commjoen/generated-game-experiment/actions/workflows/docker-release.yml)
6+
[![Create Release](https://github.com/commjoen/generated-game-experiment/actions/workflows/release.yml/badge.svg)](https://github.com/commjoen/generated-game-experiment/actions/workflows/release.yml)
67

78
<!-- Project Status -->
89
[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)

dist/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@
122122
pointer-events: auto;
123123
}
124124
</style>
125-
<script type="module" crossorigin="" src="/assets/index-C5PRTwdf.js" integrity="sha384-eN4SGVQBXOf4tlbMQMdJMmNp4NGw+JAu4WrsYzKn10CI6V66BcWeBYTF970Wq52/"></script>
125+
<script type="module" crossorigin="" src="/assets/index-B0Gq0q3G.js" integrity="sha384-zyyWlskqe3IyNWZbEF2zSYXhWsks3KOatwCyvUvp8qSJFLTIi6XPIuvbyKvKipXj"></script>
126126
</head>
127127
<body>
128128
<main id="main-content" role="main" tabindex="-1">

docs/RELEASE.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# Release Workflow Guide
2+
3+
This document explains how to use the release workflow to create tagged releases of the Generated Game Experiment.
4+
5+
## 🚀 How to Create a Release
6+
7+
The release workflow can only be triggered manually by @commjoen. The workflow has built-in security to prevent unauthorized access.
8+
9+
### Steps to Create a Release
10+
11+
1. **Navigate to Actions**
12+
- Go to the [Actions tab](https://github.com/commjoen/generated-game-experiment/actions)
13+
- Select "Create Release" workflow
14+
15+
2. **Trigger the Workflow**
16+
- Click "Run workflow"
17+
- Choose your options:
18+
- **Version bump type**: `patch`, `minor`, or `major`
19+
- **Custom version** (optional): Override automatic calculation
20+
- **Pre-release**: Mark as pre-release if needed
21+
22+
3. **Version Bump Guide**
23+
- **Patch** (e.g., 0.2.1 → 0.2.2): Bug fixes, small improvements
24+
- **Minor** (e.g., 0.2.1 → 0.3.0): New features, backwards compatible
25+
- **Major** (e.g., 0.2.1 → 1.0.0): Breaking changes, major rewrites
26+
27+
## ✨ What the Workflow Does
28+
29+
1. **Validation**
30+
- Runs all tests to ensure code quality
31+
- Builds the project to verify everything works
32+
33+
2. **Version Management**
34+
- Calculates the new version based on your selection
35+
- Updates `package.json` with the new version
36+
- Commits the version change
37+
38+
3. **Release Creation**
39+
- Creates a semantic version Git tag (e.g., `v0.2.2`)
40+
- Generates release notes automatically
41+
- Creates a GitHub Release with the notes
42+
43+
4. **Automation Triggers**
44+
- Existing Docker workflows will automatically build and publish images
45+
- Docker Hub release (if configured) will be triggered
46+
47+
## 📋 Release Notes
48+
49+
Release notes are generated automatically and include:
50+
- **First Release**: Feature overview and deployment information
51+
- **Subsequent Releases**: List of commits since the last tag
52+
- **Technical Details**: Version, build info, and commit hash
53+
54+
## 🔒 Security & Access
55+
56+
- **Restricted Access**: Only @commjoen can trigger this workflow
57+
- The workflow validates the user before proceeding
58+
- Requires `workflow_dispatch` permissions in GitHub Actions
59+
- All changes are committed with the official GitHub Actions bot
60+
61+
## 🐳 Docker Images
62+
63+
After a successful release, Docker images will be available at:
64+
- **GitHub Container Registry**: `ghcr.io/commjoen/generated-game-experiment:v<version>`
65+
- **Docker Hub** (if configured): `<username>/platformer-game:v<version>`
66+
67+
## 🎮 Deployment
68+
69+
Released versions are automatically deployed to:
70+
- **GitHub Pages**: [commjoen.github.io/generated-game-experiment](https://commjoen.github.io/generated-game-experiment/)
71+
- **Render**: [generated-game-experiment.onrender.com](https://generated-game-experiment.onrender.com/)
72+
73+
## 📝 Example Usage
74+
75+
```bash
76+
# Run the latest release
77+
docker pull ghcr.io/commjoen/generated-game-experiment:latest
78+
docker run -p 8080:80 -p 3001:3001 ghcr.io/commjoen/generated-game-experiment:latest
79+
80+
# Run a specific version
81+
docker pull ghcr.io/commjoen/generated-game-experiment:v0.2.2
82+
docker run -p 8080:80 -p 3001:3001 ghcr.io/commjoen/generated-game-experiment:v0.2.2
83+
```
84+
85+
## 🛠️ Troubleshooting
86+
87+
If the workflow fails:
88+
1. Check the workflow logs for specific error messages
89+
2. Ensure all tests are passing on the main branch
90+
3. Verify the version format is correct (if using custom version)
91+
4. Contact @commjoen for repository-specific issues

0 commit comments

Comments
 (0)