Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 28 additions & 21 deletions skills/github-project/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,26 @@ allowed-tools: Bash(gh:*) Bash(git:*) Bash(grep:*) Read Write

# GitHub Project Skill

Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous ## Overview section heading was removed, leaving an unheaded overview sentence. If other skills/docs rely on consistent section headings for navigation or automated extraction, consider restoring ## Overview and placing the sentence under it for consistency.

Suggested change
## Overview

Copilot uses AI. Check for mistakes.
## Overview

GitHub repository setup, configuration, troubleshooting, and best practices for collaboration workflows.
GitHub repository configuration, troubleshooting, and collaboration workflow best practices.

## When to Use

- PR won't merge or shows BLOCKED status
- PR won't merge, shows BLOCKED, or has unresolved review threads
- Auto-merge not working for Dependabot/Renovate PRs
- Solo maintainer needs auto-approve for their own PRs
- Branch protection or ruleset configuration needed
- GitHub Actions workflow problems or CI failures
- Setting up CODEOWNERS, issue templates, or PR templates
- Repository standards compliance (TYPO3, Go, polyglot)
- Branch protection, rulesets, or `enforce_admins` audit
- GitHub Actions workflow problems, CI failures, or permission issues
- Signed commit merge failures (rebase cannot be auto-signed)
- CodeQL default setup conflicts with custom workflows
- OpenSSF Scorecard improvements (token permissions, pinned deps)
- Setting up CODEOWNERS, issue templates, PR templates, or release labeling
- Fork PR merge base issues (too many commits shown)

## Quick Diagnostics

### PR Won't Merge

```bash
# Check merge state, review decision, and unresolved threads
gh api graphql -f query='query($owner:String!,$repo:String!,$pr:Int!){
repository(owner:$owner,name:$repo){pullRequest(number:$pr){
mergeStateStatus reviewDecision mergeable
Expand All @@ -42,22 +42,15 @@ gh api graphql -f query='query($owner:String!,$repo:String!,$pr:Int!){

### Solo Maintainer: PRs Stuck on REVIEW_REQUIRED

Solo maintainer projects MUST have auto-approve. Use `assets/pr-quality.yml.template` and keep `required_approving_review_count >= 1`. See `references/auto-merge-guide.md` for full setup.

### Auto-merge Setup for New Repos
Use `assets/pr-quality.yml.template` for auto-approve with `required_approving_review_count >= 1`. See `references/auto-merge-guide.md`.

Every repo with Dependabot/Renovate needs auto-merge. Key requirements:
- Enable `allow_auto_merge` on repo
- Use `pull_request_target` trigger (not `pull_request`)
- Check `user.login` (not `github.actor`)
- Use `gh pr merge --auto` with dynamic strategy
### Auto-merge Setup

See `references/auto-merge-guide.md` for the canonical workflow and common pitfalls.
Requirements: `allow_auto_merge` on repo, `pull_request_target` trigger (not `pull_request`), check `user.login` (not `github.actor`), `gh pr merge --auto` with dynamic strategy. See `references/auto-merge-guide.md`.

### Auto-merge Not Working

```bash
# Check who enabled auto-merge and bypass apps
gh api graphql -f query='query{repository(owner:"OWNER",name:"REPO"){
pullRequest(number:PR){autoMergeRequest{enabledBy{login}}}
}}' --jq '.data.repository.pullRequest.autoMergeRequest'
Expand All @@ -74,9 +67,23 @@ gh run view RUN_ID --repo OWNER/REPO --log-failed
gh run rerun RUN_ID --repo OWNER/REPO
```

## Running Scripts
### Security & Compliance Quick Checks

```bash
gh api repos/OWNER/REPO/branches/main/protection --jq '.enforce_admins.enabled'
gh api repos/OWNER/REPO/code-scanning/default-setup --jq '.state'
Comment on lines +73 to +74
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This hard-codes main for the branch protection check. Since one of the evals explicitly covers migrating mastermain, and repos can have non-main default branches, it’s easy for readers to run this command against the wrong branch. Suggest using a placeholder like DEFAULT_BRANCH (or documenting how to obtain it via gh repo view) instead of main.

Copilot uses AI. Check for mistakes.
gh api graphql -f query='query($owner:String!,$repo:String!,$pr:Int!){
repository(owner:$owner,name:$repo){pullRequest(number:$pr){
reviewThreads(first:50){nodes{id isResolved}}
}}
}' -f owner=OWNER -f repo=REPO -F pr=NUMBER
Comment on lines +75 to +79
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This GraphQL query is redundant as the 'PR Won't Merge' section (lines 35-40) already covers reviewThreads. If you choose to keep it here for the 'Security & Compliance' context, please add a --jq filter to make the output readable and consistent with other examples in this file.

