Skip to content

fix(janitor): reconcile #26/#50/#54 — stale-diff conflicts, no content overlap - #69

Merged
asachs01 merged 1 commit into
mainfrom
fix/janitor-triconflict-reconcile
Aug 31, 2026
Merged

fix(janitor): reconcile #26/#50/#54 — stale-diff conflicts, no content overlap#69
asachs01 merged 1 commit into
mainfrom
fix/janitor-triconflict-reconcile

Conversation

@asachs01

@asachs01 asachs01 commented Aug 31, 2026

Copy link
Copy Markdown
Member

Summary

#26, #50, and #54 were all open with mergeable: CONFLICTING against current main (tip 692c0d0 at investigation time). None of their real changes overlap line-for-line — the conflicts are stale-diff artifacts of main moving on since each PR's fork point, most significantly #66's dual-org repo-enumeration restructure of dependabot-janitor.sh. This PR reapplies all three fixes' actual intent by hand onto current main, in dependency order.

#54 — classify() group-PR hardening (fix/janitor-group-perdep-rebased, supersedes #23)

A Dependabot "group" PR title (e.g. "bump the dev-dependencies group with 12 updates") no longer proves the PR is minor/patch — the title doesn't list the dependencies. classify() now fetches the PR body over REST (outage-resilient vs. gh pr view's GraphQL) and requires every per-dependency Updates \pkg` from A to Bmarker to be same-major, failing closed on any cross-major, unparseable marker, zero markers, or a failed fetch. This is the fix for the realnode-datto-rmm#46incident, where a "group" title unconditionally short-circuited toELIGIBLE` and auto-merged a hidden major that broke main.

Reapplied verbatim from #54's diff except one adaptation: the body fetch now calls gh api "repos/$repo/pulls/$num" directly, since $repo is already "org/name" post-#66's dual-org restructure, instead of #54's original single-org repos/$ORG/$repo/pulls/$num (which would reference an undefined $ORG under set -u in the current file, or double/misdirect the org).

Also adds .github/scripts/dependabot-janitor.test.sh (14 assertions, fixtures from real Dependabot PR bodies) — verified byte-identical to #54's original test file aside from that same $ORG$repo adaptation (and dropping the now-unused ORG= assignment, which also fixes a shellcheck SC2034 warning #54's original had). All 14 assertions pass unmodified against the reconciled script.

#50 — cortextos/conduit scope carve-out (fix/dependabot-janitor-scope-cortextos-conduit)

cortextos and conduit don't match the janitor's repo-selection regex (-mcp$|^mcp|^node-) and get zero Dependabot auto-merge coverage as a result (task_1785692635899_03153380). #50's own diff targets the pre-#66 single-org grep pipeline and no longer applies — reapplied by hand as |^cortextos$|^conduit$ added to the still-present grep -E call, now living inside the for _org in $ORGS multi-org loop #66 introduced. Confirmed both repos currently live under WYRE-AI (one of the two default ORGS), so the carve-out is reached by the existing enumeration without further changes.

#26 — mcp-server-release.yml always() gating (fix/release-resilient-artifact-gating)

A non-fatal failure after semantic-release cuts a release (e.g. a flaky/duplicate git-notes push — "cannot lock ref refs/notes/semantic-release-…: reference already exists") previously failed the Semantic Release step even though the release was already complete, which then skipped the (unconditional) Detect released version step, left released unset, and cascaded into skipping docker/mcp-registry/security — a published version with no image, no registry listing, no deploy.

Fix: the detect step now runs with if: always(), and docker's gate is if: always() && needs.release.outputs.released == 'true'.

Double-id: detect investigation: the current workflow (877 lines vs. #26's much smaller base) does carry a second step named id: detect, inside a mcpb job added after #26 was opened. Read both in full — it is not a duplicate release-detection block. It's an unrelated step ("Detect MCPB support") that checks for a pack:mcpb script in package.json, scoped to its own job. #26's fix applies to exactly the one release-detection occurrence and the one docker gate it always targeted; nothing was duplicated blindly.

Flagged (not fixed, out of scope for this reconciliation): the mcpb job's own gate (if: needs.release.outputs.released == 'true') has an analogous latent exposure to the same post-release-hiccup skip, since it also needs: [release] without always(). It didn't exist when #26 was authored and isn't part of any of the three PRs' original content — noted in the CHANGELOG entry and here for a possible follow-up.

Verification

Test plan

  • shellcheck on the reapplied shell script and new test script
  • dependabot-janitor.test.sh — 14/14 assertions pass
  • YAML parse of mcp-server-release.yml
  • Manual read of the gating logic (detect step, docker job, mcpb job) to confirm scope
  • Byte-for-byte comparison of reapplied classify() and new test file against fix(janitor): classify grouped PRs per-dependency, fail-closed (supersedes #23) #54's original content
  • Human review — not merged, left for review per the task that produced this PR

🤖 Generated with Claude Code


View with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is enabled.

…ent overlap

Three open PRs (#26, #50, #54) all showed mergeable=CONFLICTING against
current main. None of their real changes overlap line-for-line — the
conflicts are purely stale-diff artifacts of main having moved on since
each PR's fork point (#66's dual-org repo-enumeration restructure in
particular). This reapplies all three fixes' actual intent by hand onto
current main, in dependency order (both #50 and #54 touch
dependabot-janitor.sh).

#54 (classify() group-PR hardening, supersedes #23): a Dependabot "group"
PR title no longer proves minor/patch. classify() now fetches the PR body
via REST and requires every per-dependency "from A to B" marker to be
same-major, failing closed otherwise. Reapplied verbatim except the body
fetch now calls `repos/$repo/pulls/$num` directly (since $repo is already
"org/name" post-#66) instead of #54's original `repos/$ORG/$repo/...`.
Adds dependabot-janitor.test.sh (14 assertions, real fixtures) — verified
byte-identical to #54's original test file aside from that same $ORG->
$repo adaptation; all 14 assertions pass unmodified.

#50 (cortextos/conduit scope carve-out): reapplied by hand onto the
current multi-org enumeration loop (#66) rather than #50's own stale
single-org grep pipeline — added `|^cortextos$|^conduit$` to the
still-present grep -E inside the `for _org in $ORGS` loop.

#26 (mcp-server-release.yml always() gating): the release job's "Detect
released version" step now runs with `if: always()`, and the docker job's
gate is `if: always() && needs.release.outputs.released == 'true'`, so a
non-fatal failure after semantic-release cuts a release (e.g. a flaky
git-notes push) can't silently skip artifact publishing. Investigated the
apparent second `id: detect` in the current file: it is an unrelated step
in the (post-#26) mcpb job that checks for a pack:mcpb script, not a
duplicate release-detection block — #26's fix applies to exactly the one
occurrence it always targeted. Flagged in the CHANGELOG that mcpb's own
released=='true' gate has an analogous latent exposure, left out of scope
here since it predates neither #26 nor this reconciliation.

Verified: shellcheck clean on dependabot-janitor.sh (baseline was already
clean); dependabot-janitor.test.sh carries only pre-existing info-level
notices inherited from #54's original file (one pre-existing SC2034
warning was fixed by dropping the now-unused $ORG var); all 14 tests
pass; mcp-server-release.yml parses as valid YAML.

Refs: #26, #50, #54
@asachs01
asachs01 merged commit b9a4bdf into main Aug 31, 2026
4 checks passed
@asachs01
asachs01 deleted the fix/janitor-triconflict-reconcile branch August 31, 2026 15:31
@github-project-automation github-project-automation Bot moved this from Todo to Done in MSP Claude Plugins Aug 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant