Skip to content

feat: Implement Bloqr landing page — 10 section components, dark desi… #888

feat: Implement Bloqr landing page — 10 section components, dark desi…

feat: Implement Bloqr landing page — 10 section components, dark desi… #888

Workflow file for this run

name: Version Bump
on:
push:
branches:
- main
- master
workflow_dispatch:
inputs:
bump_type:
description: 'Version bump type (leave empty for auto-detect from commits)'
required: false
type: choice
options:
- ''
- patch
- minor
- major
create_release:
description: 'Create a release after bumping'
required: false
default: false
type: boolean
permissions:
contents: write
actions: write
pull-requests: write
jobs:
version-bump:
name: Version Bump
runs-on: ubuntu-latest
# Skip if commit message contains [skip ci], [skip version], or was made by github-actions bot
if: |
github.event_name == 'workflow_dispatch' || (
github.event.head_commit &&
!contains(github.event.head_commit.message, '[skip ci]') &&
!contains(github.event.head_commit.message, '[skip version]') &&
github.event.head_commit.author.name != 'github-actions[bot]'
)
outputs:
old_version: ${{ steps.bump.outputs.old }}
new_version: ${{ steps.bump.outputs.new }}
bump_type: ${{ steps.determine_bump.outputs.bump_type }}
compiler_changed: ${{ steps.determine_bump.outputs.compiler_changed || 'false' }}
steps:
- name: Checkout
uses: actions/[email protected]
with:
fetch-depth: 0 # full history required: git log --grep searches all commits to find last version bump
token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup Deno
uses: denoland/setup-deno@667a34cdef165d8d2b2e98dde39547c9daac7282 # v2
with:
deno-version: '2.x'
- name: Determine version bump type
id: determine_bump
run: |
set -euo pipefail
# If bump_type input is provided, use it
if [ -n "${{ inputs.bump_type }}" ]; then
BUMP_TYPE="${{ inputs.bump_type }}"
echo "bump_type=$BUMP_TYPE" >> "$GITHUB_OUTPUT"
echo "Using manual bump type: $BUMP_TYPE"
exit 0
fi
# Get the last version bump commit
LAST_VERSION_COMMIT=$(git log --grep="chore: bump version" --format="%H" -n 1 || echo "")
# If no version commit found, use first commit
if [ -z "$LAST_VERSION_COMMIT" ]; then
LAST_VERSION_COMMIT=$(git rev-list --max-parents=0 HEAD)
fi
echo "Analyzing commits since $LAST_VERSION_COMMIT"
# Detect if any src/** files (excluding tests) changed since last version bump
CHANGED_SRC=$(git diff --name-only $LAST_VERSION_COMMIT..HEAD -- 'src/' | grep -E '\.ts$' | grep -v '\.test\.ts$' || true)
if [ -z "$CHANGED_SRC" ]; then
echo "No compiler source files changed, skipping version bump"
echo "bump_type=none" >> "$GITHUB_OUTPUT"
echo "compiler_changed=false" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "compiler_changed=true" >> "$GITHUB_OUTPUT"
echo "Compiler source files changed:"
echo "$CHANGED_SRC"
# Get commit messages since last version bump
COMMITS=$(git log --format="%s" $LAST_VERSION_COMMIT..HEAD || echo "")
if [ -z "$COMMITS" ]; then
echo "No commits to analyze, skipping version bump"
echo "bump_type=none" >> "$GITHUB_OUTPUT"
exit 0
fi
# Filter to compiler-relevant commits: no scope or compiler scope only
# Exclude commits explicitly scoped to non-compiler packages
# Keep: unscoped (feat:, fix:), compiler-scoped (feat(compiler):), breaking (feat!:)
# Exclude: scoped to frontend, db, worker, migrations, prisma, docker, ci, deps, admin
COMPILER_COMMITS=$(echo "$COMMITS" | grep -vE "^(feat|fix|perf|refactor|chore|build|ci|docs|style|test)\((frontend|db|worker|migrations|prisma|docker|ci|deps|admin)\)(!)?:" || true)
# Determine bump type based on conventional commits
BUMP_TYPE="none"
while IFS= read -r commit; do
echo "Analyzing commit: $commit"
# Check for breaking changes (major bump)
if echo "$commit" | grep -qiE "^(feat|fix|perf|refactor)!:|BREAKING CHANGE:"; then
BUMP_TYPE="major"
echo "Found breaking change: $commit"
break
fi
# Check for features (minor bump)
if echo "$commit" | grep -qiE "^feat(\(.+\))?:"; then
if [ "$BUMP_TYPE" != "major" ]; then
BUMP_TYPE="minor"
echo "Found feature: $commit"
fi
fi
# Check for fixes (patch bump)
if echo "$commit" | grep -qiE "^fix(\(.+\))?:"; then
if [ "$BUMP_TYPE" != "major" ] && [ "$BUMP_TYPE" != "minor" ]; then
BUMP_TYPE="patch"
echo "Found fix: $commit"
fi
fi
# Check for performance improvements (patch bump)
if echo "$commit" | grep -qiE "^perf(\(.+\))?:"; then
if [ "$BUMP_TYPE" != "major" ] && [ "$BUMP_TYPE" != "minor" ]; then
BUMP_TYPE="patch"
echo "Found performance improvement: $commit"
fi
fi
done <<< "$COMPILER_COMMITS"
echo "Determined bump type: $BUMP_TYPE"
echo "bump_type=$BUMP_TYPE" >> "$GITHUB_OUTPUT"
- name: Bump version
id: bump
if: steps.determine_bump.outputs.bump_type != 'none'
run: |
set -euo pipefail
BUMP_TYPE="${{ steps.determine_bump.outputs.bump_type }}"
# Get current version from deno.json
OLD=$(deno eval "console.log(JSON.parse(Deno.readTextFileSync('deno.json')).version)")
echo "old=$OLD" >> "$GITHUB_OUTPUT"
# Parse version components
IFS='.' read -r major minor patch <<< "$OLD"
# Calculate new version
case "$BUMP_TYPE" in
major)
NEW="$((major + 1)).0.0"
;;
minor)
NEW="$major.$((minor + 1)).0"
;;
patch)
NEW="$major.$minor.$((patch + 1))"
;;
*)
echo "Error: Unknown bump type '$BUMP_TYPE'" >&2
exit 1
;;
esac
echo "new=$NEW" >> "$GITHUB_OUTPUT"
echo "Bumping version: $OLD → $NEW ($BUMP_TYPE)"
# Update the single source of truth
if [ -f src/version.ts ]; then
sed -i "s/VERSION = '[^']*'/VERSION = '$NEW'/" src/version.ts
fi
# Propagate to all other version files via sync script
deno run --allow-read --allow-write scripts/sync-version.ts
echo "Version bumped successfully: $OLD → $NEW"
- name: Generate changelog entry
id: changelog
if: steps.determine_bump.outputs.bump_type != 'none'
run: |
set -euo pipefail
NEW_VERSION="${{ steps.bump.outputs.new }}"
# Get the last version bump commit
LAST_VERSION_COMMIT=$(git log --grep="chore: bump version" --format="%H" -n 1 || echo "")
if [ -z "$LAST_VERSION_COMMIT" ]; then
LAST_VERSION_COMMIT=$(git rev-list --max-parents=0 HEAD)
fi
# Generate changelog entry
CHANGELOG_ENTRY=$(cat <<EOF
## [${NEW_VERSION}] - $(date +%Y-%m-%d)
### Added
EOF
)
# Collect features
FEATURES=$(git log --format="%s" $LAST_VERSION_COMMIT..HEAD | grep -E "^feat(\(.+\))?:" | sed 's/^feat(\([^)]*\)): \(.*\)/- **\1**: \2/' | sed 's/^feat: /- /' || echo "")
if [ -n "$FEATURES" ]; then
CHANGELOG_ENTRY="$CHANGELOG_ENTRY$FEATURES"$'\n\n'
else
CHANGELOG_ENTRY="${CHANGELOG_ENTRY%$'\n### Added\n'}"
fi
# Collect fixes
FIXES=$(git log --format="%s" $LAST_VERSION_COMMIT..HEAD | grep -E "^fix(\(.+\))?:" | sed 's/^fix(\([^)]*\)): \(.*\)/- **\1**: \2/' | sed 's/^fix: /- /' || echo "")
if [ -n "$FIXES" ]; then
CHANGELOG_ENTRY="$CHANGELOG_ENTRY### Fixed"$'\n\n'"$FIXES"$'\n\n'
fi
# Collect performance improvements
PERF=$(git log --format="%s" $LAST_VERSION_COMMIT..HEAD | grep -E "^perf(\(.+\))?:" | sed 's/^perf(\([^)]*\)): \(.*\)/- **\1**: \2/' | sed 's/^perf: /- /' || echo "")
if [ -n "$PERF" ]; then
CHANGELOG_ENTRY="$CHANGELOG_ENTRY### Performance"$'\n\n'"$PERF"$'\n\n'
fi
# Check for breaking changes
BREAKING=$(git log --format="%B" $LAST_VERSION_COMMIT..HEAD | grep -A 10 "BREAKING CHANGE:" || echo "")
if [ -n "$BREAKING" ]; then
CHANGELOG_ENTRY="$CHANGELOG_ENTRY### BREAKING CHANGES"$'\n\n'"$BREAKING"$'\n\n'
fi
# Prepend to CHANGELOG.md
if [ -f CHANGELOG.md ]; then
# Find the first versioned release header (starts with "## [" but NOT "## [Unreleased]")
# Insert new entry before it to preserve [Unreleased] as the topmost section
if grep -q "^## \[" CHANGELOG.md; then
# Get line number of first released version entry (skip [Unreleased])
FIRST_VERSION_LINE=$(grep -n "^## \[" CHANGELOG.md | grep -v "## \[Unreleased\]" | head -1 | cut -d: -f1)
# Verify we got a valid line number
if [ -n "$FIRST_VERSION_LINE" ] && [ "$FIRST_VERSION_LINE" -gt 0 ]; then
# Create temporary file with new entry inserted before the first versioned release
{
head -n $((FIRST_VERSION_LINE - 1)) CHANGELOG.md # Keep header (including [Unreleased]) up to first versioned release
echo "$CHANGELOG_ENTRY"
tail -n +$FIRST_VERSION_LINE CHANGELOG.md # Keep rest of changelog
} > CHANGELOG.md.tmp
mv CHANGELOG.md.tmp CHANGELOG.md
echo "Changelog updated"
else
echo "Warning: Could not determine changelog insertion point, appending to end"
echo "$CHANGELOG_ENTRY" >> CHANGELOG.md
fi
else
# No existing versions, append to end
echo "$CHANGELOG_ENTRY" >> CHANGELOG.md
echo "Changelog updated (first entry)"
fi
fi
- name: Create PR with version bump
if: steps.determine_bump.outputs.bump_type != 'none'
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
if git diff --quiet; then
echo "No changes detected"
exit 0
fi
# Create a new branch for the version bump
BRANCH_NAME="auto-version-bump-${{ steps.bump.outputs.new }}"
# Delete existing remote branch if it exists (from a previous failed run)
git push origin --delete "$BRANCH_NAME" 2>/dev/null || true
git checkout -b "$BRANCH_NAME"
# Only add files that were modified and exist
git add deno.json package.json 2>/dev/null || true
[ -f src/version.ts ] && git add src/version.ts
[ -f wrangler.toml ] && git add wrangler.toml
[ -f CHANGELOG.md ] && git add CHANGELOG.md
git commit -m "chore: bump version to ${{ steps.bump.outputs.new }}"
git push -u origin "$BRANCH_NAME"
# Create pull request with reviewer/assignee for notification.
# Falls back to creating the PR without those flags if the org/repo
# rejects them (e.g. self-assignment restriction or outside collaborator).
gh pr create \
--title "chore: bump version to ${{ steps.bump.outputs.new }}" \
--body "$(cat <<'EOF'
## Compiler Version Bump
This PR was automatically created by the version-bump workflow.
- **Old Version**: ${{ steps.bump.outputs.old }}
- **New Version**: ${{ steps.bump.outputs.new }}
- **Bump Type**: ${{ steps.determine_bump.outputs.bump_type }}
### Changes
- Updated version in `deno.json`
- Updated version in `package.json`
- Updated version in `src/version.ts`
- Updated version in `wrangler.toml`
- Updated `CHANGELOG.md`
### Next Steps
After this PR is merged:
1. A release tag `v${{ steps.bump.outputs.new }}` will be created
2. The release workflow will be automatically triggered
---
🤖 Generated by Version Bump workflow
EOF
)" \
--base main \
--head "$BRANCH_NAME" \
--reviewer jaypatrick \
--assignee jaypatrick \
|| gh pr create \
--title "chore: bump version to ${{ steps.bump.outputs.new }}" \
--body "$(cat <<'EOF'
## Compiler Version Bump
This PR was automatically created by the version-bump workflow.
- **Old Version**: ${{ steps.bump.outputs.old }}
- **New Version**: ${{ steps.bump.outputs.new }}
- **Bump Type**: ${{ steps.determine_bump.outputs.bump_type }}
### Changes
- Updated version in `deno.json`
- Updated version in `package.json`
- Updated version in `src/version.ts`
- Updated version in `wrangler.toml`
- Updated `CHANGELOG.md`
### Next Steps
After this PR is merged:
1. A release tag `v${{ steps.bump.outputs.new }}` will be created
2. The release workflow will be automatically triggered
---
🤖 Generated by Version Bump workflow
⚠️ Note: reviewer/assignee could not be set — please assign manually.
EOF
)" \
--base main \
--head "$BRANCH_NAME"
# GITHUB_TOKEN-created PRs do not fire pull_request events, so CI
# never triggers automatically. Explicitly dispatch the CI workflow
# on the new branch so the PR gets its required status checks.
gh workflow run ci.yml --ref "$BRANCH_NAME"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Summary
if: steps.determine_bump.outputs.bump_type != 'none'
run: |
cat <<EOF >> $GITHUB_STEP_SUMMARY
## 🎉 Version Bump PR Created
- **Old Version**: ${{ steps.bump.outputs.old }}
- **New Version**: ${{ steps.bump.outputs.new }}
- **Bump Type**: ${{ steps.determine_bump.outputs.bump_type }}
- **Branch**: auto-version-bump-${{ steps.bump.outputs.new }}
A pull request has been created with the version bump changes.
After the PR is merged, a release tag will be created automatically.
EOF
- name: Skip summary
if: steps.determine_bump.outputs.bump_type == 'none'
run: |
cat <<EOF >> $GITHUB_STEP_SUMMARY
## ℹ️ No Version Bump Required
No commits requiring a version bump were found since the last version.
Commits that trigger version bumps:
- \`feat:\` → minor bump
- \`fix:\` → patch bump
- \`perf:\` → patch bump
- \`BREAKING CHANGE:\` or \`feat!:\` or \`fix!:\` → major bump
EOF
trigger-release:
name: Trigger Release
runs-on: ubuntu-latest
needs: version-bump
if: inputs.create_release == true && needs.version-bump.outputs.bump_type != 'none'
permissions:
actions: write
steps:
- name: Trigger release workflow
uses: actions/github-script@v9
with:
script: |
await github.rest.actions.createWorkflowDispatch({
owner: context.repo.owner,
repo: context.repo.repo,
workflow_id: 'release.yml',
ref: context.ref,
inputs: {
version: '${{ needs.version-bump.outputs.new_version }}'
}
})
console.log('Release workflow triggered for version ${{ needs.version-bump.outputs.new_version }}')