ci: use bun in builds #216
This file contains 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: | |
workflow_dispatch: | |
inputs: | |
releaseType: | |
description: 'Release type (patch, minor, major)' | |
required: false | |
default: 'auto' | |
type: choice | |
options: | |
- auto | |
- patch | |
- minor | |
- major | |
dryRun: | |
description: 'Dry run (no actual release)' | |
required: false | |
default: false | |
type: boolean | |
preRelease: | |
description: 'Pre-release identifier (beta, alpha, rc, etc.)' | |
required: false | |
default: '' | |
type: string | |
repository_dispatch: | |
types: [release-trigger] | |
push: | |
branches: | |
- release | |
jobs: | |
release: | |
name: Release | |
runs-on: ubuntu-latest | |
strategy: | |
matrix: | |
node-version: [20] | |
outputs: | |
new_version: ${{ steps.extract-version.outputs.version }} | |
released: ${{ steps.release.outputs.released }} | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
token: ${{ secrets.GH_TOKEN || secrets.GITHUB_TOKEN }} | |
- name: Setup Bun | |
uses: oven-sh/setup-bun@v1 | |
with: | |
bun-version: latest | |
- name: Use Node.js ${{ matrix.node-version }} | |
uses: actions/setup-node@v4 | |
with: | |
node-version: ${{ matrix.node-version }} | |
# Removing npm caching as we're using Bun | |
# Proper caching specifically for Bun | |
- name: Cache dependencies | |
uses: actions/cache@v3 | |
with: | |
path: | | |
**/node_modules | |
~/.bun/install/cache | |
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }} | |
restore-keys: | | |
${{ runner.os }}-bun- | |
- name: Install dependencies | |
run: | | |
bun install | |
# Validate version before release (tag protection) | |
- name: Validate release | |
id: validate | |
run: | | |
if [[ "${{ github.event_name }}" == "workflow_dispatch" || "${{ github.event_name }}" == "repository_dispatch" ]]; then | |
echo "✅ Manual release triggered, validation passed" | |
echo "valid=true" >> $GITHUB_OUTPUT | |
elif [[ "${{ github.event_name }}" == "push" && "${{ github.ref }}" == "refs/heads/release" ]]; then | |
# Check if there are any new commits since last release | |
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "none") | |
if [[ "$LAST_TAG" != "none" ]]; then | |
CHANGES=$(git log $LAST_TAG..HEAD --oneline) | |
if [[ -z "$CHANGES" ]]; then | |
echo "❌ No changes since last release" | |
echo "valid=false" >> $GITHUB_OUTPUT | |
exit 0 | |
fi | |
fi | |
echo "✅ Changes detected, validation passed" | |
echo "valid=true" >> $GITHUB_OUTPUT | |
else | |
echo "❌ Unknown trigger source" | |
echo "valid=false" >> $GITHUB_OUTPUT | |
fi | |
- name: Build | |
if: steps.validate.outputs.valid == 'true' | |
run: | | |
bun run build --if-present | |
- name: Run tests | |
if: steps.validate.outputs.valid == 'true' | |
run: | | |
bun run test | |
- name: Release | |
id: release | |
if: steps.validate.outputs.valid == 'true' | |
env: | |
GITHUB_TOKEN: ${{ secrets.GH_TOKEN || secrets.GITHUB_TOKEN }} | |
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | |
RELEASE_TYPE: ${{ github.event.inputs.releaseType || 'auto' }} | |
DRY_RUN: ${{ github.event.inputs.dryRun || 'false' }} | |
PRE_RELEASE: ${{ github.event.inputs.preRelease || '' }} | |
run: | | |
EXTRA_ARGS="" | |
RELEASED="false" | |
if [ "$DRY_RUN" == "true" ]; then | |
echo "Running in dry-run mode" | |
EXTRA_ARGS="--dry-run" | |
fi | |
if [ -n "$PRE_RELEASE" ]; then | |
echo "Running pre-release: $PRE_RELEASE" | |
npx semantic-release --prerelease $PRE_RELEASE $EXTRA_ARGS | |
elif [ "$RELEASE_TYPE" == "auto" ]; then | |
echo "Running auto release" | |
npx semantic-release $EXTRA_ARGS | |
else | |
echo "Running release with type: $RELEASE_TYPE" | |
npx semantic-release --release-as $RELEASE_TYPE $EXTRA_ARGS | |
fi | |
# Only set released=true if this was not a dry run and the command succeeded | |
if [ "$DRY_RUN" != "true" ] && [ $? -eq 0 ]; then | |
echo "released=true" >> $GITHUB_OUTPUT | |
else | |
echo "released=false" >> $GITHUB_OUTPUT | |
fi | |
# Extract version for notifications | |
- name: Extract version | |
id: extract-version | |
if: steps.release.outputs.released == 'true' | |
run: | | |
VERSION=$(grep '"version":' package.json | cut -d'"' -f4) | |
echo "version=$VERSION" >> $GITHUB_OUTPUT | |
# Find related PR to comment on | |
- name: Find PR | |
id: find-pr | |
if: steps.release.outputs.released == 'true' | |
uses: jwalton/gh-find-current-pr@v1 | |
with: | |
state: closed | |
# Comment on the PR that triggered this release | |
- name: Comment on PR | |
if: steps.release.outputs.released == 'true' && steps.find-pr.outputs.pr | |
uses: actions/github-script@v6 | |
with: | |
script: | | |
github.rest.issues.createComment({ | |
issue_number: ${{ steps.find-pr.outputs.pr }}, | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
body: '🚀 Release has been published: v${{ steps.extract-version.outputs.version }}' | |
}) | |
# Notification job that runs after release | |
notify: | |
name: Send notifications | |
needs: release | |
if: needs.release.outputs.released == 'true' | |
runs-on: ubuntu-latest | |
steps: | |
# Optional: Slack notifications | |
- name: Notify Slack | |
uses: rtCamp/action-slack-notify@v2 | |
if: env.SLACK_WEBHOOK != '' | |
env: | |
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} | |
SLACK_TITLE: "🚀 New Release" | |
SLACK_MESSAGE: "Version v${{ needs.release.outputs.new_version }} of QuickAdd has been released!" | |
SLACK_COLOR: "good" | |
SLACK_ICON: "https://github.com/chhoumann.png" | |
MSG_MINIMAL: true | |
# Optional: Discord notifications | |
- name: Notify Discord | |
if: env.DISCORD_WEBHOOK != '' | |
uses: Ilshidur/action-discord@master | |
env: | |
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} | |
with: | |
args: '🚀 **New Release**: Version v${{ needs.release.outputs.new_version }} of QuickAdd has been released!' |