Skip to content

feat: migrate from semantic-release to Release Please - #375

Merged
baleen37 merged 1 commit into
mainfrom
feat/release-please
Feb 4, 2026
Merged

feat: migrate from semantic-release to Release Please#375
baleen37 merged 1 commit into
mainfrom
feat/release-please

Conversation

@baleen37

@baleen37 baleen37 commented Feb 4, 2026

Copy link
Copy Markdown
Owner

Summary

Replace semantic-release with Release Please to solve branch protection issues by using a PR-based release workflow instead of direct commits to main.

Problem Solved

  • semantic-release creates release commits and tries to push directly to main
  • Branch protection requires "CI / test" status check
  • New commit doesn't have status yet (chicken-egg problem)
  • Push is rejected: "Required status check 'CI / test' is expected"

Solution: Release Please PR-Based Workflow

Release Please creates release PRs instead of pushing commits directly:

  1. Release Please bot analyzes conventional commits
  2. Creates/updates a release PR with version bump and changelog
  3. PR goes through normal CI checks
  4. When PR is merged, Release Please creates the GitHub release
  5. No branch protection bypass needed - follows normal PR workflow

Changes Made

  • ✅ Add Release Please configuration files (.release-please-manifest.json, release-please-config.json)
  • ✅ Add Release Please workflow (.github/workflows/release-please.yml)
  • ✅ Add marketplace.json sync workflow (.github/workflows/sync-marketplace.yml)
  • ✅ Add marketplace version sync script (scripts/sync-marketplace-version.sh)
  • ✅ Remove semantic-release dependencies from package.json
  • ✅ Remove semantic-release configuration (.releaserc.js)
  • ✅ Simplify CI workflow (remove release job, keep only test job)
  • ✅ Update tests to validate new Release Please workflows

Benefits

  • No branch protection bypass needed - follows normal PR workflow
  • Release changes are visible in PR before release
  • Can review version bumps and changelog before releasing
  • Same CI process for all changes

Breaking Change

⚠️ Release workflow now requires merging Release Please PRs instead of automatic releases on push to main.

Next Steps

  1. ⚠️ Install Release Please GitHub App (required for workflows to work)

  2. After merging this PR, Release Please will:

    • Detect the new conventional commit
    • Create/update a release PR with version bump
    • Wait for manual merge
    • Create GitHub release when PR is merged

Test Plan

  • All pre-commit hooks pass
  • All BATS tests pass
  • Marketplace sync script tested and working
  • YAML files validated
  • CI tests pass on this PR
  • Release Please App installed (manual step)

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • Chores
    • Updated release automation infrastructure with an improved system for streamlined version management and release notes generation.
    • Automated marketplace version synchronization to maintain consistency during releases.

Replace semantic-release with Release Please to solve branch protection
issues by using a PR-based release workflow instead of direct commits to main.

Changes:
- Add Release Please configuration files (.release-please-manifest.json, release-please-config.json)
- Add Release Please workflow (.github/workflows/release-please.yml)
- Add marketplace.json sync workflow (.github/workflows/sync-marketplace.yml)
- Add marketplace version sync script (scripts/sync-marketplace-version.sh)
- Remove semantic-release dependencies from package.json
- Remove semantic-release configuration (.releaserc.js)
- Simplify CI workflow (remove release job, keep only test job)
- Update tests to validate new Release Please workflows

Benefits:
- No branch protection bypass needed - follows normal PR workflow
- Release changes are visible in PR before release
- Can review version bumps and changelog before releasing
- Same CI process for all changes

Breaking Change: Release workflow now requires merging Release Please PRs
instead of automatic releases on push to main.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Feb 4, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This PR replaces semantic-release automation with release-please, removing the old release job from CI workflows, adding Release Please and marketplace sync workflows, and updating configuration files and tests accordingly.

Changes

Cohort / File(s) Summary
Release Automation Migration
.github/workflows/ci.yml, .releaserc.js, package.json
Removed semantic-release dependencies and configuration; changed CI workflow permissions to read-only and eliminated the release job entirely.
Release Please Setup
.github/workflows/release-please.yml, .release-please-manifest.json, release-please-config.json
Added Release Please workflow configuration and manifest files to manage releases, versioning, and changelog generation on pushes to main.
Marketplace Sync
.github/workflows/sync-marketplace.yml, scripts/sync-marketplace-version.sh
Introduced new workflow and script to synchronize plugin versions in marketplace.json when autorelease PRs are created, replacing semantic-release's plugin synchronization logic.
Test Updates
tests/github_workflows.bats
Updated workflow tests to validate Release Please and marketplace sync workflows; removed release job assertions; changed CI permission assertions from write to read.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

