From 7c3494f072095eba194ea4ba917640641a6f81ac Mon Sep 17 00:00:00 2001 From: "Jiaxiao (mossaka) Zhou" Date: Thu, 19 Feb 2026 04:23:35 +0000 Subject: [PATCH 1/3] feat: simplify release process to workflow_dispatch only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the tag push trigger from the release workflow. Now the only way to release is via workflow_dispatch (Actions UI or `gh workflow run`). The workflow reads the version from package.json, builds everything, then creates and pushes the git tag only after builds succeed. This eliminates the multi-step tag push dance and reduces the release process to: npm version → git push → trigger workflow. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/release.yml | 38 ++++++++++--------- docs/releasing.md | 70 ++++++++++++++--------------------- 2 files changed, 49 insertions(+), 59 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ee6e3033..49e4a7d8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,13 +1,10 @@ name: Release on: - push: - tags: - - 'v*.*.*' # Trigger on version tags like v1.0.0, v0.1.0, etc. - workflow_dispatch: # Allow manual triggers + workflow_dispatch: # Trigger from Actions UI or gh workflow run permissions: - contents: write # Required for creating releases + contents: write # Required for creating releases and pushing tags packages: write # Required for pushing to GHCR id-token: write # Required for cosign keyless signing @@ -23,24 +20,17 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4 - name: Setup Node.js - if: github.event_name == 'workflow_dispatch' uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version: '22' - - name: Extract version from tag + - name: Extract version from package.json id: version run: | - if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then - VERSION=$(node -p "require('./package.json').version") - echo "version=v$VERSION" >> $GITHUB_OUTPUT - echo "version_number=$VERSION" >> $GITHUB_OUTPUT - else - VERSION="${GITHUB_REF#refs/tags/}" - VERSION_NUMBER="${VERSION#v}" - echo "version=$VERSION" >> $GITHUB_OUTPUT - echo "version_number=$VERSION_NUMBER" >> $GITHUB_OUTPUT - fi + VERSION=$(node -p "require('./package.json').version") + echo "version=v$VERSION" >> $GITHUB_OUTPUT + echo "version_number=$VERSION" >> $GITHUB_OUTPUT + echo "Releasing version: v$VERSION" build-squid: name: Build Squid Image @@ -280,6 +270,9 @@ jobs: steps: - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4 + with: + fetch-depth: 0 # Full history for tag listing and changelog generation + fetch-tags: true - name: Setup Node.js uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 @@ -340,6 +333,17 @@ jobs: cd release sha256sum * > checksums.txt + - name: Create git tag + run: | + TAG="${{ needs.setup.outputs.version }}" + if git rev-parse "$TAG" >/dev/null 2>&1; then + echo "Tag $TAG already exists, skipping creation" + else + git tag "$TAG" + git push origin "$TAG" + echo "Created and pushed tag $TAG" + fi + - name: Get previous release tag id: previous_tag run: | diff --git a/docs/releasing.md b/docs/releasing.md index d0afeaa2..acabb257 100644 --- a/docs/releasing.md +++ b/docs/releasing.md @@ -5,13 +5,11 @@ This document describes how to create a new release of the agentic-workflow-fire ## Prerequisites - Push access to the repository -- Ability to create and push tags +- Ability to trigger workflows (Actions tab or `gh` CLI) ## Release Steps -### 1. Update Version - -Update the version in `package.json`: +### 1. Bump the Version ```bash # For a patch release (0.1.0 -> 0.1.1) @@ -24,32 +22,29 @@ npm version minor npm version major ``` -This will: -- Update `package.json` version -- Create a git commit with the version change -- Create a git tag (e.g., `v0.1.1`) +This updates `package.json` and creates a version commit locally. -### 2. Push Changes and Tag +### 2. Push the Version Commit ```bash -# Push the version commit git push origin main - -# Push the tag (this triggers the release workflow) -git push origin --tags ``` -### 3. Monitor Release Workflow +### 3. Run the Release Workflow + +Trigger the release from the **Actions** tab or CLI: + +```bash +gh workflow run release.yml +``` -1. Go to **Actions** tab in GitHub -2. Watch the **Release** workflow run -3. The workflow will: - - Build TypeScript - - Build and push Docker images to GHCR - - Create Linux x64 binary - - Create NPM tarball - - Generate checksums - - Publish GitHub Release +The workflow will: +- Read the version from `package.json` +- Build and push Docker images to GHCR +- Create Linux x64 and arm64 binaries +- Create NPM tarball and checksums +- Create the git tag (e.g., `v0.1.1`) +- Publish the GitHub Release with changelog ### 4. Verify Release @@ -58,6 +53,7 @@ Once the workflow completes: 1. Go to **Releases** page 2. Verify the new release is published with: - Linux x64 binary (`awf-linux-x64`) + - Linux arm64 binary (`awf-linux-arm64`) - NPM tarball (`awf.tgz`) - Checksums file (`checksums.txt`) - Installation instructions with GHCR image references @@ -68,23 +64,13 @@ Once the workflow completes: - `api-proxy:` and `api-proxy:latest` - `agent-act:` and `agent-act:latest` (GitHub Actions parity image) -## Manual Release - -If you need to trigger a release manually without creating a new tag: - -1. Go to **Actions** → **Release** workflow -2. Click **Run workflow** -3. Select branch (usually `main`) -4. Click **Run workflow** - -This will create a release using the version from `package.json`. - ## Release Artifacts Each release includes: ### GitHub Release Assets - `awf-linux-x64` - Linux x64 standalone executable +- `awf-linux-arm64` - Linux arm64 standalone executable - `awf.tgz` - NPM package tarball (alternative installation method) - `checksums.txt` - SHA256 checksums for all files @@ -101,7 +87,7 @@ The `agent-act` image is used when running with `--agent-image act` for workflow ## Testing a Release Locally -Before pushing a tag, you can test the build process locally: +Before releasing, you can test the build process locally: ### Test Binary Creation @@ -174,13 +160,12 @@ To make packages public: ### Version mismatch -If you accidentally pushed the wrong version: +If you accidentally released the wrong version: -1. Delete the tag locally: `git tag -d v0.1.0` -2. Delete the tag remotely: `git push origin :refs/tags/v0.1.0` -3. Delete the release from GitHub UI -4. Delete or retag the GHCR images if needed -5. Fix the version and retry +1. Delete the tag remotely: `git push origin :refs/tags/v0.1.0` +2. Delete the release from GitHub UI +3. Delete or retag the GHCR images if needed +4. Fix the version and re-run the workflow ## Pre-release Versions @@ -206,6 +191,7 @@ For backporting fixes to older major versions: 1. Create a maintenance branch: `git checkout -b v0.x` 2. Cherry-pick or apply fixes 3. Update version: `npm version patch` -4. Push branch and tag: `git push origin v0.x --tags` +4. Push branch: `git push origin v0.x` +5. Run the release workflow on the maintenance branch The release workflow works the same for maintenance branches. From d6b28d81725e34fea8670672306760f12f812890 Mon Sep 17 00:00:00 2001 From: "Jiaxiao (mossaka) Zhou" Date: Thu, 19 Feb 2026 04:25:59 +0000 Subject: [PATCH 2/3] fix: address review feedback on release workflow - Add concurrency group to prevent duplicate releases - Add branch guard (only main or maintenance v*.x branches) - Use `git tag -l` instead of `git rev-parse` for precise tag checks - Document that npm version creates a local tag (don't push it) Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/release.yml | 12 +++++++++++- docs/releasing.md | 4 +++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 49e4a7d8..d8bf6ed3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,6 +3,10 @@ name: Release on: workflow_dispatch: # Trigger from Actions UI or gh workflow run +concurrency: + group: release + cancel-in-progress: false # Never cancel an in-progress release + permissions: contents: write # Required for creating releases and pushing tags packages: write # Required for pushing to GHCR @@ -24,6 +28,12 @@ jobs: with: node-version: '22' + - name: Verify branch + if: github.ref != 'refs/heads/main' && !startsWith(github.ref, 'refs/heads/v') + run: | + echo "::error::Release should be triggered on main or a maintenance branch (v*.x), got: ${{ github.ref }}" + exit 1 + - name: Extract version from package.json id: version run: | @@ -336,7 +346,7 @@ jobs: - name: Create git tag run: | TAG="${{ needs.setup.outputs.version }}" - if git rev-parse "$TAG" >/dev/null 2>&1; then + if [ -n "$(git tag -l "$TAG")" ]; then echo "Tag $TAG already exists, skipping creation" else git tag "$TAG" diff --git a/docs/releasing.md b/docs/releasing.md index acabb257..8752465f 100644 --- a/docs/releasing.md +++ b/docs/releasing.md @@ -22,7 +22,7 @@ npm version minor npm version major ``` -This updates `package.json` and creates a version commit locally. +This updates `package.json` and creates a version commit (and a local tag) automatically. ### 2. Push the Version Commit @@ -30,6 +30,8 @@ This updates `package.json` and creates a version commit locally. git push origin main ``` +> **Note:** Do not push git tags manually. The release workflow creates and pushes the tag automatically after all builds succeed. + ### 3. Run the Release Workflow Trigger the release from the **Actions** tab or CLI: From efe25ad88d0442307b08f083ea069496101ab2ec Mon Sep 17 00:00:00 2001 From: "Jiaxiao (mossaka) Zhou" Date: Thu, 19 Feb 2026 04:33:46 +0000 Subject: [PATCH 3/3] feat: integrate version bump into release workflow The entire release process is now a single workflow dispatch. Select the bump type (patch/minor/major) in the UI or pass it via CLI: gh workflow run release.yml -f bump=patch The workflow bumps package.json, commits, tags, builds all artifacts, and publishes the GitHub release. No local steps required. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/release.yml | 104 ++++++++++++++++++++-------------- docs/releasing.md | 65 +++++++-------------- 2 files changed, 84 insertions(+), 85 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d8bf6ed3..7d20a665 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,32 +1,40 @@ name: Release on: - workflow_dispatch: # Trigger from Actions UI or gh workflow run + workflow_dispatch: + inputs: + bump: + description: 'Version bump type' + required: true + type: choice + options: + - patch + - minor + - major + default: patch concurrency: group: release cancel-in-progress: false # Never cancel an in-progress release permissions: - contents: write # Required for creating releases and pushing tags + contents: write # Required for creating releases, pushing version commits and tags packages: write # Required for pushing to GHCR id-token: write # Required for cosign keyless signing jobs: - setup: - name: Extract Version + bump-version: + name: Bump Version runs-on: ubuntu-latest outputs: - version: ${{ steps.version.outputs.version }} - version_number: ${{ steps.version.outputs.version_number }} + version: ${{ steps.bump.outputs.version }} + version_number: ${{ steps.bump.outputs.version_number }} steps: - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4 - - - name: Setup Node.js - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: - node-version: '22' + fetch-depth: 0 + fetch-tags: true - name: Verify branch if: github.ref != 'refs/heads/main' && !startsWith(github.ref, 'refs/heads/v') @@ -34,21 +42,39 @@ jobs: echo "::error::Release should be triggered on main or a maintenance branch (v*.x), got: ${{ github.ref }}" exit 1 - - name: Extract version from package.json - id: version + - name: Setup Node.js + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + with: + node-version: '22' + + - name: Bump version + id: bump run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + # npm version creates a commit and tag (e.g., "v0.21.0") + npm version ${{ inputs.bump }} --no-git-tag-version VERSION=$(node -p "require('./package.json').version") + + git add package.json package-lock.json + git commit -m "$VERSION" + git tag "v$VERSION" + git push origin HEAD --tags + echo "version=v$VERSION" >> $GITHUB_OUTPUT echo "version_number=$VERSION" >> $GITHUB_OUTPUT - echo "Releasing version: v$VERSION" + echo "Bumped to v$VERSION (${{ inputs.bump }})" build-squid: name: Build Squid Image runs-on: ubuntu-latest - needs: setup + needs: bump-version steps: - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4 + with: + ref: ${{ needs.bump-version.outputs.version }} - name: Log in to GitHub Container Registry uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3 @@ -76,7 +102,7 @@ jobs: push: true platforms: linux/amd64,linux/arm64 tags: | - ghcr.io/${{ github.repository }}/squid:${{ needs.setup.outputs.version_number }} + ghcr.io/${{ github.repository }}/squid:${{ needs.bump-version.outputs.version_number }} ghcr.io/${{ github.repository }}/squid:latest cache-from: type=gha,scope=squid cache-to: type=gha,mode=max,scope=squid @@ -103,10 +129,12 @@ jobs: build-agent: name: Build Agent Image runs-on: ubuntu-latest - needs: setup + needs: bump-version steps: - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4 + with: + ref: ${{ needs.bump-version.outputs.version }} - name: Log in to GitHub Container Registry uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3 @@ -134,7 +162,7 @@ jobs: push: true platforms: linux/amd64,linux/arm64 tags: | - ghcr.io/${{ github.repository }}/agent:${{ needs.setup.outputs.version_number }} + ghcr.io/${{ github.repository }}/agent:${{ needs.bump-version.outputs.version_number }} ghcr.io/${{ github.repository }}/agent:latest # Disable cache for agent image to ensure security-critical packages # (like libcap2-bin for capability dropping) are always freshly installed @@ -162,10 +190,12 @@ jobs: build-api-proxy: name: Build API Proxy Image runs-on: ubuntu-latest - needs: setup + needs: bump-version steps: - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4 + with: + ref: ${{ needs.bump-version.outputs.version }} - name: Log in to GitHub Container Registry uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3 @@ -193,7 +223,7 @@ jobs: push: true platforms: linux/amd64,linux/arm64 tags: | - ghcr.io/${{ github.repository }}/api-proxy:${{ needs.setup.outputs.version_number }} + ghcr.io/${{ github.repository }}/api-proxy:${{ needs.bump-version.outputs.version_number }} ghcr.io/${{ github.repository }}/api-proxy:latest cache-from: type=gha,scope=api-proxy cache-to: type=gha,mode=max,scope=api-proxy @@ -222,10 +252,12 @@ jobs: build-agent-act: name: Build Agent-Act Image runs-on: ubuntu-latest - needs: setup + needs: bump-version steps: - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4 + with: + ref: ${{ needs.bump-version.outputs.version }} - name: Log in to GitHub Container Registry uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3 @@ -248,7 +280,7 @@ jobs: push: true platforms: linux/amd64 tags: | - ghcr.io/${{ github.repository }}/agent-act:${{ needs.setup.outputs.version_number }} + ghcr.io/${{ github.repository }}/agent-act:${{ needs.bump-version.outputs.version_number }} ghcr.io/${{ github.repository }}/agent-act:latest build-args: | BASE_IMAGE=ghcr.io/catthehacker/ubuntu:act-24.04 @@ -276,11 +308,12 @@ jobs: release: name: Create Release runs-on: ubuntu-latest - needs: [setup, build-squid, build-agent, build-api-proxy, build-agent-act] + needs: [bump-version, build-squid, build-agent, build-api-proxy, build-agent-act] steps: - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4 with: + ref: ${{ needs.bump-version.outputs.version }} # Checkout the version tag fetch-depth: 0 # Full history for tag listing and changelog generation fetch-tags: true @@ -325,7 +358,7 @@ jobs: run: | npx tsx scripts/ci/smoke-test-binary.ts \ release/awf-linux-x64 \ - ${{ needs.setup.outputs.version_number }} + ${{ needs.bump-version.outputs.version_number }} - name: Verify arm64 binary is valid ELF run: | @@ -343,22 +376,11 @@ jobs: cd release sha256sum * > checksums.txt - - name: Create git tag - run: | - TAG="${{ needs.setup.outputs.version }}" - if [ -n "$(git tag -l "$TAG")" ]; then - echo "Tag $TAG already exists, skipping creation" - else - git tag "$TAG" - git push origin "$TAG" - echo "Created and pushed tag $TAG" - fi - - name: Get previous release tag id: previous_tag run: | set -euo pipefail - CURRENT_TAG="${{ needs.setup.outputs.version }}" + CURRENT_TAG="${{ needs.bump-version.outputs.version }}" # Use git tags directly (more reliable than gh release list) # Get the most recent tag that is not the current tag @@ -371,7 +393,7 @@ jobs: id: changelog run: | set -euo pipefail - CURRENT_TAG="${{ needs.setup.outputs.version }}" + CURRENT_TAG="${{ needs.bump-version.outputs.version }}" PREVIOUS_TAG="${{ steps.previous_tag.outputs.previous_tag }}" echo "Generating changelog from $PREVIOUS_TAG to $CURRENT_TAG" @@ -433,8 +455,8 @@ jobs: - name: Create Release Notes id: release_notes env: - VERSION: ${{ needs.setup.outputs.version }} - VERSION_NUMBER: ${{ needs.setup.outputs.version_number }} + VERSION: ${{ needs.bump-version.outputs.version }} + VERSION_NUMBER: ${{ needs.bump-version.outputs.version_number }} REPOSITORY: ${{ github.repository }} run: | set -euo pipefail @@ -461,11 +483,11 @@ jobs: - name: Create GitHub Release uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0 with: - tag_name: ${{ needs.setup.outputs.version }} - name: Release ${{ needs.setup.outputs.version }} + tag_name: ${{ needs.bump-version.outputs.version }} + name: Release ${{ needs.bump-version.outputs.version }} body_path: release_notes.md draft: false - prerelease: ${{ contains(needs.setup.outputs.version, 'alpha') || contains(needs.setup.outputs.version, 'beta') || contains(needs.setup.outputs.version, 'rc') }} + prerelease: ${{ contains(needs.bump-version.outputs.version, 'alpha') || contains(needs.bump-version.outputs.version, 'beta') || contains(needs.bump-version.outputs.version, 'rc') }} files: | release/awf-linux-x64 release/awf-linux-arm64 diff --git a/docs/releasing.md b/docs/releasing.md index 8752465f..d9e7587d 100644 --- a/docs/releasing.md +++ b/docs/releasing.md @@ -4,51 +4,36 @@ This document describes how to create a new release of the agentic-workflow-fire ## Prerequisites -- Push access to the repository - Ability to trigger workflows (Actions tab or `gh` CLI) ## Release Steps -### 1. Bump the Version +### 1. Run the Release Workflow -```bash -# For a patch release (0.1.0 -> 0.1.1) -npm version patch - -# For a minor release (0.1.1 -> 0.2.0) -npm version minor - -# For a major release (0.2.0 -> 1.0.0) -npm version major -``` - -This updates `package.json` and creates a version commit (and a local tag) automatically. - -### 2. Push the Version Commit +From the CLI: ```bash -git push origin main -``` +# Patch release (0.1.0 -> 0.1.1) +gh workflow run release.yml -f bump=patch -> **Note:** Do not push git tags manually. The release workflow creates and pushes the tag automatically after all builds succeed. +# Minor release (0.1.1 -> 0.2.0) +gh workflow run release.yml -f bump=minor -### 3. Run the Release Workflow - -Trigger the release from the **Actions** tab or CLI: - -```bash -gh workflow run release.yml +# Major release (0.2.0 -> 1.0.0) +gh workflow run release.yml -f bump=major ``` +Or from the GitHub UI: go to **Actions** > **Release** > **Run workflow**, select the bump type, and click **Run workflow**. + The workflow will: -- Read the version from `package.json` +- Bump the version in `package.json` +- Commit the version change and create a git tag - Build and push Docker images to GHCR - Create Linux x64 and arm64 binaries - Create NPM tarball and checksums -- Create the git tag (e.g., `v0.1.1`) -- Publish the GitHub Release with changelog +- Publish the GitHub Release with auto-generated changelog -### 4. Verify Release +### 2. Verify Release Once the workflow completes: @@ -167,24 +152,19 @@ If you accidentally released the wrong version: 1. Delete the tag remotely: `git push origin :refs/tags/v0.1.0` 2. Delete the release from GitHub UI 3. Delete or retag the GHCR images if needed -4. Fix the version and re-run the workflow +4. Re-run the workflow with the correct bump type ## Pre-release Versions -For alpha, beta, or release candidate versions: +Pre-release versions are not currently supported via the workflow dispatch input. +To create a pre-release, manually bump the version locally and push: ```bash -# Alpha release npm version prerelease --preid=alpha # 0.1.0 -> 0.1.1-alpha.0 - -# Beta release -npm version prerelease --preid=beta # 0.1.0 -> 0.1.1-beta.0 - -# Release candidate -npm version prerelease --preid=rc # 0.1.0 -> 0.1.1-rc.0 +git push origin main --tags ``` -The workflow automatically marks releases containing `alpha`, `beta`, or `rc` as pre-releases on GitHub. +The release workflow can then be triggered manually (it will read the pre-release version from `package.json` and skip the bump step since the tag already exists). ## Maintenance Releases @@ -192,8 +172,5 @@ For backporting fixes to older major versions: 1. Create a maintenance branch: `git checkout -b v0.x` 2. Cherry-pick or apply fixes -3. Update version: `npm version patch` -4. Push branch: `git push origin v0.x` -5. Run the release workflow on the maintenance branch - -The release workflow works the same for maintenance branches. +3. Push branch: `git push origin v0.x` +4. Run the release workflow on the maintenance branch (select the `v0.x` branch in the UI)