Skip to content

3.0.4

3.0.4 #7

Workflow file for this run

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