Possibly related PRs

Poem

🐰 From semantic dreams to release-please delight,
We've hopped away from complexity's night,
The marketplace sync script now takes the lead,
Automating versions with rabbit-speed! 🚀

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: migrate from semantic-release to Release Please' clearly summarizes the main change—replacing semantic-release with Release Please—which is the primary objective of the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/release-please

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@baleen37
baleen37 enabled auto-merge (squash) February 4, 2026 08:51
@baleen37
baleen37 merged commit d20c736 into main Feb 4, 2026
2 of 3 checks passed
@baleen37
baleen37 deleted the feat/release-please branch February 4, 2026 08:51

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In @.github/workflows/sync-marketplace.yml:
- Around line 31-35: The workflow uses unquoted $GITHUB_OUTPUT in the echo
commands which can cause word-splitting (ShellCheck SC2086); update both echo
lines that write to GITHUB_OUTPUT (the ones echoing "changed=false" and
"changed=true" after the git diff check) to quote the variable as
"$GITHUB_OUTPUT" so the output file path is treated as a single argument.

In `@release-please-config.json`:
- Around line 5-10: The extra-files entry that uses the glob pattern
"plugins/*/.claude-plugin/plugin.json" is missing the "glob": true flag so
Release Please treats the path as a literal; update the JSON object inside the
"extra-files" array (the entry with "type": "json", "path":
"plugins/*/.claude-plugin/plugin.json", "jsonpath": "$.version") to include
"glob": true so the glob pattern is recognized and plugin manifest versions are
updated.

In `@scripts/sync-marketplace-version.sh`:
- Around line 4-14: Validate the VERSION variable returned by jq (VERSION=$(jq
-r '.version' package.json)) before mutating .claude-plugin/marketplace.json:
check if VERSION is empty or equals "null", and if so write a clear error
message to stderr (use >&2) and exit with non-zero status so the script does not
overwrite marketplace.json; only proceed to run the existing jq update and mv
steps when VERSION is valid. Ensure the error message is descriptive and use the
same .claude-plugin/marketplace.json temporary-write flow when proceeding.

In `@tests/github_workflows.bats`:
- Around line 65-131: The tests in tests/github_workflows.bats currently perform
command substitution and direct [[ ... ]] checks (e.g., jobs=$(yaml_get
"$CI_WORKFLOW" ".jobs | keys | .[]"), release_job=$(yaml_get "$CI_WORKFLOW"
".jobs.release"), and workflow_has_trigger/uses checks) instead of using BATS'
run/$status/$output conventions; update each test to invoke the helper commands
with run (for example run yaml_get "$CI_WORKFLOW" ".jobs | keys | .[]"), assert
success with [ "$status" -eq 0 ], and assert expected text using [[ "$output" =~
"expected" ]] (apply this pattern to tests that call yaml_get,
workflow_has_trigger, and file existence checks that can be run and captured,
e.g., run test -f "${WORKFLOW_DIR}/release-please.yml" then check $status, and
similarly replace direct [[ "$uses" == *"...release-please-action@v4"* ]] with a
run of yaml_get and an output regex assertion).

Comment on lines +31 to +35
run: |
if git diff --quiet .claude-plugin/marketplace.json; then
echo "changed=false" >> $GITHUB_OUTPUT
else
echo "changed=true" >> $GITHUB_OUTPUT

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Quote $GITHUB_OUTPUT to avoid word splitting.

Shellcheck SC2086 warns here; quoting is the safe default.

✅ Suggested fix
-          if git diff --quiet .claude-plugin/marketplace.json; then
-            echo "changed=false" >> $GITHUB_OUTPUT
-          else
-            echo "changed=true" >> $GITHUB_OUTPUT
-          fi
+          if git diff --quiet .claude-plugin/marketplace.json; then
+            echo "changed=false" >> "$GITHUB_OUTPUT"
+          else
+            echo "changed=true" >> "$GITHUB_OUTPUT"
+          fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
run: |
if git diff --quiet .claude-plugin/marketplace.json; then
echo "changed=false" >> $GITHUB_OUTPUT
else
echo "changed=true" >> $GITHUB_OUTPUT
run: |
if git diff --quiet .claude-plugin/marketplace.json; then
echo "changed=false" >> "$GITHUB_OUTPUT"
else
echo "changed=true" >> "$GITHUB_OUTPUT"
fi
🧰 Tools
🪛 actionlint (1.7.10)

[error] 31-31: shellcheck reported issue in this script: SC2086:info:2:27: Double quote to prevent globbing and word splitting

