From 91c22916497af300810ce02780897467748380c9 Mon Sep 17 00:00:00 2001 From: Will Washburn Date: Mon, 20 Apr 2026 08:03:51 -0400 Subject: [PATCH 1/2] Add per-package GitHub Release job Expose the bumped package versions from the publish job and add a parallel 'create-release' job that creates one GitHub Release per published package. The job is matrixed across packages, checks whether each package was published via the publish.outputs.versions, checks prerelease status, checks out the package tag, prefers a per-package CHANGELOG entry for release notes (falls back to generated notes), and creates the appropriate release (stable with changelog, stable with auto notes, or prerelease). Also grants contents write permission and gates execution on dry-run/custom version inputs. --- .github/workflows/publish.yml | 94 +++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 5f70c0bc..12b20547 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -61,6 +61,8 @@ concurrency: jobs: publish: runs-on: ubuntu-latest + outputs: + versions: ${{ steps.bump.outputs.versions }} steps: - name: Checkout uses: actions/checkout@v4 @@ -358,3 +360,95 @@ jobs: echo "Next step: verify the published artifact by running the \`Verify Publish\` workflow." fi } >> "$GITHUB_STEP_SUMMARY" + + # One GitHub Release per package tag. Matches the relay pattern + # (softprops/action-gh-release@v2 + generate_release_notes). Runs in parallel + # across packages; each cell is gated on whether its package was published. + create-release: + name: Release @agentworkforce/${{ matrix.package }} + needs: publish + if: ${{ github.event.inputs.dry_run != 'true' && (github.event.inputs.version != 'none' || github.event.inputs.custom_version != '') }} + runs-on: ubuntu-latest + permissions: + contents: write + strategy: + fail-fast: false + matrix: + package: [workload-router, harness-kit, cli] + steps: + - name: Check if this package was published + id: check + run: | + VERSIONS='${{ needs.publish.outputs.versions }}' + for entry in $VERSIONS; do + pkg="${entry%%:*}" + ver="${entry##*:}" + if [ "$pkg" = "${{ matrix.package }}" ]; then + echo "published=true" >> "$GITHUB_OUTPUT" + echo "version=$ver" >> "$GITHUB_OUTPUT" + if [[ "$ver" == *-* ]]; then + echo "prerelease=true" >> "$GITHUB_OUTPUT" + else + echo "prerelease=false" >> "$GITHUB_OUTPUT" + fi + exit 0 + fi + done + echo "published=false" >> "$GITHUB_OUTPUT" + + - name: Checkout + if: steps.check.outputs.published == 'true' + uses: actions/checkout@v4 + with: + # Need the tag that the publish job just pushed. + ref: ${{ matrix.package }}-v${{ steps.check.outputs.version }} + + # Prefer the per-package CHANGELOG section that was generated and + # committed during publish. Falls back to auto-generated notes for + # prereleases and first publishes (where no CHANGELOG entry exists). + - name: Extract changelog notes + if: steps.check.outputs.published == 'true' + id: notes + run: | + pkg="${{ matrix.package }}" + ver="${{ steps.check.outputs.version }}" + file="packages/$pkg/CHANGELOG.md" + out=/tmp/release-notes.md + : > "$out" + if [ -f "$file" ]; then + awk -v v="## [$ver]" ' + $0 ~ "^" v { flag=1; print; next } + /^## \[/ && flag { exit } + flag { print } + ' "$file" > "$out" + fi + if [ -s "$out" ]; then + echo "has_notes=true" >> "$GITHUB_OUTPUT" + else + echo "has_notes=false" >> "$GITHUB_OUTPUT" + fi + + - name: Create GitHub Release (stable, with changelog) + if: steps.check.outputs.published == 'true' && steps.check.outputs.prerelease != 'true' && steps.notes.outputs.has_notes == 'true' + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ matrix.package }}-v${{ steps.check.outputs.version }} + name: "@agentworkforce/${{ matrix.package }}@${{ steps.check.outputs.version }}" + body_path: /tmp/release-notes.md + + - name: Create GitHub Release (stable, auto notes) + if: steps.check.outputs.published == 'true' && steps.check.outputs.prerelease != 'true' && steps.notes.outputs.has_notes != 'true' + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ matrix.package }}-v${{ steps.check.outputs.version }} + name: "@agentworkforce/${{ matrix.package }}@${{ steps.check.outputs.version }}" + generate_release_notes: true + + - name: Create GitHub Release (prerelease) + if: steps.check.outputs.published == 'true' && steps.check.outputs.prerelease == 'true' + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ matrix.package }}-v${{ steps.check.outputs.version }} + name: "@agentworkforce/${{ matrix.package }}@${{ steps.check.outputs.version }} (prerelease)" + prerelease: true + generate_release_notes: true From b030ef19a364476270f80ab2155150708086f0c5 Mon Sep 17 00:00:00 2001 From: Will Washburn Date: Mon, 20 Apr 2026 08:13:21 -0400 Subject: [PATCH 2/2] Use awk index for prefix matching Replace the regex-based ^v match with index($0, prefix) == 1 when locating the version header in the release notes. This ensures a literal prefix match (avoiding regex metacharacter issues) and more reliably extracts the section for the given version. --- .github/workflows/publish.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 12b20547..856ede3c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -416,8 +416,8 @@ jobs: out=/tmp/release-notes.md : > "$out" if [ -f "$file" ]; then - awk -v v="## [$ver]" ' - $0 ~ "^" v { flag=1; print; next } + awk -v prefix="## [$ver]" ' + index($0, prefix) == 1 { flag=1; print; next } /^## \[/ && flag { exit } flag { print } ' "$file" > "$out"