gh-cli: implement the six release operations so /dev:promote can run on GitHub #69

Open
opened 2026-08-25 14:02:21 +00:00 by jbr870 · 0 comments
Owner

PREQ: gh-cli — implement the six release operations so /dev:promote can run on GitHub

Created: 2026-08-25

Problem

/dev:promote cannot run on a GitHub project at all. The gh-cli adapter implements none of the
six release operations the forge contract defines:

primitive glab-cli local-fs tea-cli gh-cli
pr_create
pr_status
pr_merge
comment_on_pr
pipeline_status
release_create

gh-cli/SKILL.md's capability manifest lists fourteen operations and does not mention the release ops
at all
— not even as unsupported, which it does use for the two wiki ops. So the gap is invisible in
the one place a reader would look for it.

The contract states that declaring a release op unsupported "is caught at /dev:setup when the project
declares a release: block — or when it declares uat: { open_pr: true }", which puts pr_create,
pr_status and comment_on_pr on /dev:integrate's review path as well. That means the gap is not
confined to /dev:promote: a GitHub project that declares open_pr: true loses /dev:integrate's review
path too.

Why now: most repositories on the Forgejo instance are being migrated to GitHub (decided
2026-08-25). Today the gap is theoretical because no project declares forge.adapter: gh-cli with a
release: block. After the migration it is the first thing a release run hits.

Users:

  • Primary: the operator driving /dev:promote (and /dev:integrate's review path) on a GitHub-hosted
    project after the migration.

Current state: untested — no GitHub project has reached a release run. Whatever the failure looks like,
it happens at the moment someone is trying to ship.

Proposed Solution

Implement the six release primitives for gh-cli against the gh CLI / GitHub REST API, declare them in
the adapter's capability manifest, and prove them with a live smoke test against a real GitHub repository —
the same shape as glab-cli/test/release-smoke.sh.

Scope: to be assessed when this is picked up. The natural split is the /dev:integrate review-path
three
(pr_create, pr_status, comment_on_pr) versus the /dev:promote release three (pr_merge,
pipeline_status, release_create), which may be worth shipping as two slices — GitHub Actions is a
different enough model from GitLab pipelines that pipeline_status deserves its own design pass.

Notes

  • Sibling of #47 (release-pipeline-status — an answer that says what it is an answer about). Filed
    out of that feature's requirements session on 2026-08-25 rather than folded into it: #47 is honesty
    work in the shared tier (make an absent capability expressible), this is implementation work in one
    adapter. Doing gh-cli's pipeline_status slice inside #47 would mean designing GitHub's release
    surface twice.
  • Depends on #47 landing first for pipeline_status's answer shape: #47 adds commit identity to the
    response and separates "no pipeline yet" from "no CI", so a gh-cli implementation written before it
    would be written against a shape that is about to change.
  • Requirements not yet gathered. This issue is a scoped stub — run /dev:requirements --issue=<this>
    when it is picked up.
# PREQ: gh-cli — implement the six release operations so /dev:promote can run on GitHub **Created:** 2026-08-25 ## Problem **`/dev:promote` cannot run on a GitHub project at all.** The `gh-cli` adapter implements none of the six release operations the forge contract defines: | primitive | `glab-cli` | `local-fs` | `tea-cli` | `gh-cli` | |---|---|---|---|---| | `pr_create` | ✓ | ✓ | ✗ | ✗ | | `pr_status` | ✓ | ✓ | ✗ | ✗ | | `pr_merge` | ✓ | ✓ | ✗ | ✗ | | `comment_on_pr` | ✓ | ✓ | ✗ | ✗ | | `pipeline_status` | ✓ | ✓ | ✗ | ✗ | | `release_create` | ✓ | ✓ | ✗ | ✗ | `gh-cli/SKILL.md`'s capability manifest lists fourteen operations and **does not mention the release ops at all** — not even as `unsupported`, which it does use for the two wiki ops. So the gap is invisible in the one place a reader would look for it. The contract states that declaring a release op `unsupported` "is caught at `/dev:setup` when the project declares a `release:` block — **or** when it declares `uat: { open_pr: true }`", which puts `pr_create`, `pr_status` and `comment_on_pr` on `/dev:integrate`'s **review path** as well. That means the gap is not confined to `/dev:promote`: a GitHub project that declares `open_pr: true` loses `/dev:integrate`'s review path too. **Why now:** most repositories on the Forgejo instance are being **migrated to GitHub** (decided 2026-08-25). Today the gap is theoretical because no project declares `forge.adapter: gh-cli` with a `release:` block. After the migration it is the first thing a release run hits. **Users:** - **Primary:** the operator driving `/dev:promote` (and `/dev:integrate`'s review path) on a GitHub-hosted project after the migration. **Current state:** untested — no GitHub project has reached a release run. Whatever the failure looks like, it happens at the moment someone is trying to ship. ## Proposed Solution Implement the six release primitives for `gh-cli` against the `gh` CLI / GitHub REST API, declare them in the adapter's capability manifest, and prove them with a live smoke test against a real GitHub repository — the same shape as `glab-cli/test/release-smoke.sh`. **Scope:** to be assessed when this is picked up. The natural split is *the `/dev:integrate` review-path three* (`pr_create`, `pr_status`, `comment_on_pr`) versus *the `/dev:promote` release three* (`pr_merge`, `pipeline_status`, `release_create`), which may be worth shipping as two slices — GitHub Actions is a different enough model from GitLab pipelines that `pipeline_status` deserves its own design pass. ## Notes - **Sibling of #47** (`release-pipeline-status` — an answer that says what it is an answer about). Filed out of that feature's requirements session on 2026-08-25 rather than folded into it: #47 is *honesty* work in the shared tier (make an absent capability expressible), this is *implementation* work in one adapter. Doing `gh-cli`'s `pipeline_status` slice inside #47 would mean designing GitHub's release surface twice. - **Depends on #47 landing first** for `pipeline_status`'s answer shape: #47 adds commit identity to the response and separates "no pipeline yet" from "no CI", so a `gh-cli` implementation written before it would be written against a shape that is about to change. - **Requirements not yet gathered.** This issue is a scoped stub — run `/dev:requirements --issue=<this>` when it is picked up.
Sign in to join this conversation.
No description provided.