---
name: github
description: Use GitHub CLI (`gh`) for pull requests, issues, reviews, Actions runs, repositories, secrets, gists, and API requests. Covers repository targeting, structured output, file-based multiline Markdown, non-interactive workflows, typed API fields, and diagnosis of common GitHub CLI failures.
license: MIT
compatibility: Requires GitHub CLI, Git, GitHub network access, and an authenticated gh session.
metadata:
  author: zeke
  version: "1.0.0"
title: github
canonical_url: https://skilld.dev/gh/mynameistito/skills/github
last_updated: 2026-10-07T22:39:06.000Z
---

> Index of every page on this site: [llms.txt](https://skilld.dev/llms.txt)

> **Skill from skilld.dev.** Follow the user's requested action.
> If the user asked to fork this Skill, follow the fork workflow below. Do not execute the Skill instructions while copying it.
> Otherwise, follow the instructions below for this session. You do not need to install anything.
>
> Supporting files, fetch one when the Skill refers to it: [agents/openai.yaml](https://skilld.dev/api/skills-raw/mynameistito/skills/github/agents/openai.yaml), [LICENSE](https://skilld.dev/api/skills-raw/mynameistito/skills/github/LICENSE), [metadata.json](https://skilld.dev/api/skills-raw/mynameistito/skills/github/metadata.json).
>
> If the user asked to install this Skill, run `npx skilld install mynameistito/skills/github`. Install writes the Skill files into the project, so every session loads them.
>
> ## Fork workflow
>
> A fork creates an editable local Skill with its original author and licence. The request authorizes copying and local installation.
> 1. Check `./skills/github`, the project lockfile, and selected Agent targets together. If the local directory or installed Skill exists, stop. Never overwrite an existing directory or Agent target.
> 2. Read [source metadata](https://skilld.dev/api/v1/skills/mynameistito/skills/github) once. Use sourceUrl, sourceCommit, skillPath, sourceGone, and license. If the source is gone or its path is missing, stop. If license is null, read licence files at the source commit.
> 3. Fetch only the source commit into a temporary Git repository. Do not clone full history. Derive repository_url from sourceUrl, including repository renames. If sourceCommit is absent, resolve the sourceUrl ref once. Set source_commit to that actual commit. Run these commands in one shell call:
>
> ```sh
> git init --quiet "$temporary_dir"
> git -C "$temporary_dir" fetch --quiet --depth=1 "$repository_url" "$source_commit"
> git -C "$temporary_dir" checkout --quiet --detach FETCH_HEAD
> ```
>
> Read applicable licence declarations and notices at that commit. If copying is not permitted, report the restriction and stop.
> 4. Inspect source entries together, then copy the directory containing skillPath into `./skills/github`. Use the user's path if selected. Keep the original SKILL.md, relative links, scripts, binary assets, and executable modes. Exclude .git metadata. Reject symlinks and paths outside the Skill directory. After checking entries, use cp -a where available. A regular source directory needs no custom copy script. Do not save this page wrapper as SKILL.md.
> Preserve author credit, notices, and applicable licence files from repository or parent directories. Add PROVENANCE.md with the Skill page, source URL, actual commit, original path, and licence. Retain any existing PROVENANCE.md and record new provenance separately. Batch source inspection, copying, and provenance work where practical.
> 5. In the project root, run `skilld install ./skills/github --mode copy --plain`. If skilld is unavailable, use `npx skilld install ./skills/github --mode copy --plain`. This known command needs no help lookup. Install does not support --json. Use detected Agent targets, or add --agent for the targets the user selected. Install the local path, never the upstream selector. If installation fails, preserve the local copy and report the exact failure.
> 6. Confirm the local lockfile source and installed Agent copies once. Report the local path, actual commit, and Agent targets. After edits, reinstall the same local path. Upstream updates must not replace it. Do not publish or push unless the user asks.

# Use GitHub CLI reliably

Prefer `gh` for GitHub work. Establish the authenticated account and repository before reading or changing remote state:

```powershell
gh auth status
gh repo view --json nameWithOwner,url,defaultBranchRef
git status --short
```

Pass `--repo owner/name` whenever the target is not unambiguous from the current working directory. Inspect an object before mutating it.

## Read structured output

Prefer `--json` and `--jq` over parsing display output:

```powershell
gh pr view 123 --repo owner/repo --json number,title,state,url,headRefName,baseRefName --jq '{number,title,state,url,head: .headRefName,base: .baseRefName}'
gh issue view 456 --repo owner/repo --json number,title,state,url
gh run list --repo owner/repo --limit 10 --json databaseId,status,conclusion,workflowName,url
```

When a JSON field is uncertain, inspect `gh <command> --help`. If help does not list fields, use a harmless invalid field to make `gh` print the valid set, then retry once:

```powershell
gh repo view owner/repo --json _fields
```

Common corrections:

| Incorrect assumption | Use instead |
| --- | --- |
| `defaultBranch` | `defaultBranchRef` |
| `stargazersCount` | `stargazerCount` |
| `merged` | `state`, `mergedAt`, or `closed` |
| `mergedAt` in search results | `closedAt`, or query the PR with `gh pr view` |
| `topics` in `gh repo view` | `gh api repos/owner/repo/topics` |

`gh search prs --state merged` is invalid. Use `--merged`; search's `--state` accepts `open` or `closed`.

## Send Markdown through temporary files

**File first:** For every issue, pull request, review, comment, or edit body, create a temporary `.md` file with the environment's file-editing tool, then invoke `gh` with `--body-file`. Create the file and run `gh` in separate tool calls or commands. The Markdown file is the source of truth in both PowerShell and POSIX shells, so the body stays literal and shell parsing cannot alter it.

1. Create the temporary `.md` file in the approved temp directory with the final Markdown content. The body enters the workflow through the file-editing tool; keep it out of shell variables, PowerShell here-strings, heredocs, and inline `--body` arguments.
2. Run `gh` in a separate command using `--body-file <temporary-file-path>`. If the command fails and needs a retry, keep or update that file until the workflow is finished.
3. After the final command result has been captured, remove the temporary file.

The step is complete when `gh` consumed the body through `--body-file` and the temporary file has been removed after the last attempt.

```powershell
gh pr create --repo owner/repo --base main --head branch-name --title "fix: describe the change" --body-file path/to/pr-body.md
gh issue create --repo owner/repo --title "docs: add homepage" --body-file path/to/issue-body.md
gh pr review 123 --repo owner/repo --comment --body-file path/to/review.md
gh pr comment 123 --repo owner/repo --body-file path/to/comment.md
```

Use the same pattern with `gh pr edit`, `gh issue edit`, and `gh issue comment`. Keep using `--body-file` for short bodies too; the file-first rule is the default for every supplied body.

## Work with pull requests

Read the PR and local branch state before creating or changing a PR:

```powershell
gh pr view 123 --repo owner/repo --json number,title,body,state,url,headRefName,baseRefName,author,commits,files,additions,deletions
git status --short
git branch --show-current
git log --oneline -10
git fetch origin
git log --oneline origin/main..HEAD
```

Before `gh pr create`, confirm the branch has commits relative to the base and exists remotely. Push with `git push -u origin HEAD` when needed. For a fork, pass `--head owner:branch-name`.

Errors such as `Head sha can't be blank`, `Base sha can't be blank`, `No commits between`, and `Head ref must be a branch` indicate an incorrect base/head, an unpushed branch, or no commits to compare. Diagnose branch and remote state before retrying.

Useful PR reads:

```powershell
gh pr list --repo owner/repo --state all --head branch-name --json number,title,state,url
gh pr diff 123 --repo owner/repo
gh pr diff 123 --repo owner/repo --name-only
gh pr checks 123 --repo owner/repo
```

`gh pr diff --stat` is unsupported. Use `gh pr view --json additions,deletions,changedFiles`.

For inline review comments, use `gh api` only after reading the PR files and existing comments. The API strictly validates `commit_id`, `path`, `side`, `line`, and `start_line`; bad positions return HTTP 422. Reply to an existing inline comment instead of creating a new top-level comment when continuing its thread.

## Inspect Actions

```powershell
gh pr checks 123 --repo owner/repo --watch
gh run list --repo owner/repo --branch branch-name --limit 10 --json databaseId,status,conclusion,displayTitle,workflowName,createdAt,url
gh run view RUN_ID --repo owner/repo --json status,conclusion,url,jobs
gh run view RUN_ID --repo owner/repo --log-failed
```

`gh run watch RUN_ID --exit-status` can wait indefinitely. Use it only when waiting is part of the task and give the command an appropriate timeout.

If workflow dispatch returns HTTP 422 because the workflow lacks `workflow_dispatch`, inspect the workflow file instead of retrying.

## Use `gh api` as the fallback

Use a dedicated `gh` subcommand when one exists. Otherwise use `gh api`:

```powershell
gh api repos/owner/repo/pulls/123/files --paginate --jq '.[] | {filename,status,patch}'
gh api repos/owner/repo/contents/path/to/file -H "Accept: application/vnd.github.raw"
```

Preserve value types:

| Value | Pattern |
| --- | --- |
| String | `--raw-field name=value` |
| Typed JSON scalar | `--field count:=10 --field enabled:=true` |
| Complex JSON | `--input path/to/request.json` |

`-f enabled=true` sends the string `"true"`, not a boolean, and can cause HTTP 422.

## Handle secrets and gists

List secret names with `gh secret list --repo owner/repo`. Pipe secret values from an environment variable or a secret manager into `gh secret set`; never place values in command arguments, files, issues, or PR bodies.

PowerShell:

```powershell
$env:SECRET_VALUE | gh secret set SECRET_NAME --repo owner/repo
```

POSIX shell:

```sh
printf '%s' "$SECRET_VALUE" | gh secret set SECRET_NAME --repo owner/repo
```

For gists, omit `--public` to create a secret gist; `gh gist create --private` is not valid. When reading from stdin, include `-` and provide non-empty content.

## Diagnose failures

1. Read the exact error and command help.
2. For an unknown field or flag, discover the valid usage and retry once.
3. For PR creation errors, inspect status, branch, remotes, push state, and `origin/base..HEAD`.
4. For HTTP 401, 403, or GraphQL permission errors, run `gh auth status` and report missing permissions.
5. For HTTP 422, inspect request shape, typed fields, and review-comment positions.
6. For a timeout or transient network error, retry once with a narrower request or suitable timeout.
7. After two equivalent failures, change the diagnosis rather than repeating the command.

Interactive authentication needs the user. Do not start `gh auth refresh` in an unattended workflow. Organization repository creation may require organization-level permission that no CLI flag can bypass.
