From 839286df6d30fb15f2054546f54b8cbb138895b2 Mon Sep 17 00:00:00 2001 From: Sebastian Mendel Date: Tue, 25 Aug 2026 23:35:19 +0200 Subject: [PATCH] feat(references): contributing to repositories you do not own MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every rule in this reference exists because skipping it produced a public artifact that had to be walked back, all in one upstream engagement (FriendsOfTYPO3/fractor, 2026-08-25): - Three keyword searches came back empty against a repo whose open issue described the same defect in different words, with the fix already in an open PR — the repo had six open issues, and reading the list would have taken a minute. Duplicate issue and PR both had to be closed. Hence: read the open issue AND PR lists; an empty search is first a broken query. - Two five-line comment blocks were the longest in the entire codebase until a reviewer asked why. Hence: measure comment density, do not import house style. - The PR went out non-draft and a documented contributing step (composer docs) was skipped. Hence: draft-first, run ALL of the contract. - The project's own rectify fixers rewrote four unrelated files during the gate run. Hence: revert what the fixer touched that you did not. - What ended the thread well: running the maintainer's competing fix against the own reproduction and answering with measured numbers, then closing the superseded PR in its favour. Hence the last two sections. SKILL.md gains a When-to-Use trigger and the reference row. main sat at 499 words of the 500-word cap, so existing prose is compressed to make room: "See X (a, b)" becomes "X: a, b", two headings lose filler words, one redundant reference parenthetical goes (the table row carries it), and one code comment drops context the neighbouring bullet already states. No guidance is removed. Assisted-by: claude-code:claude-opus-5 Agent-Session: https://claude.ai/code/session_01GSptxPLHWsttu9FuqVkvYZ Agent-Host: 0493f0 Signed-off-by: Sebastian Mendel --- skills/github-project/SKILL.md | 20 ++--- .../references/upstream-contributions.md | 81 +++++++++++++++++++ 2 files changed, 92 insertions(+), 9 deletions(-) create mode 100644 skills/github-project/references/upstream-contributions.md diff --git a/skills/github-project/SKILL.md b/skills/github-project/SKILL.md index 87a4d34..f2f3187 100644 --- a/skills/github-project/SKILL.md +++ b/skills/github-project/SKILL.md @@ -14,8 +14,9 @@ allowed-tools: Bash(gh:*) Bash(git:*) Bash(grep:*) Read Write ## When to Use -- **Post `gh repo create` + push, before first PR** — REQUIRED: `scripts/init-branch-protection.sh OWNER/REPO` (`references/repo-bootstrap.md`) -- Adding a job to a repo's workflow — see pitfall #6 +- **Post `gh repo create` + push, before first PR** — REQUIRED: `scripts/init-branch-protection.sh OWNER/REPO` +- **First issue/PR into a foreign repo** — `references/upstream-contributions.md` BEFORE filing +- Adding a workflow job — pitfall #6 - PR won't merge / threads - Auto-merge fails (Dependabot/Renovate) - Solo auto-approve @@ -36,13 +37,13 @@ gh pr view PR --repo OWNER/REPO \ --json mergeStateStatus,reviewDecision,mergeable,reviewThreads ``` -### Solo Maintainer: PRs Stuck on REVIEW_REQUIRED +### Solo Maintainer: Stuck on REVIEW_REQUIRED -Use `assets/pr-quality.yml.template` for auto-approve with `required_approving_review_count >= 1`. +`assets/pr-quality.yml.template`: auto-approve with `required_approving_review_count >= 1`. ### Auto-merge Setup -Requires `allow_auto_merge`, `pull_request_target`, bot detection, `gh pr merge --auto`. See `references/auto-merge-guide.md`. +Requires `allow_auto_merge`, `pull_request_target`, bot detection, `gh pr merge --auto` (`references/auto-merge-guide.md`). ### Auto-merge Not Working @@ -60,7 +61,7 @@ gh run view RUN_ID --repo OWNER/REPO --log-failed gh run rerun RUN_ID --repo OWNER/REPO ``` -### Security & Compliance Quick Checks +### Security Quick Checks ```bash gh api repos/OWNER/REPO/rules/branches/main @@ -72,19 +73,19 @@ gh pr view PR --repo OWNER/REPO --json reviewThreads --jq '.reviewThreads' ### Merge Strategy Issues -See `references/auto-merge-guide.md` (signed-commit rebase, workflow-file PRs, Copilot race). +`references/auto-merge-guide.md`: signed-commit rebase, workflow-file PRs, Copilot race. ## Running Scripts ```bash -scripts/init-branch-protection.sh OWNER/REPO # baseline (post gh repo create) +scripts/init-branch-protection.sh OWNER/REPO # baseline scripts/init-branch-protection.sh OWNER/REPO --from-current-checks # after first CI scripts/verify-github-project.sh /path/to/repository # local-checkout audit ``` ## No editorializing -State what a change does, not how good it is. See `references/no-editorializing.md`. +State what a change does, not how good it is. ## References @@ -108,6 +109,7 @@ State what a change does, not how good it is. See `references/no-editorializing. | Fork merge base | `references/pr-commit-cleanup.md` | | Multi-repo batch ops | `references/multi-repo-operations.md` | | Cross-repo references | `references/cross-repo-references.md` | +| Foreign-repo contributions | `references/upstream-contributions.md` | | Reusable workflow security | `references/reusable-workflow-security.md` | | Reusable workflow pitfalls | `references/reusable-workflow-pitfalls.md` | | Org security settings | `references/org-security-settings.md` | diff --git a/skills/github-project/references/upstream-contributions.md b/skills/github-project/references/upstream-contributions.md new file mode 100644 index 0000000..3f9b448 --- /dev/null +++ b/skills/github-project/references/upstream-contributions.md @@ -0,0 +1,81 @@ +# Contributing to Repositories You Do Not Own + +First contribution to a foreign repo — an issue, a PR, or both. Every step here +exists because skipping it produced a public artifact that had to be walked +back. + +## Before filing anything: read the lists, not just search results + +Read the **open issue list AND the open PR list** before writing a word. +Keyword searches find your phrasing, not the problem: three searches +("dry-run exit", "changed_files", "xliff diff") all came back empty against a +repo whose issue #427 described the same defect as "don't return **error +code**" — and whose open PR #430 already fixed it. The repo had six open +issues; reading the list would have taken a minute. The duplicate issue and PR +both had to be closed with thanks. + +```bash +gh issue list -R OWNER/REPO --state open # read it, all of it if small +gh pr list -R OWNER/REPO --state open # the fix may already be in flight +``` + +An empty keyword search is first a broken query, never evidence of absence. + +## Read the contribution contract — and run ALL of it + +`CONTRIBUTING.md` or the README's contributing section, every linked step, the +issue/PR templates, and the workflows under `.github/workflows/` (they encode +gates prose never mentions: linear-history checks, rebase-on-latest-main +requirements). Running four of five documented steps is not compliance — the +skipped `composer docs` step is the one the maintainer notices. + +Conventions are read from artifacts, not assumed: + +- **Commit style** from `git log --oneline -10` (e.g. `[BUGFIX]`/`[TASK]` + prefixes vs conventional commits). +- **Sign-off** from recent commit trailers — a repo where 0 of the last 6 + commits carry `Signed-off-by` does not want yours enforced; carrying your own + disclosure trailers is fine where nothing bans them. + +## Match the code style you measure, not the style you brought + +House style does not travel. Before writing code, measure the target: + +```bash +# comment density and the longest comment block in their source +find src -name '*.php' | xargs grep -cE '^\s*//' | awk -F: '{s+=$2; n++} END {print s/n " avg comment lines/file"}' +``` + +A codebase whose largest existing comment block is two lines does not want +your six-line rationale inline — that context belongs in the commit message +and PR body, which is where such projects keep it. Two five-line comment +blocks were the longest in an entire codebase until a reviewer asked why. + +## Open the PR as a draft + +A first-time PR into a foreign org starts in draft. It signals "for your +judgment" rather than "merge me", costs one click to promote, and gives the +maintainers the first move. Converting later: `gh pr ready `. + +## Their fixers are not your diff + +Project-level format/rectify gates may rewrite files you never touched (their +main simply drifted). Revert those before committing — a first PR that +reformats four unrelated files reads as carelessness: + +```bash +git checkout -- +``` + +## When a maintainer asks "does X fix your problem?" — run X + +Check out the competing branch and run it against **your own reproduction**, +then answer with the measured result. A table of before/after numbers settles +in one comment what diff-reading speculation cannot — and if the other fix is +better, say so plainly and close your own PR in its favour, with thanks. + +## Closing your superseded work + +Close with a reference to what supersedes it and what, if anything, of yours +remains useful (offer it as a follow-up, do not relitigate). The goodwill from +a clean retreat is worth more than the PR was.