ptr727/plexcleaner/branching-and-release-model

Claude Code and agent skill by ptr727/plexcleaner

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Governs how a ptr727/ProjectTemplate fleet repo branches, promotes, and publishes: the feature -> develop -> main flow, squash-only vs. merge-commit-only branch protection, the promotion traps (never delete develop, EOL-only conflicts), the two-phase publish model (PRs smoke-test only, a human merge never auto-publishes), NBGV versioning, and the operational-repo delta (direct-to-develop commits, advisory CI, dispatch-only release) that applies whenever the registry's workflowModel reads operational. Use this whenever choosing a target branch, promoting develop to main, resolving a promotion conflict, deciding whether a config change needs a PR or can commit straight to develop, bumping version.json, adding or dropping a release target, or reasoning about why a merge did or didn't publish. Triggers even when the request sounds like ordinary git housekeeping ("just push this config fix", "merge develop into main"), because the two workflow models genuinely differ and a step correct in one is a rule violation in the other. This is the git policy: `workflow-ci-contract` keeps the YAML half, and performing a promotion merge or a release dispatch is `merge-and-release`, which wins where both fire.

Install

npx vskill@latest install ptr727/plexcleaner/branching-and-release-model

SKILL.md

Branching and Release Model

Why this exists

Two workflow models exist because the underlying repos are two different things. Most fleet repos ship versioned units of delivery, so they earn a feature -> develop -> main flow with real release gates. A handful of repos instead track a live service's running state (Home Assistant, ESPHome, Vantage, home automation configs). There the "release" is the config already committed, not something built and shipped later. Applying the release model's ceremony to an operational repo is wrong there and correct in a release repo. Skipping the release model's gates on a repo that actually ships versioned artifacts is wrong there and correct in an operational repo. That is why this is one skill keyed on which repo you're in rather than two skills that never talk to each other.

Which model this repo uses

Read the registry workflowModel field for this repo (release, the default, or operational). The rest of this skill's "Branching" and "Publishing" sections describe the release model. The "Operational repositories" section below is the complete delta for operational repos. Anything not mentioned there is unchanged. When in doubt which one applies, check registry/repos.json rather than guessing from the repo's contents.

Branching (release model)

  • GitHub's repository setting for "default branch" reads `main`, but `develop` is where work starts and where in-flight content lives. A worktree or clone that defaults to "the default branch" lands on main. It can silently miss content that has merged to develop but not yet been promoted. Before branching off a change, or asserting something absent from this repo, check develop, not just whichever branch a tool defaulted to. See GOVERNANCE.md "Verification Discipline" on naming the branch a "does not exist" claim was checked against. See also the repo-worktree skill, which owns the worktree-creation moment this base-branch choice is made at.
  • develop is the integration branch. Feature branches -> develop is squash-only, which

keeps develop linear.

  • develop -> main is merge-commit only (no squash, no rebase). Merge commits preserve

develop's commit list as a real second-parent reference on main. That lets the release model attribute releases to the develop commits that produced them. Branch protection enforces this: the develop ruleset allows only squash, the main ruleset allows only merge.

  • All commits on both branches must be cryptographically signed (SSH or GPG), see

git-commit-conventions. Squash and merge commits created via the GitHub UI are signed by GitHub's web-flow key.

  • `develop` is forward-only, with no `main -> develop` back-merges. The develop ruleset's

squash-only setting physically blocks merge commits on develop. Any historical back-merge commits in git log predate this rule and must not be repeated.

  • Never delete `develop`, and take the EOL-only conflict by taking develop's side. A

