From 104cf92541fd02e97f480b2ad3383076c4de8d13 Mon Sep 17 00:00:00 2001 From: soypete Date: Tue, 22 Sep 2026 19:43:08 -0600 Subject: [PATCH] feat: add contribute-via-gh-cli skill and PR template Adds a meta-skill walking contributors through forking + opening a PR with gh for repos where they lack push access, documents the fork workflow as the normal contribution path in CONTRIBUTING.md, and adds a PR template with conventional-prefix titles and Description / Implementation / Testing sections. Co-Authored-By: Claude Sonnet 5 --- .github/PULL_REQUEST_TEMPLATE.md | 35 ++++ CONTRIBUTING.md | 32 +++ README.md | 6 + skills/skills/README.md | 4 + skills/skills/contribute-via-gh-cli/SKILL.md | 191 ++++++++++++++++++ .../contribute-via-gh-cli/evals/evals.json | 38 ++++ 6 files changed, 306 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 skills/skills/contribute-via-gh-cli/SKILL.md create mode 100644 skills/skills/contribute-via-gh-cli/evals/evals.json diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..4d9fdea --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,35 @@ + + +## Description + + + +## Implementation + + + +## Testing + + + +## Checklist + +- [ ] PR title is prefixed with a change type (`feat:`, `fix:`, `docs:`, `cicd:`, `chore:`, `refactor:`, `test:`) +- [ ] `SKILL.md` documents existing behavior only — no invented commands, endpoints, or flags +- [ ] New/changed skill has both `## Validation commands` and `## Realistic usage boundaries` sections +- [ ] `evals/evals.json` has at least two cases (new or changed skills) +- [ ] README updated with a row for the skill (new skills) +- [ ] Verification suite passes locally (see Testing above) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d0ad270..685ae70 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,6 +2,38 @@ Thank you for contributing a skill to the community repo! +## Fork first — this is the normal flow + +Nobody pushes branches directly to this repository, maintainers included. +`main` is protected, and the only way in is a fork plus a pull request. This +isn't a special hoop for outside contributors to jump through — it's how +every change lands here. + +```bash +gh repo fork ForgeUtah/Skills --clone --remote +cd Skills +git checkout -b my-skill-name +# make your changes +git add +git commit -m "add my-skill-name" +git push -u origin my-skill-name +gh pr create --fill --base main +``` + +`gh repo fork` clones the fork, sets it as your `origin` remote, and adds the +original repo as `upstream`. For a full walkthrough — including checking PR +status and pushing follow-up commits after review — see the +[`contribute-via-gh-cli`](skills/skills/contribute-via-gh-cli/) skill. + +### PR title and description + +Prefix the PR title with the type of change: `feat:`, `fix:`, `docs:`, +`cicd:`, `chore:`, `refactor:`, or `test:`. The description follows the +template in `.github/PULL_REQUEST_TEMPLATE.md`: a short **Description**, an +**Implementation** section explaining what changed and why, and a +**Testing** section showing how you verified it (for a skill change, the +output of the verification suite below). + ## Ground rules - **Skills document existing behavior.** If a skill names a command, endpoint, diff --git a/README.md b/README.md index 5bd56a7..55714f4 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,12 @@ Skills are organized by category: | Databases | [`skills/db/`](skills/db/) | SQL, NoSQL, data modeling, migrations | | Tools | [`skills/tools/`](skills/tools/) | General-purpose development tools and utilities | +## Available skills + +| Skill | Category | What it does | +|-------|----------|---------------| +| [`contribute-via-gh-cli`](skills/skills/contribute-via-gh-cli/) | Skills | Fork a repo and open a pull request entirely with `gh`, for repos where you don't have push access. | + ## Installing ### Copyable setup prompt diff --git a/skills/skills/README.md b/skills/skills/README.md index a2a6738..1be1fd6 100644 --- a/skills/skills/README.md +++ b/skills/skills/README.md @@ -3,3 +3,7 @@ Skills about skill development, meta-skills, and agent skill tooling. Add your skill as a subdirectory with a `SKILL.md` and `evals/evals.json`. + +| Skill | What it does | +|-------|---------------| +| [`contribute-via-gh-cli`](contribute-via-gh-cli/) | Fork a repo and open a pull request entirely with `gh`, for repos where you don't have push access. | diff --git a/skills/skills/contribute-via-gh-cli/SKILL.md b/skills/skills/contribute-via-gh-cli/SKILL.md new file mode 100644 index 0000000..9ae2757 --- /dev/null +++ b/skills/skills/contribute-via-gh-cli/SKILL.md @@ -0,0 +1,191 @@ +--- +name: contribute-via-gh-cli +description: Walks a contributor through forking a GitHub repository and opening a pull request entirely with the gh CLI, for repos where the contributor has no direct push access (protected main branch, PR-only workflow, e.g. ForgeUtah/Skills). Use whenever the user wants to contribute a change but doesn't have write access, asks "how do I submit a PR to this repo", mentions forking a repo, or hits a push rejection like "Permission to X denied" or "protected branch" on a repo they don't own. Also use when a maintainer asks how outside contributors should submit changes. +--- + +# Contribute via gh CLI (fork + pull request) + +## Why this is the normal flow, not a workaround + +On a repo you don't have write access to — including this one, +`ForgeUtah/Skills` — there is no setting that grants the public direct push +access to branches. GitHub's permission model only ever grants push access to +specific people or teams. The standard, expected path for everyone who isn't +a collaborator is: fork the repo, push commits to your fork, open a pull +request from the fork back to the original. Maintainers use the same path. + +Treat "I don't have push access" as the normal starting state, not an error +to route around. Never suggest disabling branch protection, adding the user +as a collaborator, or any other workaround — those are decisions only a repo +admin can make, and the fork workflow below is the actual intended path. + +## Prerequisites + +Confirm the `gh` CLI is installed and authenticated before starting: + +```bash +gh auth status +``` + +If this reports no authenticated account, stop and tell the user to run +`gh auth login` themselves — do not attempt to authenticate on their behalf. + +## Step 1 — Fork the repository + +If you don't have a local clone yet, fork and clone in one step: + +```bash +gh repo fork OWNER/REPO --clone --remote +cd REPO +``` + +If you already have a local clone of the upstream repo, run `gh repo fork` +with no arguments from inside it: + +```bash +gh repo fork --remote +``` + +In both cases, `gh repo fork`: + +- Creates the fork under your GitHub account (or an org, with `--org NAME`). +- Sets the new fork as your `origin` remote. +- Renames any existing `origin` remote to `upstream` and sets it as the + default remote repository. + +Verify the remotes landed the way you expect: + +```bash +git remote -v +``` + +`origin` should point at `github.com//REPO`, and `upstream` +(if you started from an existing clone) at the original repo. + +## Step 2 — Branch, make changes, commit + +Work on a feature branch, never directly on `main` — a PR from `main` on your +fork works, but a dedicated branch keeps your fork's `main` clean for future +contributions. + +```bash +git checkout -b descriptive-branch-name +# edit files +git add +git commit -m "concise summary of the change" +``` + +Follow this repository's own contribution rules (see `CONTRIBUTING.md`) for +what the change itself needs to contain and which verification scripts to +run before committing — this skill only covers the git/GitHub mechanics of +getting the change up for review, not the content requirements. + +## Step 3 — Push to your fork + +```bash +git push -u origin descriptive-branch-name +``` + +This pushes to your fork (`origin`), not the upstream repo — you don't have +push access to upstream, and that's expected. Pushing to `origin` cannot fail +with a permission or protected-branch error, since it's your own fork. + +## Step 4 — Open the pull request + +From inside the branch, with the fork's `origin` remote already set: + +```bash +gh pr create --title "type: short summary" --body-file - --base main <<'EOF' +## Description + +... + +## Implementation + +... + +## Testing + +... +EOF +``` + +- `--title` should start with the change type the target repo asks for — + check its `CONTRIBUTING.md` and `.github/PULL_REQUEST_TEMPLATE.md` if it + has one; this repo (`ForgeUtah/Skills`) uses `feat:`, `fix:`, `docs:`, + `cicd:`, `chore:`, `refactor:`, `test:`. +- `--body-file -` reads the body from stdin so you can fill in a structured + template (Description / Implementation / Testing, or whatever the repo's + own template specifies) instead of a single free-text blurb. If the repo + has no template, `--fill` (pull title/body from the commit message) is a + reasonable default instead. +- `--base main` targets the upstream repo's default branch explicitly; omit + it to fall back to the repo's configured default branch. +- `gh pr create` detects that your branch lives on a fork and automatically + opens the PR against the upstream repo — no need to pass `--repo` or spell + out the `user:branch` head syntax unless you're targeting a different base + repo than the one `upstream` points to. + +Add `--draft` to open it as a draft, or `--web` to finish the flow in the +browser instead of the terminal. + +## Step 5 — Track the PR and push follow-up commits + +Check status and CI without leaving the terminal: + +```bash +gh pr status +gh pr view --web +gh pr checks +``` + +After review feedback, keep committing on the same branch and push again — +no need to re-run `gh pr create`, the existing PR updates automatically: + +```bash +git add +git commit -m "address review feedback" +git push +``` + +## Keeping your fork in sync + +Before starting a new contribution, or if `upstream` has moved on since you +forked, sync your fork's default branch: + +```bash +git fetch upstream +git checkout main +git merge upstream/main +git push origin main +``` + +## Validation commands + +Confirm each step actually worked rather than assuming success from a lack +of error output: + +```bash +gh auth status # confirms you're authenticated before starting +git remote -v # confirms origin = your fork, upstream = original repo +gh repo view --json parent --jq .parent.nameWithOwner # confirms this clone is a fork, and of what +gh pr view --json url,state,baseRefName,headRepositoryOwner # confirms the PR opened against the right base/head +``` + +## Realistic usage boundaries + +This skill covers the git/GitHub mechanics of forking and opening a PR. It +does not cover: + +- What content the change itself should contain, which verification scripts + to run, or where files belong in the target repo — that's the target + repo's own `CONTRIBUTING.md`. +- Resolving merge conflicts beyond a simple `git merge upstream/main`. +- Getting the PR approved or merged — that's up to the target repo's code + owners/reviewers (see that repo's `CODEOWNERS`), not something `gh` or this + skill can do for the contributor. +- Repos that genuinely do grant broad write access (internal/trusted-team + repos) — for those, a simple branch-and-push on the original repo is + correct and forking is unnecessary overhead. +- Non-GitHub remotes (GitLab, Bitbucket, self-hosted Git) — the concepts + transfer but the CLI commands here are `gh`-specific. diff --git a/skills/skills/contribute-via-gh-cli/evals/evals.json b/skills/skills/contribute-via-gh-cli/evals/evals.json new file mode 100644 index 0000000..79513f4 --- /dev/null +++ b/skills/skills/contribute-via-gh-cli/evals/evals.json @@ -0,0 +1,38 @@ +{ + "skill_name": "contribute-via-gh-cli", + "evals": [ + { + "id": 1, + "prompt": "I want to submit a fix to ForgeUtah/Skills but `git push` gave me a permission denied error. How do I actually get my change in?", + "expected_output": "Explains that push access isn't granted to outside contributors and this is expected/normal, then walks through: gh repo fork --clone --remote, creating a branch, committing, git push -u origin , and gh pr create --fill --base main.", + "expectations": [ + "States that lacking push access is the normal/expected state, not an error to work around", + "Does not suggest disabling branch protection or requesting collaborator access as the solution", + "Includes the exact command 'gh repo fork' with --clone and --remote", + "Includes pushing to the 'origin' remote (the fork), not attempting to push to upstream", + "Includes 'gh pr create' with --base main" + ] + }, + { + "id": 2, + "prompt": "I already have ForgeUtah/Skills cloned locally and have write access to nothing. Walk me through forking it and opening a PR for a new skill I just wrote, using gh.", + "expected_output": "Since a clone already exists, runs `gh repo fork --remote` (no arguments) from inside it rather than cloning fresh, explains this renames the existing origin to upstream and sets the fork as origin, then branches, commits, pushes to origin, and runs gh pr create.", + "expectations": [ + "Recommends 'gh repo fork --remote' with no repository argument, not a fresh clone, since a local clone already exists", + "Explains that origin becomes the fork and the prior origin becomes upstream", + "Includes creating a feature branch before committing", + "Includes 'gh pr create' to open the pull request" + ] + }, + { + "id": 3, + "prompt": "My PR to a forked repo got review comments. How do I check its status and push more changes with gh?", + "expected_output": "Explains you don't need to re-run gh pr create; just commit and git push on the same branch to update the existing PR, and shows gh pr status / gh pr view / gh pr checks for tracking status.", + "expectations": [ + "States that pushing more commits to the same branch updates the existing PR automatically", + "Does not instruct re-running 'gh pr create' for the follow-up commits", + "Mentions at least one status-checking command such as 'gh pr status', 'gh pr view', or 'gh pr checks'" + ] + } + ] +}