Feature/UI clean up 2026 01 05 (#36) #6
Workflow file for this run
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 and Deploy | |
| on: | |
| push: | |
| tags: | |
| - 'v*' # Triggers on version tags like v0.1.0, v1.0.0, etc. | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: 'Version to release (e.g., 0.1.0)' | |
| required: true | |
| type: string | |
| tag: | |
| description: 'Tag name (e.g., v0.1.0). If empty, will use v{version}' | |
| required: false | |
| type: string | |
| permissions: | |
| contents: write | |
| pages: write | |
| id-token: write | |
| jobs: | |
| release: | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: github-pages | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 # Fetch all history for changelog generation | |
| - name: Extract version from tag | |
| id: tag_version | |
| run: | | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| # Manual trigger - use inputs | |
| VERSION="${{ inputs.version }}" | |
| TAG_NAME="${{ inputs.tag }}" | |
| if [ -z "$TAG_NAME" ]; then | |
| TAG_NAME="v$VERSION" | |
| fi | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT | |
| echo "π¦ Creating release for version: $VERSION (tag: $TAG_NAME) [Manual Trigger]" | |
| else | |
| # Automatic trigger from tag push | |
| VERSION=${GITHUB_REF#refs/tags/v} | |
| TAG_NAME=${GITHUB_REF#refs/tags/} | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT | |
| echo "π¦ Creating release for version: $VERSION (tag: $TAG_NAME) [Tag Push]" | |
| fi | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v4 | |
| with: | |
| version: 10.17.0 | |
| - name: Get pnpm store directory | |
| shell: bash | |
| run: | | |
| echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV | |
| - name: Setup pnpm cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: ${{ env.STORE_PATH }} | |
| key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-pnpm-store- | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Run type check | |
| run: pnpm type-check | |
| - name: Run linting | |
| run: pnpm lint | |
| - name: Run tests | |
| run: pnpm test:ci | |
| - name: Build application | |
| run: pnpm build | |
| env: | |
| NEXT_PUBLIC_APP_VERSION: ${{ steps.tag_version.outputs.version }} | |
| - name: Verify build output | |
| run: | | |
| if [ ! -d "out" ]; then | |
| echo "β Build output directory 'out' not found!" | |
| exit 1 | |
| fi | |
| if [ ! -f "out/index.html" ]; then | |
| echo "β Main index.html not found in build output!" | |
| exit 1 | |
| fi | |
| if [ ! -d "out/tools" ]; then | |
| echo "β Tools directory not found in build output!" | |
| exit 1 | |
| fi | |
| echo "β Build output verification passed" | |
| - name: Test static file serving | |
| run: | | |
| python3 -m http.server 8080 --directory out & | |
| SERVER_PID=$! | |
| sleep 3 | |
| if curl -s -o /dev/null -w "%{http_code}" http://localhost:8080 | grep -q "200"; then | |
| echo "β Static file serving test passed" | |
| else | |
| echo "β Static file serving test failed" | |
| exit 1 | |
| fi | |
| kill $SERVER_PID 2>/dev/null || true | |
| - name: Generate release notes from CHANGELOG | |
| id: release_notes | |
| run: | | |
| VERSION="${{ steps.tag_version.outputs.version }}" | |
| if [ -f "CHANGELOG.md" ]; then | |
| # Extract content between [version] and next version or end of file | |
| awk "/^## \[$VERSION\]/,/^## \[/ {if (!/^## \[$VERSION\]/ && !/^## \[/) print}" CHANGELOG.md > /tmp/release_notes.md || true | |
| # If no content found, use a default message | |
| if [ ! -s /tmp/release_notes.md ]; then | |
| echo "## Release $VERSION" > /tmp/release_notes.md | |
| echo "" >> /tmp/release_notes.md | |
| echo "See [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/main/CHANGELOG.md) for details." >> /tmp/release_notes.md | |
| fi | |
| # Build release body | |
| { | |
| echo "## π Release $VERSION" | |
| echo "" | |
| cat /tmp/release_notes.md | |
| echo "" | |
| echo "---" | |
| echo "" | |
| # Get the previous tag for comparison | |
| PREV_TAG=$(git describe --tags --abbrev=0 "${{ steps.tag_version.outputs.tag_name }}^" 2>/dev/null || echo "") | |
| if [ -n "$PREV_TAG" ]; then | |
| echo "**Full Changelog**: https://github.com/${{ github.repository }}/compare/$PREV_TAG...${{ steps.tag_version.outputs.tag_name }}" | |
| else | |
| echo "**Full Changelog**: https://github.com/${{ github.repository }}/releases/tag/${{ steps.tag_version.outputs.tag_name }}" | |
| fi | |
| } > /tmp/release_body.md | |
| else | |
| { | |
| echo "## π Release $VERSION" | |
| echo "" | |
| echo "**Full Changelog**: https://github.com/${{ github.repository }}/commits/${{ steps.tag_version.outputs.tag_name }}" | |
| } > /tmp/release_body.md | |
| fi | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| name: Release ${{ steps.tag_version.outputs.version }} | |
| tag_name: ${{ steps.tag_version.outputs.tag_name }} | |
| body_path: /tmp/release_body.md | |
| draft: false | |
| prerelease: ${{ contains(steps.tag_version.outputs.version, '-') }} | |
| generate_release_notes: false | |
| make_latest: true | |
| fail_on_unmatched_files: false | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Upload Pages artifact | |
| uses: actions/upload-pages-artifact@v3 | |
| with: | |
| path: ./out | |
| - name: Deploy to GitHub Pages | |
| id: deployment | |
| uses: actions/deploy-pages@v4 | |
| - name: Sync package.json version to main branch | |
| if: success() | |
| continue-on-error: true # Don't fail the workflow if this step fails | |
| run: | | |
| VERSION="${{ steps.tag_version.outputs.version }}" | |
| # Configure git | |
| git config --local user.email "action@github.com" | |
| git config --local user.name "GitHub Action" | |
| # Fetch main branch and check it out | |
| git fetch origin main | |
| git checkout main | |
| # Check if package.json needs updating | |
| CURRENT_VERSION=$(node -p "require('./package.json').version") | |
| if [ "$CURRENT_VERSION" = "$VERSION" ]; then | |
| echo "β package.json already has version $VERSION, no commit needed" | |
| exit 0 | |
| fi | |
| # Update package.json version | |
| node -e " | |
| const fs = require('fs'); | |
| const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8')); | |
| pkg.version = '$VERSION'; | |
| fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n'); | |
| console.log('Updated package.json version to', '$VERSION'); | |
| " | |
| # Commit and push | |
| git add package.json | |
| git commit -m "chore: update version to $VERSION [skip ci]" | |
| git push origin main | |
| echo "β Committed and pushed updated package.json to main" | |
| - name: Upload build artifacts | |
| if: success() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: build-artifacts-${{ steps.tag_version.outputs.version }} | |
| path: out/ | |
| retention-days: 30 |