promotion PR's head is develop, so --delete-branch deletes it. An EOL-only conflict on a workflow YAML file resolves on a throwaway branch off main, not on develop. Full recovery and conflict-resolution commands: references/branch-protection-and-promotion.md.

  • A merge or release ends with worktree cleanup and the base clone on current `develop`. Run the repo-worktree post-merge procedure after a feature squash merge. Run it again after a promotion or release completes, unless the user explicitly asks to retain a checkout or branch. Remove finished task, conflict-resolution, installer, and release helpers. Never delete develop, and never leave the base clone on main merely because main was promoted or released.
  • **Issue-closing keywords (Closes #N, Fixes #N) go in the develop -> main promotion PR, not

the feature -> develop PR. GitHub auto-closes an issue only when the closing keyword merges into the default branch** (main), so a feature -> develop PR merge never fires it. Reference the issue in the develop PR body if useful, but the actual closing keyword belongs on the promotion PR. Closing by hand is the ordinary route wherever the keyword cannot fire. Cases include a promotion that already merged without it, or completed work with no promotion imminent. Closing by hand is not a repair for a botched promotion. Cite the squash SHA and re-read that commit before closing.

  • Neither ruleset requires branches to be up to date before merging. The reasons differ on

each branch (a graph-based check that would fail every release on main, a check that stalls bot auto-merge on develop). Detail: references/branch-protection-and-promotion.md.

  • Configuring branch protection: import the committed ruleset payloads, don't hand-build them.

Exactly two rulesets, named develop and main. Full procedure, including the operational develop payload and the brownfield-repo signing caveat: references/branch-protection-and-promotion.md.

  • Dependabot and codegen target both `main` and `develop` in parallel. Each branch absorbs

its own bot PRs independently so neither falls behind. The merge-bot dispatches the merge form (--squash/--merge) that matches each PR's base ruleset. Codegen output must be deterministic from its inputs alone, never per-run state, or the two branches' legs conflict on every promotion. Full mechanics: references/branch-protection-and-promotion.md.

  • App-token workflows authenticate with Client ID, not the deprecated App ID. Use

client-id: ${{ secrets.CODEGEN_APP_CLIENT_ID }} at any new App-token call site.

Publishing (release model)

  • The two-phase model is the default: PRs build fast, publishing is batched. A PR only

smoke-tests (unit tests plus a reduced build of the changed targets), it never pushes anything. publish-release.yml is the sole publisher, and each run builds a single trigger branch (main a release, develop a prerelease).

  • A human merge never auto-publishes. Publishing fires on a `workflow_dispatch` of

main/develop (a human-initiated release). Publishing also fires on a code-affecting bot push to `main` (the codegen App merging a Dependabot/codegen PR). That trigger is gated on github.actor so a human merge/promotion skips it. Publishing also fires on a weekly `schedule` (Docker only, to refresh the base image). A source-only repo publishes on dispatch only.

  • The changes-detection job is a required check that must succeed, not just not fail. A

paths-filter error must never let a target-changing PR merge with its smoke build silently skipped. A skipped smoke job (no matching change) passes, failure/cancelled blocks.

  • Versioning is semantic and maintainer-controlled. version.json's major.minor is the

version floor. The maintainer edits it for functional changes only, in the PR that introduces the work, never on a fixed cadence or mechanically after a release. NBGV appends the git height automatically on every commit. So a release always gets a fresh build version with no post-release bump and no develop-ahead requirement.

  • Docs reference the 2-digit `major.minor` line, never a 3-digit build. README.md,

HISTORY.md, and release notes name the version as Version 1.0 (the floor), never the concrete build height. That height is both wrong (the real height differs) and a maintenance trap. "Correcting" 1.0 to 1.0.0 is a defect.

  • **A no-op publish (unchanged NBGV SemVer2) on a schedule or push trigger re-pushes nothing to

any target keyed on the version string.** Docker is the exception: it always re-pushes (a dispatch refreshes the release instead of skipping) to pick up upstream base-image refreshes. Full guarantee and the version.json pathFilters boundary: references/release-publish-mechanics.md.

  • A package push can fail after the release is already cut, since it runs after the release

task and no gate covers it. A full re-run is always available inside its bounded window and is the only route once the branch tip has moved: references/release-publish-mechanics.md.

  • Adding, dropping, or wiring a release target is covered in

references/release-publish-mechanics.md: which leaf task, which artifact-naming contract, which seam a given output belongs to. Tracking an upstream release from a wrapper repo is covered there too. Seams are a GitHub Release asset, a package-registry push, an image-registry push, a filesystem deploy, or a source-only repo with no build layer at all. See also WORKFLOW.md for the full CI/CD contract this section's rules are load-bearing excerpts of.

Operational repositories (the complete delta)

Everything above is the release model. An operational repo (registry workflowModel: operational) tracks a live service's running state rather than shipping versioned units of delivery. It differs from the release model in exactly these ways, and everything not listed here stays the same:

  • Commit configuration directly to `develop`. There is no feature branch requirement, the

maintainer commits straight to develop, and only occasionally opens a develop -> main PR to bless a known-good snapshot. The develop ruleset drops the PR and status-check gate, so direct signed pushes are allowed (force-push, deletion, and unsigned commits are still blocked). CI runs on the push as advisory feedback that never rejects a commit.

  • A PR into `develop` stays available, and CI runs on it, reported but not required. Dropping

the requirement permits the direct push. It does not withdraw the pull request, so a change worth reviewing takes one and both paths into develop are legitimate.

  • **Take the pull request whenever the change is not one a reader takes in at a glance and

reverts cleanly.** What decides it is the shape of the change, not a line count. Restructuring rather than adjusting a value is the pull request case. So is touching several files at once. So is introducing a device, an integration, or an automation that did not exist before. So is anything whose failure shows up on the live service rather than in a lint run. So is a change the author cannot state in one sentence. This stays a judgment call by design because a pull_request rule added to the operational develop ruleset would gate the direct push too. That would withdraw the allowance the model exists to give.

  • The `main` promotion gate is unchanged. The shared main ruleset still enforces the

required Check pull request workflow status job on the develop -> main PR. For an operational repo that check is lint/validation only, never unit tests. It is editorconfig/EOL plus a domain linter such as a Home Assistant or ESPHome config validation. So develop stays the live surface and a broken config can never reach main.

  • Release only by manual dispatch. Operational repos carry releaseTrigger: dispatch-only and

run no codegen or auto-publish bots. They publish only on a manual workflow_dispatch (the same source-only release the publisher already supports: tag, source zip, README, LICENSE, NBGV-versioned), never automatically. The develop -> main promotion just blesses a known-good snapshot, a release is a separate, deliberate dispatch.

  • Fleet sync still applies. Dependabot's dual-target sync and the App-signed merge-bot run on

every tier, operational included. So both branches stay in sync and a promotion stays a clean forward merge.

  • Line-ending policy differs too, following the consuming app's native platform rather than the

fleet LF default, per the registry lineEndings field. That rule belongs to comment-and-doc-style, not repeated here.

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

7-day trend score
0

Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/ptr727/plexcleaner/branching-and-release-model/badge)](https://verified-skill.com/skills/ptr727/plexcleaner/branching-and-release-model)

Something wrong with this skill or its page? Tell us.