release-kit 0.1.0

A canonical release workflow: a technology-agnostic method, per-technology bindings, and the rk CLI that lands and serves them.
Documentation
#!/usr/bin/env sh
# Protect the trunk. It takes no direct push and no force-push: a pull
# request carrying the named passing check is the only way in, and squash is
# the only merge method, so the trunk history stays linear on a forge that
# offers no fast-forward merge. Nothing in the pipeline writes this branch —
# the bot pushes a tag, which release-tags governs — so it names no bypass
# actor. The method's invariants chapter owns these facts; this comment
# points there. Rerunning updates in place.
set -eu
: "${RK_REPO:?rk sets this; run this script through rk setup}"
: "${RK_TRUNK_BRANCH:?rk sets this; run this script through rk setup}"
: "${RK_REQUIRED_CHECK:?rk sets this from --required-check}"

name="$RK_TRUNK_BRANCH-protection"
id="$(gh api "repos/$RK_REPO/rulesets" -q ".[] | select(.name == \"$name\") | .id" | head -n 1)"

if [ -n "$id" ]; then
  gh api -X PUT "repos/$RK_REPO/rulesets/$id" --input - >/dev/null
else
  gh api -X POST "repos/$RK_REPO/rulesets" --input - >/dev/null
fi <<JSON
{
  "name": "$name",
  "target": "branch",
  "enforcement": "active",
  "bypass_actors": [],
  "conditions": {
    "ref_name": { "include": ["refs/heads/$RK_TRUNK_BRANCH"], "exclude": [] }
  },
  "rules": [
    { "type": "deletion" },
    { "type": "non_fast_forward" },
    {
      "type": "pull_request",
      "parameters": {
        "required_approving_review_count": 0,
        "dismiss_stale_reviews_on_push": false,
        "require_code_owner_review": false,
        "require_last_push_approval": false,
        "required_review_thread_resolution": false,
        "require_extra_approval_for_unattributed_changes": false,
        "allowed_merge_methods": ["squash"]
      }
    },
    {
      "type": "required_status_checks",
      "parameters": {
        "do_not_enforce_on_create": true,
        "strict_required_status_checks_policy": false,
        "required_status_checks": [{ "context": "$RK_REQUIRED_CHECK" }]
      }
    }
  ]
}
JSON

echo "check: prints $name"
gh api "repos/$RK_REPO/rulesets" -q ".[] | select(.name == \"$name\") | .name"