GitHub workflow delivery and enforcement: quick reference
How to realize tickets, kanban, pull-request delivery, durable context projections, and provider-native external enforcement on GitHub. These operations do not teach ticket, review, or PR content craft; they map finished artifacts and workflow intent onto GitHub-native resources.
- What a good review comment says (Conventional Comments labels, blocking vs non-blocking, summary plus inline, cross-linking) belongs to
code-review-guide. - What a good PR description says (sizing, how-tested, tradeoffs, self-review) belongs to
pull-request-guide. - The local-git push and rebase that get a clean branch onto the remote belong to
git-guide's push reference.
This skill only takes those finished artifacts and posts them through gh / gh api.
The one thing to internalize: a repository issue, a ProjectV2 item, a project Status field, a pull-request review, and a top-level context comment are separate native objects. Preserve and mutate their exact IDs separately; never turn project status into issue state, context into approval, or an issue comment into an inline review.
When this skill fires:
- Confirm the host is GitHub and auth works:
gh auth statusthen a real read call (gh api user), before any write. - Resolve the exact issue, project item/field, pull request, review thread, or comment identity before writing.
- Reach for
gh apiwhen high-level verbs cannot express the exact native operation. - Use an append-only top-level issue comment for durable context, not a review comment or verdict.
- Load the
references/*.mdfile matching the task, not everything upfront.
Requirements
ghauthenticated to the target host. First-time install +gh auth login+ protocol + clone + verify are in references/first-time-setup.md; token families, per-operation least-privilege scopes, and storage are in references/auth.md.- The git remote points at GitHub:
gh repo view --json nameWithOwner,urlresolves it; agithub.comhost (or a GHES host) ongit remote get-url originis the detection signal. For GHES, setGH_HOST/--hostnameand useGH_ENTERPRISE_TOKEN(see auth). - Projects operations require the
projectscope and explicit user or organization owner; refresh withgh auth refresh -s projectwhen appropriate.
Essentials
- Manage workflow tickets: create/reconcile repository issues; read and update assignees, labels, milestone, type, parent/sub-issue and blocking relationships; and preserve repository + number + node ID + URL + observed revision. See references/issues.md.
- Manage Projects kanban: resolve project, item, field, and option IDs; add each issue/PR once; set typed fields; distinguish Project Status from issue state; and report weak concurrency boundaries. See references/projects.md.
- Open a PR:
gh pr create --base <target> --head <source> --title ... --body-file -auto-pushes the branch if it isn't on the remote and sets reviewers/labels/assignees in one call; the rawPOST /repos/{owner}/{repo}/pullsdoes NOT push. See references/create.md. - Publish durable issue/PR context: use an append-only top-level issue comment,
give it a marker containing canonical ID/version/digest, reconcile exact retries,
and return its
html_urlfor later human or agent work. See references/context-comments.md. - Push / rebase first: the clean branch is
git-guide's job; this skill assumes the source branch builds on the latest target. Seegit-guide's push reference. - Post a structured review:
gh pr reviewonly carries the summary + verdict; batch the summary, every inline comment, and the verdict into onegh api ... /pulls/{n}/reviewsobject. See references/review-post.md. - Write the review content with code-review-guide: labels, severity, and blocking decoration are
code-review-guide's; this skill only anchors and submits them. - Write the PR body with pull-request-guide:
gh pr create --body-filetakes a description authored perpull-request-guide. - Resolve a thread: GraphQL-only
resolveReviewThreadby thread node id (PRRT_...), matched by id never by line; list threads withpullRequest.reviewThreads. See references/review-resolve.md. - Scope the token per operation: push needs Contents: write; open-PR / post-review need Pull requests: write; resolve also needs Contents: read & write on a fine-grained token. See references/auth.md.
- Enforce with native automation: use SHA-pinned reusable workflows/actions, required checks and layered rulesets, protected environments, least-privilege tokens/OIDC, attestations, and provider-native evidence. See references/automation-and-enforcement.md.
- Transact every setup: discover, preview the exact native changes and authority, authorize, apply idempotently against observed revisions, re-read and probe both allow and deny, retain rollback, and own the drift. See references/onboarding.md.
- Preserve provider conformance: map workflow tickets, kanban, changes, reviews, context, and evidence to their separate native identities and expose unsupported guarantees. See references/provider-conformance.md.
Gotchas
- A fine-grained PAT must have Contents: write to push commits/refs (
POST/PATCH .../git/refs,PUT .../contents). Contents: read is enough only to OPEN a PR and POST a review, never to push. gh pr edit --body/--body-filereplaces the whole description (never appends): fetch first (gh pr view N --json body -q .body), recombine, then set; metadata is incremental via paired--add-*/--remove-*flags.gh pr createis not create-or-update. It aborts non-zero if an open PR already exists for the branch; guard with|| gh pr view --json url -q .url. Only--webproceeds anyway, and--dry-run"may still push git changes".gh issue createis not create-or-update. Reconcile a stable body marker after an unknown result; GitHub does not enforce marker uniqueness, so concurrent creates still need one writer or an external lock.gh pr comment --edit-lastcan overwrite the authenticated identity's unrelated latest comment. Context publication is append-only: exact ID/version/digest is a no-op, same-version divergence blocks, and changed semantics create a successor.- Project item identity and Project Status are separate from issue identity and
open/closed state.
gh issue create --projectadds an item but does not replace explicit field discovery and update. - Project field edits have no general compare-and-swap. Re-read the item, field, and old value before apply and report the remaining race window.
gh pr reviewhas no inline support (cli/cli#12396) and the standalone.../pulls/{n}/commentsendpoint 422s online/sidepayloads (cli/cli#13358): put inline comments inside one.../reviewsobject.linein the reviews API is a file line number +side, NOT the deprecated diffposition(never compute position); a multi-line range needsstart_line/start_sideprecedingline/sidein the same hunk. Anchor to the PR HEAD sha or comments go "outdated".- You cannot APPROVE or REQUEST_CHANGES your own PR (HTTP 422): self-reviews are COMMENT-only.
- REQUEST_CHANGES blocks merge only under branch-protection / ruleset required reviews, and clears only via the same reviewer approving or a write-access dismiss (
PUT .../dismissals): another person's approval does not override it. - Thread resolution is GraphQL-only; on a fine-grained PAT / App token it also silently needs Contents: read & write or returns "Resource not accessible by integration" (community #44650). Classic
reposuffices. Closes #Nin the PR body auto-closes the issue only when the PR merges into the default branch; cross-repo needsCloses owner/repo#N. There is noghflag for it.- GitHub Enterprise Server uses GH_ENTERPRISE_TOKEN / GITHUB_ENTERPRISE_TOKEN, not GH_TOKEN: mixing them is the classic "works on github.com, 401 on GHES".
- Insufficient permission on a private repo returns 404 (not 403): GitHub hides existence; read the
X-Accepted-GitHub-Permissionsheader (gh api -i <endpoint>) for the exact required permission.
Example: open a PR, post a blocking inline review, resolve a thread
# 0. confirm the host is GitHub and you can read
gh repo view --json nameWithOwner,url -q '.url' # github.com/... or your GHES host
gh auth status && gh api user -q '.login'
# 1. open the PR (gh pushes feat/x if it isn't on the remote); idempotency guard
gh pr create --base main --head feat/x \
--title "feat: guard null user" --body-file pr-body.md \
--reviewer org/team-slug --assignee @me --label enhancement \
|| gh pr view feat/x --json url -q .url
# 2. post ONE review object: summary + inline comment + verdict (gh pr review can't do inline)
HEAD=$(gh pr view 123 --json headRefOid -q .headRefOid)
gh api --method POST repos/{owner}/{repo}/pulls/123/reviews \
-f commit_id="$HEAD" -f event=REQUEST_CHANGES \
-f body=$'## Summary\nOne blocking issue, see inline.' \
-f 'comments[][path]=src/app.ts' \
-F 'comments[][line]=42' \
-f 'comments[][side]=RIGHT' \
-f 'comments[][body]=**issue (blocking):** guard against a null `user` here.'
# 3. list threads, then resolve by node id (never by line): GraphQL only
gh api graphql -f query='query($o:String!,$r:String!,$n:Int!){repository(owner:$o,name:$r){pullRequest(number:$n){reviewThreads(first:100){nodes{id isResolved path comments(first:1){nodes{databaseId body}}}}}}}' \
-F o=OWNER -F r=REPO -F n=123
gh api graphql -f query='mutation($t:ID!){resolveReviewThread(input:{threadId:$t}){thread{id isResolved}}}' \
-f t=PRRT_kwDOxxxxx
Progressive Disclosure
Each reference is a trigger: read only the one matching the user's intent; do not preload everything.
- Read references/first-time-setup.md. Load when setting up a fresh machine/account: installing
gh, runninggh auth login, picking HTTPS vs SSH, making gh the git credential helper, cloning, and verifying with a read call (GHES included). - Read references/auth.md: Load when auth fails, choosing classic vs fine-grained PAT, scoping a token per operation (push / open-PR / review / resolve), the GH_TOKEN vs GH_ENTERPRISE_TOKEN split, keyring storage, or wiring tokens into CI / GitHub Actions.
- Read references/issues.md: Load when creating, finding, updating, relating, closing, reopening, or commenting on GitHub issues as workflow tickets.
- Read references/projects.md: Load when adding tickets or pull requests to GitHub Projects, setting Status or typed fields, archiving/removing items, or reconciling project automation.
- Read references/create.md. Load when opening a PR:
gh pr createflags, draft, reviewers/labels, issue-linking and auto-close semantics, the additive-body / replace-on-edit trap, idempotency guard, and the rawPOST /pullsREST equivalent. - Read references/context-comments.md: Load when publishing or reconciling versioned decision, rationale, tradeoff, assumption, or constraint context as a top-level issue or pull-request comment.
- Read references/review-post.md. Load when publishing a review: the single
.../reviewsobject, the exact path/line/side inline anchor model, the REQUEST_CHANGES blocking mechanism, and deep-linking fromhtml_url. - Read references/review-resolve.md. Load when resolving/replying on threads: listing
reviewThreads, matching a finding to a thread by id (never line), the GraphQLresolveReviewThreadmutation, in-thread replies, and the conversation-resolution merge gate. - Read references/automation-and-enforcement.md: Load when configuring or onboarding reusable workflows/actions, required checks, rulesets, protected environments, token/OIDC permissions, attestations, evidence, rollback, or governance-only GitHub adoption.
- Read references/onboarding.md: Load when setting up, diagnosing, dry-running, verifying, rolling back, uninstalling, or checking drift on repository/organization governance.
- Read provider conformance: Load when composing GitHub tickets, Projects, pull requests, reviews, context, and evidence into a provider-neutral workflow handoff or testing adapter behavior.