(shellcheck)


[error] 31-31: shellcheck reported issue in this script: SC2086:info:4:26: Double quote to prevent globbing and word splitting

(shellcheck)

🤖 Prompt for AI Agents
In @.github/workflows/sync-marketplace.yml around lines 31 - 35, The workflow
uses unquoted $GITHUB_OUTPUT in the echo commands which can cause word-splitting
(ShellCheck SC2086); update both echo lines that write to GITHUB_OUTPUT (the
ones echoing "changed=false" and "changed=true" after the git diff check) to
quote the variable as "$GITHUB_OUTPUT" so the output file path is treated as a
single argument.

Comment on lines +5 to +10
"extra-files": [
{
"type": "json",
"path": "plugins/*/.claude-plugin/plugin.json",
"jsonpath": "$.version"
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

Release Please extra-files glob pattern support documentation

💡 Result:

release-please does support glob patterns for extra-files, but not when extra-files items are plain strings. To use a glob, you must use the object form and set "glob": true (defaults to false). (raw.githubusercontent.com)

Example:

{
  "packages": {
    ".": {
      "release-type": "simple",
      "extra-files": [
        { "type": "generic", "path": "packages/*/version.txt", "glob": true }
      ]
    }
  }
}

Notes:

  • Object forms exist for targeted updates too (e.g., {type: "json"|"yaml"|"toml", path, glob, jsonpath} and {type:"xml", path, glob, xpath}), all with the same "glob" boolean. (raw.githubusercontent.com)

Citations:


Add "glob": true to enable glob pattern matching.

Release Please requires the "glob": true property to recognize glob patterns in extra-files. Without it, the path plugins/*/.claude-plugin/plugin.json is treated as a literal filename and won't match any files, preventing version updates to plugin manifests.

Corrected configuration
{
  "type": "json",
  "path": "plugins/*/.claude-plugin/plugin.json",
  "jsonpath": "$.version",
  "glob": true
}
🤖 Prompt for AI Agents
In `@release-please-config.json` around lines 5 - 10, The extra-files entry that
uses the glob pattern "plugins/*/.claude-plugin/plugin.json" is missing the
"glob": true flag so Release Please treats the path as a literal; update the
JSON object inside the "extra-files" array (the entry with "type": "json",
"path": "plugins/*/.claude-plugin/plugin.json", "jsonpath": "$.version") to
include "glob": true so the glob pattern is recognized and plugin manifest
versions are updated.

Comment on lines +4 to +14
# Get version from package.json
VERSION=$(jq -r '.version' package.json)

# Update all plugin versions in marketplace.json
jq --arg version "$VERSION" \
'.plugins = [.plugins[] | .version = $version]' \
.claude-plugin/marketplace.json > .claude-plugin/marketplace.json.tmp

mv .claude-plugin/marketplace.json.tmp .claude-plugin/marketplace.json

echo "Updated marketplace.json to version $VERSION"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Guard against missing/invalid version to avoid writing “null”.

jq -r '.version' returns null when missing, which would overwrite marketplace versions incorrectly. Add validation and stderr error output before mutation.

🛡️ Proposed fix
-# Get version from package.json
-VERSION=$(jq -r '.version' package.json)
+# Get version from package.json
+VERSION=$(jq -r '.version // empty' package.json)
+if [[ -z "$VERSION" ]]; then
+  echo "ERROR: package.json is missing .version" >&2
+  exit 1
+fi
+
+if [[ ! -f .claude-plugin/marketplace.json ]]; then
+  echo "ERROR: .claude-plugin/marketplace.json not found" >&2
+  exit 1
+fi
+
+if ! jq -e '.plugins | type=="array"' .claude-plugin/marketplace.json >/dev/null; then
+  echo "ERROR: marketplace.json missing .plugins array" >&2
+  exit 1
+fi

As per coding guidelines: Direct error messages to stderr in hook scripts.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Get version from package.json
VERSION=$(jq -r '.version' package.json)
# Update all plugin versions in marketplace.json
jq --arg version "$VERSION" \
'.plugins = [.plugins[] | .version = $version]' \
.claude-plugin/marketplace.json > .claude-plugin/marketplace.json.tmp
mv .claude-plugin/marketplace.json.tmp .claude-plugin/marketplace.json
echo "Updated marketplace.json to version $VERSION"
# Get version from package.json
VERSION=$(jq -r '.version // empty' package.json)
if [[ -z "$VERSION" ]]; then
echo "ERROR: package.json is missing .version" >&2
exit 1
fi
if [[ ! -f .claude-plugin/marketplace.json ]]; then
echo "ERROR: .claude-plugin/marketplace.json not found" >&2
exit 1
fi
if ! jq -e '.plugins | type=="array"' .claude-plugin/marketplace.json >/dev/null; then
echo "ERROR: marketplace.json missing .plugins array" >&2
exit 1
fi
# Update all plugin versions in marketplace.json
jq --arg version "$VERSION" \
'.plugins = [.plugins[] | .version = $version]' \
.claude-plugin/marketplace.json > .claude-plugin/marketplace.json.tmp
mv .claude-plugin/marketplace.json.tmp .claude-plugin/marketplace.json
echo "Updated marketplace.json to version $VERSION"
🤖 Prompt for AI Agents
In `@scripts/sync-marketplace-version.sh` around lines 4 - 14, Validate the
VERSION variable returned by jq (VERSION=$(jq -r '.version' package.json))
before mutating .claude-plugin/marketplace.json: check if VERSION is empty or
equals "null", and if so write a clear error message to stderr (use >&2) and
exit with non-zero status so the script does not overwrite marketplace.json;
only proceed to run the existing jq update and mv steps when VERSION is valid.
Ensure the error message is descriptive and use the same
.claude-plugin/marketplace.json temporary-write flow when proceeding.

Comment on lines +65 to 131
@test "CI workflow has only test job (no release job)" {
ensure_yq
yaml_get "$CI_WORKFLOW" ".jobs.release" >/dev/null
}

@test "CI workflow release job has bot detection condition" {
ensure_yq
# The job should have an 'if' condition that filters bot accounts
local if_condition
if_condition=$(yaml_get "$CI_WORKFLOW" ".jobs.release.if")
# CI workflow should only have test job, release is now handled by Release Please
local jobs
jobs=$(yaml_get "$CI_WORKFLOW" ".jobs | keys | .[]")

echo "Actual if condition: $if_condition"
[[ "$jobs" == "test" ]]

# The condition should check github.actor
[[ "$if_condition" == *"github.actor"* ]]

# The condition should use either:
# 1. contains() function for universal bot filtering (recommended)
# 2. or != operator for specific bot filtering (brittle)
[[ "$if_condition" == *"contains"* ]] || [[ "$if_condition" == *"!="* ]]
# Verify release job doesn't exist (should return "null")
local release_job
release_job=$(yaml_get "$CI_WORKFLOW" ".jobs.release")
[[ "$release_job" == "null" ]]
}

@test "CI workflow has required permissions" {
@test "CI workflow has read-only permissions" {
ensure_yq
local permissions
permissions=$(yaml_get "$CI_WORKFLOW" ".permissions.contents")

[[ "$permissions" == "write" ]]
[[ "$permissions" == "read" ]]
}

@test "CI workflow release job runs tests before release" {
# Check that 'Run tests' step exists in the release job
# We'll check for the step name in the file
grep -q "name:.*Run tests" "$CI_WORKFLOW" || grep -q "name:.*test" "$CI_WORKFLOW"
@test "Release Please workflow exists" {
[ -f "${WORKFLOW_DIR}/release-please.yml" ]
}

@test "CI workflow release job depends on test job" {
@test "Release Please workflow has valid YAML syntax" {
ensure_yq
# The release job should have 'needs: test' to ensure proper execution order
local needs
needs=$(yaml_get "$CI_WORKFLOW" ".jobs.release.needs")

[[ "$needs" == "test" ]] || [[ "$needs" == *"test"* ]]
yaml_get "${WORKFLOW_DIR}/release-please.yml" "." >/dev/null
}

@test "CI workflow release job only runs on main branch" {
@test "Release Please workflow triggers on push to main" {
ensure_yq
# The release job should only run on push to main, not on PRs
local if_condition
if_condition=$(yaml_get "$CI_WORKFLOW" ".jobs.release.if")
workflow_has_trigger "${WORKFLOW_DIR}/release-please.yml" "push"
local branches
branches=$(yaml_get "${WORKFLOW_DIR}/release-please.yml" ".on.push.branches.[]")
[[ "$branches" == "main" ]]
}

echo "Actual if condition: $if_condition"
@test "Release Please workflow has required permissions" {
ensure_yq
local contents_perm
contents_perm=$(yaml_get "${WORKFLOW_DIR}/release-please.yml" ".permissions.contents")
[[ "$contents_perm" == "write" ]]

# Should check for main branch
[[ "$if_condition" == *"main"* ]]
local pr_perm
pr_perm=$(yaml_get "${WORKFLOW_DIR}/release-please.yml" ".permissions.pull-requests")
[[ "$pr_perm" == "write" ]]
}

# Should check for push event (not pull_request)
[[ "$if_condition" == *"push"* ]]
@test "Marketplace sync workflow exists" {
[ -f "${WORKFLOW_DIR}/sync-marketplace.yml" ]
}

@test "CI workflow filters all bot accounts to prevent infinite loop" {
@test "Marketplace sync workflow has valid YAML syntax" {
ensure_yq
# The job should NOT run when ANY bot account is the actor
# This prevents infinite loops when auto-update-bot-baleen[bot] merges PRs
local if_condition
if_condition=$(yaml_get "$CI_WORKFLOW" ".jobs.release.if")

echo "Actual if condition: $if_condition"

# The condition should use contains() to filter ANY bot with [bot] suffix
# Valid patterns:
# - !contains(github.actor, '[bot]')
# - contains(github.actor, '[bot]') == false

# Check that it uses contains() function for universal bot filtering
[[ "$if_condition" == *"contains"* ]]
[[ "$if_condition" == *"[bot]"* ]]

# Verify it doesn't hardcode specific bot names (like github-actions[bot])
# Hardcoding specific bot names will miss other bots like auto-update-bot-baleen[bot]
if [[ "$if_condition" == *"github-actions[bot]"* ]]; then
# If it mentions github-actions[bot], it must be a general pattern
# that would also catch other bots
if [[ "$if_condition" != *"contains"* ]]; then
echo "ERROR: Condition hardcodes github-actions[bot] without using contains()"
echo "This will miss other bots like auto-update-bot-baleen[bot]"
return 1
fi
fi
yaml_get "${WORKFLOW_DIR}/sync-marketplace.yml" "." >/dev/null
}

@test "CI workflow blocks auto-update-bot-baleen" {
@test "Release Please workflow uses googleapis action" {
ensure_yq
# Specifically verify that auto-update-bot-baleen[bot] would be filtered
# This is the actual bot causing the infinite loop
local if_condition
if_condition=$(yaml_get "$CI_WORKFLOW" ".jobs.release.if")

echo "Checking if condition blocks auto-update-bot-baleen[bot]: $if_condition"

# The condition must block any actor with [bot] suffix
# Valid approaches:
# 1. !contains(github.actor, '[bot]')
# 2. github.actor != 'github-actions[bot]' && github.actor != 'auto-update-bot-baleen[bot]' (brittle)

# Check for the robust solution (contains)
if [[ "$if_condition" == *"contains"* ]] && [[ "$if_condition" == *"[bot]"* ]]; then
# This is the good approach - catches all bots
return 0
fi

# If using specific bot names, check if auto-update-bot-baleen[bot] is included
if [[ "$if_condition" == *"github-actions[bot]"* ]] && [[ "$if_condition" != *"contains"* ]]; then
# Hardcoded approach - must explicitly list auto-update-bot-baleen[bot]
if [[ "$if_condition" != *"auto-update-bot-baleen"* ]]; then
echo "ERROR: Condition filters github-actions[bot] but not auto-update-bot-baleen[bot]"
echo "This will cause infinite loops when auto-update-bot merges PRs"
return 1
fi
fi
# Verify that the workflow uses the official release-please action
local uses
uses=$(yaml_get "${WORKFLOW_DIR}/release-please.yml" ".jobs.release-please.steps.[0].uses")

return 0
[[ "$uses" == *"googleapis/release-please-action@v4"* ]]
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use run + status/output assertions for the new tests.

Current assertions bypass BATS’ run and $status/$output conventions. Apply the pattern below across the new tests.

♻️ Example refactor pattern
-    local jobs
-    jobs=$(yaml_get "$CI_WORKFLOW" ".jobs | keys | .[]")
-
-    [[ "$jobs" == "test" ]]
+    run yaml_get "$CI_WORKFLOW" ".jobs | keys | .[]"
+    [ "$status" -eq 0 ]
+    [[ "$output" =~ ^test$ ]]

As per coding guidelines: Use the run command to execute and capture output in BATS tests; Use [$status -eq 0] for exit code assertions; Use [[ "$output" =~ "expected" ]] for output assertions in BATS tests.

🤖 Prompt for AI Agents
In `@tests/github_workflows.bats` around lines 65 - 131, The tests in
tests/github_workflows.bats currently perform command substitution and direct [[
... ]] checks (e.g., jobs=$(yaml_get "$CI_WORKFLOW" ".jobs | keys | .[]"),
release_job=$(yaml_get "$CI_WORKFLOW" ".jobs.release"), and
workflow_has_trigger/uses checks) instead of using BATS' run/$status/$output
conventions; update each test to invoke the helper commands with run (for
example run yaml_get "$CI_WORKFLOW" ".jobs | keys | .[]"), assert success with [
"$status" -eq 0 ], and assert expected text using [[ "$output" =~ "expected" ]]
(apply this pattern to tests that call yaml_get, workflow_has_trigger, and file
existence checks that can be run and captured, e.g., run test -f
"${WORKFLOW_DIR}/release-please.yml" then check $status, and similarly replace
direct [[ "$uses" == *"...release-please-action@v4"* ]] with a run of yaml_get
and an output regex assertion).

baleen37 pushed a commit that referenced this pull request Feb 5, 2026
# [5.0.0](v4.3.0...v5.0.0) (2026-02-05)

### Bug Fixes

* **ci:** disable strict status checks to allow semantic-release commits ([7b296a4](7b296a4))
* **ci:** merge Release workflow into CI workflow with proper dependency ([906673e](906673e))
* **ci:** trigger CI on release-please PRs using workflow_run ([33ff7d3](33ff7d3))
* **ci:** update branch protection to match GitHub Actions status check format ([13efcf5](13efcf5))
* enable glob pattern for plugin.json version updates ([86fd628](86fd628))
* **handoff:** output notification to stderr to exclude from LLM context ([463bb08](463bb08))
* **marketplace:** remove databricks plugin reference ([f0bc6b8](f0bc6b8))
* **ralph-loop:** fix hooks matcher and stdin handling ([326a570](326a570))
* set release-please manifest to start from 4.3.0 ([#377](#377)) ([23a6cba](23a6cba))

### Features

* **bash-lsp:** add Bash Language Server plugin ([#394](#394)) ([7770f3d](7770f3d))
* **ci:** replace release-please with semantic-release ([35d346f](35d346f))
* **conversation-memory:** add automatic npm install when node_modules missing ([db55514](db55514))
* **conversation-memory:** add marked dependency for markdown rendering ([1887174](1887174))
* **conversation-memory:** improve MCP installation error handling ([#373](#373)) ([16eb7b7](16eb7b7))
* **conversation-memory:** reduce token usage in summarization ([d921bc7](d921bc7))
* **conversation-memory:** reduce token usage in summarization ([b3a245b](b3a245b))
* **handoff:** add session handoff plugin for context transfer ([#374](#374)) ([35cfb0c](35cfb0c))
* **me:** add tdd and spawn commands ([#371](#371)) ([9af9bbe](9af9bbe))
* migrate from semantic-release to Release Please ([#375](#375)) ([d20c736](d20c736))
* **release-please:** add auto-merge for release PRs ([cef4678](cef4678))
* **test-helpers:** extract shared BATS helpers to @baleen/bats-helpers package ([19f2a62](19f2a62))
* **tests:** run plugin tests in parallel using background processes ([04be773](04be773))

### Performance Improvements

* **tests:** add caching to improve test execution speed ([9bbee5b](9bbee5b))

### BREAKING CHANGES

* Release workflow now requires merging Release Please PRs
instead of automatic releases on push to main.

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
baleen37 added a commit that referenced this pull request Feb 5, 2026
* chore: prepare for 5.0.0 release

* chore(release): 5.0.0

# [5.0.0](v4.3.0...v5.0.0) (2026-02-05)

### Bug Fixes

* **ci:** disable strict status checks to allow semantic-release commits ([7b296a4](7b296a4))
* **ci:** merge Release workflow into CI workflow with proper dependency ([906673e](906673e))
* **ci:** trigger CI on release-please PRs using workflow_run ([33ff7d3](33ff7d3))
* **ci:** update branch protection to match GitHub Actions status check format ([13efcf5](13efcf5))
* enable glob pattern for plugin.json version updates ([86fd628](86fd628))
* **handoff:** output notification to stderr to exclude from LLM context ([463bb08](463bb08))
* **marketplace:** remove databricks plugin reference ([f0bc6b8](f0bc6b8))
* **ralph-loop:** fix hooks matcher and stdin handling ([326a570](326a570))
* set release-please manifest to start from 4.3.0 ([#377](#377)) ([23a6cba](23a6cba))

### Features

* **bash-lsp:** add Bash Language Server plugin ([#394](#394)) ([7770f3d](7770f3d))
* **ci:** replace release-please with semantic-release ([35d346f](35d346f))
* **conversation-memory:** add automatic npm install when node_modules missing ([db55514](db55514))
* **conversation-memory:** add marked dependency for markdown rendering ([1887174](1887174))
* **conversation-memory:** improve MCP installation error handling ([#373](#373)) ([16eb7b7](16eb7b7))
* **conversation-memory:** reduce token usage in summarization ([d921bc7](d921bc7))
* **conversation-memory:** reduce token usage in summarization ([b3a245b](b3a245b))
* **handoff:** add session handoff plugin for context transfer ([#374](#374)) ([35cfb0c](35cfb0c))
* **me:** add tdd and spawn commands ([#371](#371)) ([9af9bbe](9af9bbe))
* migrate from semantic-release to Release Please ([#375](#375)) ([d20c736](d20c736))
* **release-please:** add auto-merge for release PRs ([cef4678](cef4678))
* **test-helpers:** extract shared BATS helpers to @baleen/bats-helpers package ([19f2a62](19f2a62))
* **tests:** run plugin tests in parallel using background processes ([04be773](04be773))

### Performance Improvements

* **tests:** add caching to improve test execution speed ([9bbee5b](9bbee5b))

### BREAKING CHANGES

* Release workflow now requires merging Release Please PRs
instead of automatic releases on push to main.

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* refactor(bash-lsp): migrate from MCP to LSP configuration

- Remove .mcp.json file
- Add lspServers field to plugin.json with bash-language-server config
- Add .bats extension support for BATS test files

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test(bats): add lspServers to allowed plugin.json fields

- Add lspServers to json_field_is_allowed function
- Update error message to include lspServers in allowed fields list

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: semantic-release-bot <semantic-release-bot@martynus.net>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
baleen-release-app Bot pushed a commit that referenced this pull request Feb 5, 2026
# [5.0.0](v4.3.0...v5.0.0) (2026-02-05)

### Bug Fixes

* **ci:** disable strict status checks to allow semantic-release commits ([7b296a4](7b296a4))
* **ci:** merge Release workflow into CI workflow with proper dependency ([906673e](906673e))
* **ci:** trigger CI on release-please PRs using workflow_run ([33ff7d3](33ff7d3))
* **ci:** update bats-action to latest commit ([106b1f3](106b1f3))
* **ci:** update branch protection to match GitHub Actions status check format ([13efcf5](13efcf5))
* **ci:** use full commit SHA for bats-action ([9a70f52](9a70f52))
* **commands:** correct sdd command skill reference ([#403](#403)) ([a4db99c](a4db99c))
* enable glob pattern for plugin.json version updates ([86fd628](86fd628))
* **handoff:** output notification to stderr to exclude from LLM context ([463bb08](463bb08))
* **marketplace:** remove databricks plugin reference ([f0bc6b8](f0bc6b8))
* **ralph-loop:** fix hooks matcher and stdin handling ([326a570](326a570))
* **release:** add owner parameter to GitHub App token generation ([#401](#401)) ([b910a20](b910a20))
* **release:** remove GitHub App token generation ([ced7b17](ced7b17))
* **release:** restore GitHub App token generation ([45dd490](45dd490))
* **release:** use GitHub App token with Administration permission ([4077ecd](4077ecd))
* **release:** use GitHub App token with Administration permission ([#411](#411)) ([e6b1e9c](e6b1e9c))
* **release:** use GITHUB_TOKEN directly with github-actions[bot] bypass ([c7b517c](c7b517c))
* **release:** use GITHUB_TOKEN instead of custom GitHub App ([76a2a00](76a2a00))
* **release:** use secrets.GITHUB_TOKEN directly ([a2aaf50](a2aaf50))
* set release-please manifest to start from 4.3.0 ([#377](#377)) ([23a6cba](23a6cba))

### Features

* **bash-lsp:** add Bash Language Server plugin ([#394](#394)) ([7770f3d](7770f3d))
* **ci:** replace release-please with semantic-release ([35d346f](35d346f))
* **conversation-memory:** add automatic npm install when node_modules missing ([db55514](db55514))
* **conversation-memory:** add file-based logging system ([81f65bd](81f65bd))
* **conversation-memory:** add marked dependency for markdown rendering ([1887174](1887174))
* **conversation-memory:** improve MCP installation error handling ([#373](#373)) ([16eb7b7](16eb7b7))
* **conversation-memory:** reduce token usage in summarization ([d921bc7](d921bc7))
* **conversation-memory:** reduce token usage in summarization ([b3a245b](b3a245b))
* **databricks-devtools:** add Databricks CLI wrapper plugin ([#408](#408)) ([7baf422](7baf422))
* **handoff:** add session handoff plugin for context transfer ([#374](#374)) ([35cfb0c](35cfb0c))
* **lsp-support:** add Kotlin, Lua, Nix LSP servers, merge bash-lsp ([8f1ee4f](8f1ee4f))
* **me:** add commit skill ([8d0cf1c](8d0cf1c))
* **me:** add tdd and spawn commands ([#371](#371)) ([9af9bbe](9af9bbe))
* migrate from semantic-release to Release Please ([#375](#375)) ([d20c736](d20c736))
* **release-please:** add auto-merge for release PRs ([cef4678](cef4678))
* **test-helpers:** extract shared BATS helpers to @baleen/bats-helpers package ([19f2a62](19f2a62))
* **tests:** run plugin tests in parallel using background processes ([04be773](04be773))

### Performance Improvements

* **tests:** add caching to improve test execution speed ([9bbee5b](9bbee5b))

### BREAKING CHANGES

* Release workflow now requires merging Release Please PRs
instead of automatic releases on push to main.

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
baleen37 added a commit to baleen37/memmem that referenced this pull request Feb 15, 2026
* chore: prepare for 5.0.0 release

* chore(release): 5.0.0

# [5.0.0](baleen37/bstack@v4.3.0...v5.0.0) (2026-02-05)

### Bug Fixes

* **ci:** disable strict status checks to allow semantic-release commits ([7b296a4](baleen37/bstack@7b296a4))
* **ci:** merge Release workflow into CI workflow with proper dependency ([906673e](baleen37/bstack@906673e))
* **ci:** trigger CI on release-please PRs using workflow_run ([33ff7d3](baleen37/bstack@33ff7d3))
* **ci:** update branch protection to match GitHub Actions status check format ([13efcf5](baleen37/bstack@13efcf5))
* enable glob pattern for plugin.json version updates ([86fd628](baleen37/bstack@86fd628))
* **handoff:** output notification to stderr to exclude from LLM context ([463bb08](baleen37/bstack@463bb08))
* **marketplace:** remove databricks plugin reference ([f0bc6b8](baleen37/bstack@f0bc6b8))
* **ralph-loop:** fix hooks matcher and stdin handling ([326a570](baleen37/bstack@326a570))
* set release-please manifest to start from 4.3.0 ([#377](baleen37/bstack#377)) ([23a6cba](baleen37/bstack@23a6cba))

### Features

* **bash-lsp:** add Bash Language Server plugin ([#394](baleen37/bstack#394)) ([7770f3d](baleen37/bstack@7770f3d))
* **ci:** replace release-please with semantic-release ([35d346f](baleen37/bstack@35d346f))
* **conversation-memory:** add automatic npm install when node_modules missing ([db55514](baleen37/bstack@db55514))
* **conversation-memory:** add marked dependency for markdown rendering ([1887174](baleen37/bstack@1887174))
* **conversation-memory:** improve MCP installation error handling ([#373](baleen37/bstack#373)) ([16eb7b7](baleen37/bstack@16eb7b7))
* **conversation-memory:** reduce token usage in summarization ([d921bc7](baleen37/bstack@d921bc7))
* **conversation-memory:** reduce token usage in summarization ([b3a245b](baleen37/bstack@b3a245b))
* **handoff:** add session handoff plugin for context transfer ([#374](baleen37/bstack#374)) ([35cfb0c](baleen37/bstack@35cfb0c))
* **me:** add tdd and spawn commands ([#371](baleen37/bstack#371)) ([9af9bbe](baleen37/bstack@9af9bbe))
* migrate from semantic-release to Release Please ([#375](baleen37/bstack#375)) ([d20c736](baleen37/bstack@d20c736))
* **release-please:** add auto-merge for release PRs ([cef4678](baleen37/bstack@cef4678))
* **test-helpers:** extract shared BATS helpers to @baleen/bats-helpers package ([19f2a62](baleen37/bstack@19f2a62))
* **tests:** run plugin tests in parallel using background processes ([04be773](baleen37/bstack@04be773))

### Performance Improvements

* **tests:** add caching to improve test execution speed ([9bbee5b](baleen37/bstack@9bbee5b))

### BREAKING CHANGES

* Release workflow now requires merging Release Please PRs
instead of automatic releases on push to main.

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* refactor(bash-lsp): migrate from MCP to LSP configuration

- Remove .mcp.json file
- Add lspServers field to plugin.json with bash-language-server config
- Add .bats extension support for BATS test files

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test(bats): add lspServers to allowed plugin.json fields

- Add lspServers to json_field_is_allowed function
- Update error message to include lspServers in allowed fields list

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: semantic-release-bot <semantic-release-bot@martynus.net>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant