Skip to content

Migrate to Build-on-Release Pattern #22

@dcramer

Description

@dcramer

Plan: Migrate to Build-on-Release Pattern

Current State

  • dist/ is committed to main branch
  • Pre-commit hook runs pnpm build && pnpm build:action on every commit
  • Single workflow file (warden.yml) that uses @main for dogfooding
  • No release workflow or versioning strategy

Target State

  • dist/ only exists on release tags (not in main branch)
  • CI builds and tests the action on every PR
  • Release workflow handles building, tagging, and version management
  • Users reference @v1 (or specific versions) instead of @main

Changes

1. Update .gitignore

Add dist/ back to gitignore:

dist/

2. Remove pre-commit build hook

In package.json, change:

"simple-git-hooks": {
  "pre-commit": "pnpm lint-staged"
}

(Remove the pnpm build && pnpm build:action && portion)

3. Create CI workflow (.github/workflows/ci.yml)

name: CI

on:
  push:
    branches: [main]
  pull_request:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 24
          cache: pnpm
      - run: pnpm install
      - run: pnpm typecheck
      - run: pnpm lint
      - run: pnpm test
      - run: pnpm build:action

  test-action:
    runs-on: ubuntu-latest
    needs: build
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 24
          cache: pnpm
      - run: pnpm install
      - run: pnpm build:action
      - uses: ./  # Test the freshly-built action
        with:
          anthropic-api-key: ${{ secrets.WARDEN_ANTHROPIC_API_KEY }}

4. Create release workflow (.github/workflows/release.yml)

Note: We use a custom workflow instead of build-and-tag-action because this project has separate library (dist/index.js) and action (dist/action/) entry points.

name: Release

on:
  push:
    tags:
      - 'v*.*.*'

permissions:
  contents: write

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 24
          cache: pnpm

      - run: pnpm install
      - run: pnpm build:action

      - name: Parse version
        id: version
        run: |
          TAG=${GITHUB_REF#refs/tags/}
          MAJOR=${TAG%%.*}
          echo "tag=$TAG" >> $GITHUB_OUTPUT
          echo "major=$MAJOR" >> $GITHUB_OUTPUT

      - name: Update tag with built artifacts
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"

          # Add built files
          git add -f dist/action/
          git commit -m "Build ${{ steps.version.outputs.tag }}"

          # Force update the version tag to include dist/
          git tag -fa ${{ steps.version.outputs.tag }} -m "Release ${{ steps.version.outputs.tag }}"
          git push origin ${{ steps.version.outputs.tag }} --force

          # Update major version tag (v1, v2, etc.)
          git tag -fa ${{ steps.version.outputs.major }} -m "Release ${{ steps.version.outputs.tag }}"
          git push origin ${{ steps.version.outputs.major }} --force

      - name: Create GitHub Release
        uses: softprops/action-gh-release@v2
        with:
          generate_release_notes: true

5. Update warden.yml (dogfooding workflow)

Change from @main to version reference once released:

- uses: getsentry/warden@v1

(Keep @main initially for testing, update after first release)

6. Remove dist/ from repository

git rm -r --cached dist/
git commit -m "chore: Remove dist/ from version control"

7. Reinstall git hooks

pnpm simple-git-hooks

File Summary

File Action
.gitignore Add dist/
package.json Remove build from pre-commit hook
.github/workflows/ci.yml Create (new)
.github/workflows/release.yml Create (new)
.github/workflows/warden.yml Update action reference (later)
dist/ Remove from git tracking

Verification

  1. CI works: Push a PR, verify build + test-action jobs pass
  2. Action still works: The test-action job should successfully run the action
  3. Release works: Create a tag v1.0.0, verify:
    • Release workflow commits dist/action/ to the tag
    • v1 major version tag is created/updated
    • GitHub Release is created with release notes
  4. Consumers work: Test uses: getsentry/warden@v1 in another repo

Release Process (after implementation)

  1. Update version in package.json (optional, for npm publishing)
  2. Create and push a version tag: git tag v1.0.0 && git push origin v1.0.0
  3. Release workflow automatically:
    • Builds the action
    • Updates the tag to include dist/action/
    • Creates/updates the v1 major version tag
    • Creates a GitHub Release with auto-generated notes

Users can then reference:

  • getsentry/warden@v1 - latest v1.x.x (recommended)
  • getsentry/warden@v1.0.0 - specific version

Tasks

Remove build from pre-commit hook

Description

In package.json, change simple-git-hooks to only run 'pnpm lint-staged'. Then run 'pnpm simple-git-hooks' to reinstall hooks.

Result

Removed build commands from pre-commit hook. Now only runs 'pnpm lint-staged'. Reinstalled hooks via 'pnpm simple-git-hooks'.

Create release workflow

Description

Create .github/workflows/release.yml triggered on v*.. tags. Build action, commit dist/action/ to tag, update major version tag, create GitHub Release.

Result

Created .github/workflows/release.yml triggered on v*.. tags. Builds action, commits dist/action/ to tag with force push, updates major version tag (e.g., v1), and creates GitHub Release with auto-generated notes.

Update .gitignore to exclude dist/

Description

Add dist/ back to .gitignore

Result

Added dist/ to .gitignore under the '# Build output' section.

Create CI workflow

Description

Create .github/workflows/ci.yml with build job (typecheck, lint, test, build:action) and test-action job (uses: ./)

Result

Created .github/workflows/ci.yml with build job (typecheck, lint, test, build, build:action) that uploads dist/action/ as artifact, and test-action job that downloads artifact and runs the action with uses: ./

Remove dist/ from git tracking

Description

Run 'git rm -r --cached dist/' and commit

Result

Removed dist/ from git tracking using 'git rm -r --cached dist/'. All 279 files in dist/ are now untracked.

Metadata

Metadata

Assignees

No one assigned
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions