Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions .github/workflows/plugin-version-bump-gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@

name: Plugin Version Bump Gate

# OMN-16913. The Claude Code plugin cache is keyed on the manifest version, so a
# change under plugins/onex/ that lands without a bump never reaches an installed
# cache. This fails a pull request that changes plugins/onex/ (tests and bytecode
# excepted) without raising plugins/onex/.claude-plugin/plugin.json `version`
# above its merge-base value, or whose dev marketplace entry pins another version.
# OMN-20710 (port of OMN-20497): refuse a lowered or broken plugin version or
# disagreement between plugin.json and the onex dev marketplace entry. PRs no
# longer bump the version; post-merge plugin-version-bump.yml does in one bot PR.
# Resolve version-line conflicts by taking dev's value in both files.
#
# No `paths:` filter, deliberately: a filtered gate under a context something
# waits for is skip-vector 1 (see hook-inventory-gate.yml). The job is a
Expand Down Expand Up @@ -47,7 +46,7 @@ jobs:
with:
python-version: '3.12'

- name: Require a plugin version bump for plugin changes
- name: Refuse lowered or broken plugin versions and marketplace disagreement
env:
BASE_REF: ${{ github.event.pull_request.base.sha || github.event.before }}
run: |
Expand Down
152 changes: 152 additions & 0 deletions .github/workflows/plugin-version-bump.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# SPDX-FileCopyrightText: 2026 OmniNode.ai Inc.
# SPDX-License-Identifier: MIT
#
# OMN-20710: port the OMN-20497 post-merge bot bump from the internal repo.
# Operator RULING 2026-10-08T03:53:09Z lane=orchestrator-716d: one bot bump PR
# after each dev merge; the per-PR check refuses only a lowered or broken version
# (and disagreement between the two version files). PRs no longer claim the
# same next version and knock each other red when one merges.
# Lane cause-claude-bump-2245 measured 47 of dev's 161 merges since 2026-09-30
# setting the plugin version.
#
# The version-keyed plugin cache still needs a bump for shipped changes. Run the
# validator's own --bump-to-base against the last dev commit that set the version,
# raising plugin.json and the dev marketplace entry together in one fixed bot PR.
# There is no hold: every dev merge is checked, with a schedule as a delivery
# backstop. Update the branch only when its versions differ or it conflicts with
# dev; each push reruns full CI and dev does not require branches up to date.
# Close the PR when dev already carries a version for every merged change.

name: Plugin Version Bump

on:
push:
branches: [dev]
schedule:
- cron: '*/30 * * * *' # Backstop for a push event GitHub did not deliver.
workflow_dispatch: {}

permissions:
contents: read

concurrency:
group: plugin-version-bump
cancel-in-progress: false

jobs:
plugin-version-bump:
name: plugin-version-bump
runs-on: ${{ fromJSON(vars.OMNI_TRUSTED_CI_RUNS_ON_JSON || '["self-hosted","omnibase-ci"]') }}
timeout-minutes: 15
env:
BUMP_BRANCH: automation/omn-20710-plugin-version-bump
steps:
- name: Mint onexbot-occ-writer app token
id: app-token
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
app-id: ${{ secrets.ONEXBOT_OCC_APP_ID }}
private-key: ${{ secrets.ONEXBOT_OCC_PRIVATE_KEY }}
owner: OmniNode-ai
repositories: omniclaude
permission-contents: write
permission-pull-requests: write
# A force-push onto newer dev carries whatever workflow files dev changed
# in between; GitHub refuses that from an App without this scope.
permission-workflows: write

# Full history: find the version-setting commit with git log over the manifest.
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: dev
fetch-depth: 0
token: ${{ steps.app-token.outputs.token }}

- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: '3.12'

- name: Bump onex changed since its version was last set
id: bump
run: |
set -euo pipefail
log="${RUNNER_TEMP}/plugin-version-bump.log"
: > "$log"
last="$(git log -1 --format=%H -G'"version"' -- plugins/onex/.claude-plugin/plugin.json)"
if [ -z "$last" ]; then
echo "::error::no commit on dev sets the version in plugins/onex/.claude-plugin/plugin.json"
exit 1
fi
python scripts/validation/validate_plugin_version_bump.py --base "$last" --bump-to-base | tee -a "$log"
if git diff --quiet; then
echo "changed=false" >> "$GITHUB_OUTPUT"
else
echo "changed=true" >> "$GITHUB_OUTPUT"
fi

- name: Open, update or close the one bump pull request
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
REPO: ${{ github.repository }}
CHANGED: ${{ steps.bump.outputs.changed }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
set -euo pipefail
open="$(gh pr list --repo "$REPO" --base dev --head "$BUMP_BRANCH" --state open --json number --jq '.[0].number // empty')"
if [ "$CHANGED" != "true" ]; then
echo "dev already carries a version for every merged plugin change."
if [ -n "$open" ]; then
gh pr close "$open" --repo "$REPO" --delete-branch \
--comment "dev already carries a version for every merged plugin change, so this bump is no longer needed (OMN-20710). Closed by ${RUN_URL}"
fi
exit 0
fi
tip="$(git rev-parse HEAD)"
live="$(git ls-remote origin refs/heads/dev | cut -f1)"
if [ "$live" != "$tip" ]; then
echo "dev moved from $tip to $live during this run; the run that push queued rebuilds the bump."
exit 0
fi
git config user.name "onexbot-occ-writer[bot]"
git config user.email "307849072+onexbot-occ-writer[bot]@users.noreply.github.com"
{
echo "chore(OMN-20710): post-merge plugin version bump"
echo
grep '^bumped ' "${RUNNER_TEMP}/plugin-version-bump.log"
} > "${RUNNER_TEMP}/plugin-version-bump.msg"
git commit -q -a -F "${RUNNER_TEMP}/plugin-version-bump.msg" \
--trailer "Onex-Workflow: ${GITHUB_WORKFLOW}" --trailer "Onex-Run: ${RUN_URL}"
remote="$(git ls-remote origin "refs/heads/${BUMP_BRANCH}" | cut -f1)"
if [ -n "$remote" ]; then
git fetch -q origin "+refs/heads/${BUMP_BRANCH}:refs/remotes/origin/${BUMP_BRANCH}"
fi
if [ -n "$remote" ] && \
git diff --quiet "$remote" HEAD -- plugins/onex/.claude-plugin/plugin.json plugins/*-marketplace/.claude-plugin/marketplace.json && \
git merge-tree --write-tree "$remote" HEAD > /dev/null; then
echo "${BUMP_BRANCH} already carries this bump without a conflict with dev; nothing to push."
else
git push --force origin "HEAD:refs/heads/${BUMP_BRANCH}"
fi
if [ -n "$open" ]; then
echo "Updated #${open} in place."
exit 0
fi
printf '%s\n' \
"## Summary" \
"" \
"Automated post-merge plugin version bump. PRs no longer bump plugins/onex. This one bot PR raises plugins/onex/.claude-plugin/plugin.json and the onex entry in plugins/*-marketplace/.claude-plugin/marketplace.json together so the version-keyed plugin cache delivers merged changes." \
"" \
"Kept open as the single bump PR, updated in place when the next version changes, and closed when dev needs no bump." \
"" \
"## Ticket" \
"" \
"OMN-20710 (port of OMN-20497)" \
"" \
"## Triggered by" \
"" \
"${RUN_URL}" \
"" \
"Evidence-Ticket: OMN-20710" > "${RUNNER_TEMP}/plugin-version-bump.body"
gh pr create --repo "$REPO" --base dev --head "$BUMP_BRANCH" \
--title "chore(OMN-20710): post-merge plugin version bump" \
--body-file "${RUNNER_TEMP}/plugin-version-bump.body"
8 changes: 4 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1240,11 +1240,11 @@ repos:
always_run: true
stages: [pre-commit]

# OMN-16913: a change under plugins/onex needs a plugin version bump. The
# plugin cache is version-keyed, so an unbumped change never reaches an
# installed cache. Same validator runs in CI (plugin-version-bump-gate.yml).
# OMN-20710: refuse lowered or broken versions and marketplace disagreement.
# PRs no longer bump; plugin-version-bump.yml does after merging to dev.
# Same validator runs in CI (plugin-version-bump-gate.yml).
- id: plugin-version-bump-gate
name: Plugin version bump (OMN-16913)
name: Plugin version not lowered or broken (OMN-20710)
entry: bash scripts/uv-run-worktree-safe.sh python scripts/validation/validate_plugin_version_bump.py --base origin/dev --defer-to-workflow-in-ci
language: system
pass_filenames: false
Expand Down
5 changes: 5 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,11 @@ python3 -c "import yaml; print(list(yaml.safe_load(open('.github/workflows/ci.ym

- Branch protection aggregates through gate jobs (**Quality Gate**, **Tests Gate**, **Security Gate**, CI Summary) declared in `.github/required-checks.yaml`. Gate names are API-stable — do not rename without the Branch Protection Migration Safety procedure in knowledge-base `reference/omniclaude-ci-cd-standards.md`.
- Standalone lint gates (hook log paths, skill MCP references, verification evidence, plan verified-state) live in their own workflows AND run as pre-commit hooks; if one fires, fix the underlying issue, never bypass.
- PRs do not bump the onex plugin version (OMN-20710, port of OMN-20497). After a change lands on dev,
`.github/workflows/plugin-version-bump.yml` raises `plugins/onex/.claude-plugin/plugin.json` and the onex entry in
`plugins/*-marketplace/.claude-plugin/marketplace.json` together in one bot PR (`automation/omn-20710-plugin-version-bump`).
The Plugin Version Bump Gate refuses only a lowered or non-numeric version or the two files disagreeing;
resolve a version-line conflict by taking dev's value.
- CI uv version: read the pin from `.github/workflows/ci.yml` before lock-file changes; ruff behavior may differ local vs CI.
- Never remove branch-protection rules after adding them; flag temporary rules to the user.

Expand Down
Loading
Loading