3.0.4 #7
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: Release | |
| on: | |
| release: | |
| types: [ created ] | |
| jobs: | |
| build-and-unit: | |
| name: Build & Unit Tests | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: 25 | |
| cache: "npm" | |
| - name: Install dependencies | |
| run: npm install | |
| - name: Run unit tests | |
| run: npm run test:min | |
| - name: Build (prod) | |
| run: npm run build:all:prod | |
| - name: Upload build artifacts | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: build-output | |
| path: dist/ | |
| retention-days: 1 | |
| integration-tests: | |
| name: Integration (${{ matrix.browser }}, Shard ${{ matrix.shard }}/4) | |
| needs: build-and-unit | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| browser: [ chromium, firefox ] | |
| shard: [ 1, 2, 3, 4 ] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: 25 | |
| cache: "npm" | |
| - name: Install dependencies | |
| run: npm install | |
| - name: Download build artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: build-output | |
| path: dist/ | |
| - name: Cache Playwright browsers | |
| uses: actions/cache@v5 | |
| id: playwright-cache | |
| with: | |
| path: ~/.cache/ms-playwright | |
| key: playwright-${{ runner.os }}-${{ matrix.browser }}-${{ hashFiles('package-lock.json') }} | |
| - name: Install Playwright browser | |
| if: steps.playwright-cache.outputs.cache-hit != 'true' | |
| run: npx playwright install --with-deps ${{ matrix.browser }} | |
| - name: Install Playwright deps only | |
| if: steps.playwright-cache.outputs.cache-hit == 'true' | |
| run: npx playwright install-deps ${{ matrix.browser }} | |
| - name: Run integration tests (${{ matrix.browser }}, shard ${{ matrix.shard }}/4) | |
| run: npx playwright test --project=${{ matrix.browser }} --shard=${{ matrix.shard }}/4 --reporter=list | |
| - name: Upload test results | |
| if: always() | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: playwright-results-${{ matrix.browser }}-shard-${{ matrix.shard }} | |
| path: test-results/ | |
| retention-days: 7 | |
| if-no-files-found: ignore | |
| publish: | |
| name: Publish to npm | |
| needs: [ build-and-unit, integration-tests ] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| id-token: write | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: 25 | |
| registry-url: 'https://registry.npmjs.org' | |
| cache: "npm" | |
| - name: Install dependencies | |
| run: npm install | |
| - name: Download build artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: build-output | |
| path: dist/ | |
| # Determine npm tag based on version | |
| - name: Determine npm tag | |
| id: npm_tag | |
| run: | | |
| VERSION=$(node -p "require('./package.json').version") | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| if [[ "$VERSION" == *"-alpha"* ]]; then | |
| echo "tag=alpha" >> $GITHUB_OUTPUT | |
| elif [[ "$VERSION" == *"-beta"* ]]; then | |
| echo "tag=beta" >> $GITHUB_OUTPUT | |
| elif [[ "$VERSION" == *"-rc"* ]]; then | |
| echo "tag=rc" >> $GITHUB_OUTPUT | |
| else | |
| echo "tag=latest" >> $GITHUB_OUTPUT | |
| fi | |
| echo "Publishing version $VERSION with tag: $(grep tag= $GITHUB_OUTPUT | cut -d= -f2)" | |
| # Publish to npm using OIDC (no token needed) | |
| - name: Publish to npm | |
| run: npm publish --tag ${{ steps.npm_tag.outputs.tag }} --provenance --access public | |
| # Check if release has manual notes | |
| - name: Check for manual release notes | |
| id: check_notes | |
| uses: actions/github-script@v9 | |
| with: | |
| script: | | |
| const body = context.payload.release.body || ''; | |
| const hasNotes = body.trim().length > 0; | |
| core.setOutput('has_manual_notes', hasNotes.toString()); | |
| console.log(`Release has manual notes: ${hasNotes}`); | |
| # Get previous release for changelog (only if no manual notes) | |
| - name: Get previous release tag | |
| id: prev_release | |
| if: steps.check_notes.outputs.has_manual_notes == 'false' | |
| uses: actions/github-script@v9 | |
| with: | |
| script: | | |
| const releases = await github.rest.repos.listReleases({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| per_page: 10 | |
| }); | |
| // Find current release index and get the next one (previous release) | |
| const currentTag = context.payload.release.tag_name; | |
| const currentIndex = releases.data.findIndex(r => r.tag_name === currentTag); | |
| if (currentIndex >= 0 && currentIndex < releases.data.length - 1) { | |
| const prevTag = releases.data[currentIndex + 1].tag_name; | |
| core.setOutput('tag', prevTag); | |
| console.log(`Previous release: ${prevTag}`); | |
| } else { | |
| core.setOutput('tag', ''); | |
| console.log('No previous release found'); | |
| } | |
| # Generate changelog from commits (only if no manual notes) | |
| - name: Generate changelog | |
| id: changelog | |
| if: steps.check_notes.outputs.has_manual_notes == 'false' | |
| run: | | |
| PREV_TAG="${{ steps.prev_release.outputs.tag }}" | |
| if [ -n "$PREV_TAG" ]; then | |
| COMMITS=$(git log ${PREV_TAG}..HEAD --oneline --no-merges | head -50) | |
| COMMIT_COUNT=$(git log ${PREV_TAG}..HEAD --oneline --no-merges | wc -l | tr -d ' ') | |
| else | |
| COMMITS=$(git log --oneline --no-merges -20) | |
| COMMIT_COUNT="20+" | |
| fi | |
| # Write to file to preserve newlines | |
| echo "## Changes" > changelog.md | |
| echo "" >> changelog.md | |
| echo "$COMMITS" | while read line; do | |
| echo "- $line" >> changelog.md | |
| done | |
| if [ "$COMMIT_COUNT" -gt 50 ] 2>/dev/null; then | |
| echo "" >> changelog.md | |
| echo "_...and $((COMMIT_COUNT - 50)) more commits_" >> changelog.md | |
| fi | |
| cat changelog.md | |
| # Update GitHub release with changelog (only if no manual notes) | |
| - name: Update GitHub release | |
| if: steps.check_notes.outputs.has_manual_notes == 'false' | |
| uses: actions/github-script@v9 | |
| with: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| script: | | |
| const fs = require('fs'); | |
| // Read generated changelog | |
| if (fs.existsSync('./changelog.md')) { | |
| const changelog = fs.readFileSync('./changelog.md', 'utf8'); | |
| // Update the release with generated notes | |
| await github.rest.repos.updateRelease({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| release_id: context.payload.release.id, | |
| body: changelog | |
| }); | |
| } | |
| # Calculate next version | |
| - name: Calculate next version | |
| id: next_version | |
| run: | | |
| VERSION="${{ steps.npm_tag.outputs.version }}" | |
| if [[ "$VERSION" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)-([a-z]+)\.([0-9]+)$ ]]; then | |
| # Pre-release version: 3.0.0-alpha.1 -> 3.0.0-alpha.2 | |
| MAJOR="${BASH_REMATCH[1]}" | |
| MINOR="${BASH_REMATCH[2]}" | |
| PATCH="${BASH_REMATCH[3]}" | |
| PRERELEASE="${BASH_REMATCH[4]}" | |
| PRENUM="${BASH_REMATCH[5]}" | |
| NEXT_VERSION="${MAJOR}.${MINOR}.${PATCH}-${PRERELEASE}.$((PRENUM + 1))" | |
| elif [[ "$VERSION" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then | |
| # Stable version: 3.0.0 -> 3.0.1 | |
| MAJOR="${BASH_REMATCH[1]}" | |
| MINOR="${BASH_REMATCH[2]}" | |
| PATCH="${BASH_REMATCH[3]}" | |
| NEXT_VERSION="${MAJOR}.${MINOR}.$((PATCH + 1))" | |
| else | |
| echo "Unable to parse version: $VERSION" | |
| exit 1 | |
| fi | |
| echo "next_version=$NEXT_VERSION" >> $GITHUB_OUTPUT | |
| echo "Bumping version from $VERSION to $NEXT_VERSION" | |
| # Update package.json with next version | |
| - name: Bump version | |
| run: | | |
| npm version ${{ steps.next_version.outputs.next_version }} --no-git-tag-version | |
| echo "Updated package.json to version ${{ steps.next_version.outputs.next_version }}" | |
| # Commit version bump to master | |
| - name: Commit version bump | |
| uses: stefanzweifel/git-auto-commit-action@v6 | |
| with: | |
| commit_message: "[skip ci] Bump version to ${{ steps.next_version.outputs.next_version }}" | |
| file_pattern: "package.json package-lock.json" | |
| branch: master |