feat: Implement Bloqr landing page — 10 section components, dark desi… #888
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: 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 }}') |