release: v2.38.1 (#644) #178
Workflow file for this run
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: Release | |
| on: | |
| push: | |
| tags: | |
| - "v*" | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| jobs: | |
| # ─── 1. GitHub Release from CHANGELOG ─────────────────────────────────────── | |
| create-release: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| version: ${{ steps.version.outputs.VERSION }} | |
| notes_file: ${{ steps.changelog.outputs.NOTES_FILE }} | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| fetch-depth: 0 | |
| - name: Extract version from tag | |
| id: version | |
| run: echo "VERSION=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT" | |
| - name: Parse CHANGELOG for this version | |
| id: changelog | |
| run: | | |
| VERSION="${{ steps.version.outputs.VERSION }}" | |
| NOTES=$(awk -v ver="$VERSION" ' | |
| /^## \[/ { | |
| if (found) exit | |
| if (index($0, "[" ver "]") > 0) found=1 | |
| next | |
| } | |
| found { print } | |
| ' claude-ops/CHANGELOG.md) | |
| if [[ -z "$NOTES" ]]; then | |
| NOTES="Release v${VERSION}. See CHANGELOG.md for details." | |
| fi | |
| # Write to file to avoid quoting issues | |
| echo "$NOTES" > /tmp/release-notes.md | |
| echo "NOTES_FILE=/tmp/release-notes.md" >> "$GITHUB_OUTPUT" | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@v3 | |
| with: | |
| tag_name: ${{ github.ref_name }} | |
| name: "claude-ops v${{ steps.version.outputs.VERSION }}" | |
| body_path: ${{ steps.changelog.outputs.NOTES_FILE }} | |
| draft: false | |
| prerelease: ${{ contains(github.ref_name, '-') }} | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| # ─── 2. Open a PR with the version bumps ──────────────────────────────────── | |
| # Branch protection on `main` rejects direct pushes from github-actions[bot], | |
| # so the previous "Commit version bumps" step silently failed every release. | |
| # We now open a PR against main with the bumps and let the maintainer | |
| # squash-merge. | |
| bump-version-pr: | |
| needs: create-release | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Configure git | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| - name: Bump versions in plugin/marketplace/package JSON | |
| env: | |
| VERSION: ${{ needs.create-release.outputs.version }} | |
| run: | | |
| # Use jq for safe JSON edits when available; fall back to sed otherwise. | |
| if command -v jq >/dev/null 2>&1; then | |
| tmp=$(mktemp) | |
| jq --arg v "$VERSION" '.version = $v' claude-ops/.claude-plugin/plugin.json > "$tmp" \ | |
| && mv "$tmp" claude-ops/.claude-plugin/plugin.json | |
| jq --arg v "$VERSION" '.version = $v' claude-ops/package.json > "$tmp" \ | |
| && mv "$tmp" claude-ops/package.json | |
| jq --arg v "$VERSION" '.plugins |= map(if .name == "ops" then .version = $v else . end)' \ | |
| .claude-plugin/marketplace.json > "$tmp" \ | |
| && mv "$tmp" .claude-plugin/marketplace.json | |
| else | |
| # Fallback: target the literal "version" line in each file. This is | |
| # less safe (matches the first .version key) but keeps the workflow | |
| # working on minimal runners. | |
| sed -i "0,/\"version\":/{s/\"version\": \"[^\"]*\"/\"version\": \"${VERSION}\"/}" \ | |
| claude-ops/.claude-plugin/plugin.json | |
| sed -i "0,/\"version\":/{s/\"version\": \"[^\"]*\"/\"version\": \"${VERSION}\"/}" \ | |
| claude-ops/package.json | |
| # marketplace.json — only the ops plugin entry, not the marketplace meta | |
| sed -i "/\"name\": \"ops\"/,/\"version\":/{s/\"version\": \"[^\"]*\"/\"version\": \"${VERSION}\"/}" \ | |
| .claude-plugin/marketplace.json | |
| fi | |
| - name: Open bump PR | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| VERSION: ${{ needs.create-release.outputs.version }} | |
| run: | | |
| BRANCH="release/bump-${VERSION}" | |
| if git diff --quiet; then | |
| echo "no version changes to commit (already at v${VERSION})" | |
| exit 0 | |
| fi | |
| git checkout -B "$BRANCH" | |
| git add claude-ops/.claude-plugin/plugin.json \ | |
| claude-ops/package.json \ | |
| .claude-plugin/marketplace.json | |
| git commit -m "chore: bump version to ${VERSION} [skip ci]" | |
| git push -f origin "$BRANCH" | |
| # Write PR body to a file to avoid YAML/shell quoting hell | |
| cat > /tmp/bump-pr-body.md <<EOF | |
| Auto-generated by the Release workflow after publishing v${VERSION}. | |
| Bumps: | |
| - \`claude-ops/.claude-plugin/plugin.json\` | |
| - \`claude-ops/package.json\` | |
| - \`.claude-plugin/marketplace.json\` (\`plugins.ops.version\`) | |
| Squash-merge to finish the release. Safe to merge — no code changes. | |
| EOF | |
| # Open the PR; ignore failure if it already exists | |
| gh pr create \ | |
| --base main \ | |
| --head "$BRANCH" \ | |
| --title "chore: bump version to ${VERSION}" \ | |
| --body-file /tmp/bump-pr-body.md \ | |
| || echo "PR may already exist for $BRANCH — skipping create" |