Suggested change
gh api graphql -f query='query($owner:String!,$repo:String!,$pr:Int!){
repository(owner:$owner,name:$repo){pullRequest(number:$pr){
reviewThreads(first:50){nodes{id isResolved}}
}}
}' -f owner=OWNER -f repo=REPO -F pr=NUMBER
gh api graphql -f query='query($owner:String!,$repo:String!,$pr:Int!){
repository(owner:$owner,name:$repo){pullRequest(number:$pr){
reviewThreads(first:50){nodes{id isResolved}}
}}
}' -f owner=OWNER -f repo=REPO -F pr=NUMBER --jq '.data.repository.pullRequest.reviewThreads.nodes'

```

Verify repository configuration against best practices:
### Merge Strategy Issues

Rebase merge fails with signed commits: enable squash or auto-detect strategy. Workflow file PRs need manual merge (GITHUB_TOKEN lacks `workflows` scope). Copilot reviewer race conditions: re-run auto-approve workflow. See `references/auto-merge-guide.md`.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The recommendation to 'enable squash' for signed commit failures contradicts references/merge-strategy.md, which explicitly states that squash merges are incompatible with signed commits (line 115) and recommends using --merge instead (line 165). Conversely, references/auto-merge-guide.md (line 161) claims squash is preferred and compatible. Please reconcile these reference files to ensure the skill provides consistent and correct advice.


## Running Scripts

```bash
scripts/verify-github-project.sh /path/to/repository
Expand Down
264 changes: 262 additions & 2 deletions skills/github-project/evals/evals.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
},
{
"type": "content",
"pattern": "(branch protection|ruleset|required_pull_request_reviews)"
"pattern": "(branch protection|ruleset|required_pull_request_reviews|enforce_admins)"
}
]
},
Expand All @@ -25,7 +25,267 @@
},
{
"type": "content",
"pattern": "(BLOCKED|reviewDecision|mergeStateStatus)"
"pattern": "(BLOCKED|reviewDecision|mergeStateStatus|reviewThreads)"
}
]
},
{
"name": "setup_auto_merge_workflow",
"prompt": "Set up auto-merge for Dependabot and Renovate PRs in this repository",
"assertions": [
{
"type": "content",
"pattern": "pull_request_target"
},
{
"type": "content",
"pattern": "(user\\.login|dependabot\\[bot\\]|renovate\\[bot\\])"
},
{
"type": "content",
"pattern": "--auto"
}
]
},
{
"name": "diagnose_auto_merge_failure",
"prompt": "Auto-merge is not working on PR #15 - Dependabot PR stays open after checks pass",
"assertions": [
{
"type": "content",
"pattern": "(pull_request_target|user\\.login|github\\.actor|autoMergeRequest)"
},
{
"type": "content",
"pattern": "(bypass|allow_auto_merge|merge strategy|--auto)"
}
]
},
{
"name": "solo_maintainer_pr_stuck",
"prompt": "I'm a solo maintainer and my PRs are stuck on REVIEW_REQUIRED even though I'm the only contributor",
"assertions": [
{
"type": "content",
"pattern": "(auto-approve|pr-quality|required_approving_review_count)"
},
{
"type": "content",
"pattern": "(solo maintainer|collaborator|write.*permission|admin)"
}
]
},
{
"name": "setup_codeowners",
"prompt": "Set up CODEOWNERS for this repository with automatic review assignments",
"assertions": [
{
"type": "content",
"pattern": "(CODEOWNERS|\\.github/CODEOWNERS)"
},
{
"type": "content",
"pattern": "(@|review)"
}
]
},
{
"name": "fix_github_actions_failure",
"prompt": "CI is failing on this repo - the build workflow keeps erroring out on the latest push",
"assertions": [
{
"type": "tool_use",
"tool": "Bash",
"pattern": "gh run (list|view)"
},
{
"type": "content",
"pattern": "(log-failed|rerun|workflow)"
}
]
},
{
"name": "migrate_master_to_main",
"prompt": "Migrate the default branch from master to main for this repository",
"assertions": [
{
"type": "content",
"pattern": "(default_branch|default-branch)"
},
{
"type": "content",
"pattern": "(branch -m|rename|master.*main)"
}
]
},
{
"name": "setup_dependabot",
"prompt": "Configure Dependabot for a Go project that also uses GitHub Actions",
"assertions": [
{
"type": "content",
"pattern": "dependabot\\.yml"
},
{
"type": "content",
"pattern": "(gomod|github-actions|package-ecosystem)"
}
]
},
{
"name": "codeql_default_setup_conflict",
"prompt": "CodeQL is failing with 'analyses from advanced configurations cannot be processed when default setup is enabled'",
"assertions": [
{
"type": "content",
"pattern": "(default-setup|not-configured|code-scanning)"
},
{
"type": "tool_use",
"tool": "Bash",
"pattern": "gh api.*code-scanning"
}
]
},
{
"name": "signed_commits_merge_failure",
"prompt": "Merge is failing with 'Rebase merges cannot be automatically signed by GitHub' - how do I fix this?",
"assertions": [
{
"type": "content",
"pattern": "(squash|merge commit|allow_squash_merge|signed)"
},
{
"type": "content",
"pattern": "(rebase.*cannot.*sign|merge strategy|auto-detect)"
}
]
},
{
"name": "pr_too_many_commits",
"prompt": "My PR on a fork shows 38 commits but I only added 1 - the merge base seems wrong",
"assertions": [
{
"type": "content",
"pattern": "(merge base|close.*reopen|fork)"
},
{
"type": "content",
"pattern": "(gh pr close|cache|recalculate)"
}
]
},
{
"name": "enforce_admins_audit",
"prompt": "Audit whether admins can bypass branch protection on the default branch of this repo",
"assertions": [
{
"type": "content",
"pattern": "enforce_admins"
},
{
"type": "tool_use",
"tool": "Bash",
"pattern": "gh api.*protection"
}
]
},
{
"name": "resolve_review_threads",
"prompt": "PR #23 has unresolved review threads blocking merge - help me find and resolve them",
"assertions": [
{
"type": "content",
"pattern": "(reviewThreads|isResolved|resolveReviewThread)"
},
{
"type": "tool_use",
"tool": "Bash",
"pattern": "gh api graphql"
}
]
},
{
"name": "openssf_scorecard_improvement",
"prompt": "Our OpenSSF Scorecard score is low - what should we fix first?",
"assertions": [
{
"type": "content",
"pattern": "(Scorecard|Token-Permissions|Branch-Protection|Pinned-Dependencies)"
},
{
"type": "content",
"pattern": "(workflow.*write|SHA.*pin|required_approving_review_count)"
}
]
},
{
"name": "workflow_permissions_least_privilege",
"prompt": "Fix the workflow permissions in our CI - we have write permissions at the workflow level",
"assertions": [
{
"type": "content",
"pattern": "(job-level|workflow-level|permissions)"
},
{
"type": "content",
"pattern": "(contents: read|pull-requests: write|least.privilege)"
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In a regex, . matches any character. If you intended to assert the literal phrase least privilege (or least-privilege), this pattern will also match unintended strings like leastXprivilege. Consider escaping the dot (least\\.privilege) or rewriting the alternation to match the literal wording you expect.

Suggested change
"pattern": "(contents: read|pull-requests: write|least.privilege)"
"pattern": "(contents: read|pull-requests: write|least[ -]privilege)"

Copilot uses AI. Check for mistakes.
}
]
},
{
"name": "setup_release_labeling",
"prompt": "Set up automated release labeling so PRs and issues get labeled when a release is published",
"assertions": [
{
"type": "content",
"pattern": "(release-labeler|released:v)"
},
{
"type": "content",
"pattern": "(release.*published|label|announcement)"
}
]
},
{
"name": "merge_queue_troubleshooting",
"prompt": "PRs keep getting stuck in the merge queue after force-pushing a rebase",
"assertions": [
{
"type": "content",
"pattern": "(merge queue|stale review|dismiss_stale_reviews)"
},
{
"type": "content",
"pattern": "(force.push|re-queue|resolveReviewThread|auto-approve)"
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The force.push token uses . which is a wildcard in regex. If the intent is to match force-push/force push wording, this will mis-match (and also over-match). Escape the dot (force\\.push) if you truly want a literal force.push, or update the pattern to explicitly match the expected phrase (e.g., force[- ]push).

Suggested change
"pattern": "(force.push|re-queue|resolveReviewThread|auto-approve)"
"pattern": "(force[- ]push|re-queue|resolveReviewThread|auto-approve)"

Copilot uses AI. Check for mistakes.
}
]
},
{
"name": "copilot_reviewer_race_condition",
"prompt": "Auto-approve keeps getting skipped and PRs stay REVIEW_REQUIRED - we use Copilot as a reviewer",
"assertions": [
{
"type": "content",
"pattern": "(race condition|Copilot|pending reviewer)"
},
{
"type": "content",
"pattern": "(re-run|rerun|auto-approve|COMMENTED)"
}
]
},
{
"name": "workflow_file_pr_cannot_merge",
"prompt": "A Dependabot PR that updates a GitHub Actions version can't be auto-merged - it modifies workflow files",
"assertions": [
{
"type": "content",
"pattern": "(\\.github/workflows/|workflow.*files|GITHUB_TOKEN)"
},
{
"type": "content",
"pattern": "(manual.*merge|workflows.*permission|cannot.*auto-merge)"
}
]
}
Expand Down
Loading