| name | github-repo-professionalise |
| description | Bring a GitHub repo to professional standard — CI, security tooling, community health files, badges, Dependabot, CodeQL, and Scorecard. |
| version | 1.4.3 |
| tags | ["github","ci","quality-gates","security","badges","dependabot","codeql","scorecard","codecov","pre-commit","community-health","typescript","python","bun","uv"] |
| tool_agnostic | true |
| authors | ["Anders Hybertz"] |
| tested_on | [] |
GitHub Repo Professionalisation
Two battle-tested reference implementations:
- Python/uv:
jeckyl2010/mkdocs2confluence
- TypeScript/Bun:
jeckyl2010/risk-assistant
Template files are in templates/ — load with skill_view(file_path=...).
Reference file: references/skill-repo-governance.md — patterns for AI skill/prompt library repos (deprecation metadata, index staleness gate, semver PR discipline, AGENTS.md conventions).
Phase 1 — Gather information (ask before touching anything)
Ask ONE question at a time. Wait for the answer before asking the next.
Where options exist, present them as a numbered or lettered list (single or multiple choice as appropriate).
Questions in order:
-
License (single choice)
a) MIT
b) GPL v3
c) Apache 2.0
d) Other (ask them to specify)
-
Maintainer GitHub handle (open) — for CODEOWNERS and advisory links
-
Stack (single choice — auto-detect from files first, then confirm)
a) Python / uv
b) TypeScript / Bun
c) TypeScript / npm
d) Other (ask them to specify)
-
Package registry (single choice) — affects README badges
a) PyPI
b) npm
c) Not published
-
Repo type (single choice) — affects which quality gates apply
a) Application or library with a test suite
b) Documentation / markdown / tool repo (no test suite, no package)
-
Codecov (single choice — skip if repo type is (b) above)
a) Yes — CODECOV_TOKEN already set in repo secrets
b) Yes — token not yet set (will need to configure)
c) No
-
Timezone (open, default: Europe/Copenhagen) — for Dependabot schedule
-
Pre-commit installed locally? — run pre-commit --version to check, or ask the user
Phase 2 — Analyse the repo
ls pyproject.toml uv.lock requirements*.txt
ls package.json bun.lock web/package.json
find .github -type f | sort
ls *.md LICENSE .pre-commit-config.yaml
gh repo view --json name,description,homepageUrl,repositoryTopics
Identify gaps against the checklist before writing anything.
Phase 3 — Apply the checklist
3a. Repo metadata
gh repo edit \
--description "One-line description" \
--homepage "https://..." \
--add-topic "topic1" --add-topic "topic2"
Use 6–8 topics: language, framework, domain terms.
3b. LICENSE
Download — do not generate from memory.
curl -fsSL "https://www.gnu.org/licenses/gpl-3.0.txt" -o LICENSE
3c. .github/CODEOWNERS
* @<handle>
3d. Dependabot
Load the right template with skill_view:
- Python:
templates/dependabot-python.yml
- TypeScript/Bun:
templates/dependabot-typescript-bun.yml
Save as .github/dependabot.yml. Adjust timezone and directory as needed.
3e. GitHub Actions workflows
ci.yml (caller — same for both stacks):
Load templates/ci.yml
checks.yml (reusable — all quality gates):
- Python:
templates/checks-python.yml
- TypeScript/Bun:
templates/checks-typescript-bun.yml
codeql.yml:
- Python:
templates/codeql-python.yml
- TypeScript/Bun:
templates/codeql-typescript.yml
scorecard.yml (same for both stacks):
Load templates/scorecard.yml
Save all to .github/workflows/. Adjust working-directory in checks if package.json is not at web/.
Python: ensure pyproject.toml has pytest configured to emit both coverage.xml and junit.xml:
[tool.pytest.ini_options]
addopts = "--cov=src --cov-report=xml --junitxml=junit.xml -q"
3f. Pre-commit hooks
- Python:
templates/pre-commit-python.yaml
- TypeScript/Bun:
templates/pre-commit-typescript-bun.yaml
Save as .pre-commit-config.yaml. Then install:
pip install pre-commit
pre-commit install
pre-commit run --all-files
3g. Community health files
| File | Required | Notes |
|---|
README.md | ✅ | See section 3j |
LICENSE | ✅ | Full text, downloaded not generated |
SECURITY.md | ✅ | Private advisory link, real risk surface — not generic boilerplate |
CONTRIBUTING.md | ✅ | Dev setup, test expectations, PR scope |
CHANGELOG.md | ✅ | Keep a Changelog format, seed Unreleased section |
.github/ISSUE_TEMPLATE/bug_report.md | ✅ | Environment, steps, output block |
.github/ISSUE_TEMPLATE/feature_request.md | ✅ | Problem / solution / alternatives |
.github/PULL_REQUEST_TEMPLATE.md | ✅ | Checklist anchored to actual project standards |
AGENTS.md | ✅ | Repo-specific conventions for AI agents — injected automatically by Hermes when working in this repo. Encode: skill frontmatter rules (including tested_on, deprecated_since, superseded_by), version bump guidance (patch/minor/major), CHANGELOG discipline, sync-skills.py workflow, deletion checklist, commit convention. |
CODE_OF_CONDUCT.md | ❌ | Skip for single-maintainer projects — performative overhead |
SUPPORT.md | ❌ | Skip unless there is a community to support |
SECURITY.md advisory link format: https://github.com/<owner>/<repo>/security/advisories/new
3h. README badges
Order: CI, CodeQL, codecov, Scorecard, License, stack, tooling, last-commit.
Always applicable:
[](...)
[](...)
[](https://codecov.io/gh/<owner>/<repo>)
[](...)
[](LICENSE)
[](...)
Python stack additions:
[](https://www.python.org/)
[](https://github.com/astral-sh/ruff)
[](https://mypy-lang.org/)
[](https://github.com/PyCQA/bandit)
If published to PyPI:
[](https://pypi.org/project/<package>/)
[](https://pypi.org/project/<package>/)
[](...)
TypeScript/Bun stack additions:
[](https://www.typescriptlang.org/)
[](https://bun.sh)
[](https://biomejs.dev)
3i. Knip config (TypeScript only)
{
"entry": ["src/index.ts", "src/components/ui/**"],
"ignoreDependencies": ["tailwindcss"]
}
UI barrel export files (shadcn etc.) must be in entry, not ignore — otherwise every exported-but-internally-uncalled component is flagged as dead code.
3j. README structure and docs/ strategy
The README should be navigable in 60 seconds. Aim for under 150 lines.
Everything verbose belongs in docs/.
Required structure (in order):
- Title + one-line tagline
- Badges
- 2–3 sentence description — what it is, what problem it solves, what it is NOT
- Quick start — minimal path to running, nothing else
- Docs table — links into docs/
- Architecture — brief summary only
- Development — commands only, no prose
docs/ folder:
| File | Content |
|---|
docs/setup.md | Full install, manual steps, prerequisites detail |
docs/commands.md | Full CLI/API reference, all flags and options |
docs/features.md | Capability matrix, known limitations |
docs/architecture.md | Deep-dive: components, data flow, design decisions |
docs/deployment.md | Container setup, infrastructure, environment config |
docs/development.md | Test strategy, coverage expectations, model/schema changes |
Create only the files that have real content. Stub files are noise.
Assessment checklist for an existing README:
- Does it describe what the project is NOT (where that matters)?
- Is quick start truly minimal, or does it have manual-setup detail inline?
- Is there a deployment section that belongs in
docs/deployment.md?
- Is there an architecture section longer than ~10 lines? Move the detail.
- Are numbered manual steps inline that belong in
docs/setup.md?
- Does CONTRIBUTING.md duplicate README dev-setup content? Pick one.
Refactor: move content into docs/ files, replace with one-line summary + link. Commit README and docs/ together.
Phase 4 — Verify
pre-commit run --all-files
gh run list --repo <owner>/<repo> --limit 5
Commit convention
One commit per logical group:
ci: add quality gates (biome, typecheck, knip, gitleaks, osv-scanner, CodeQL, Scorecard)
docs: add GPLv3 license, update README with badges
docs: add SECURITY, CONTRIBUTING, CHANGELOG, issue templates, PR template
chore: set repo metadata and topics
Checklist before committing
Before the first commit, verify:
Pitfalls
Markdown/tool repos (no test suite). Skip Codecov entirely — nothing to measure. Skip language-specific badges (Python, Bun, Biome, etc.) unless the repo has runnable scripts. Dependabot: scope to github-actions ecosystem only. Pre-commit: gitleaks + repo-specific validators only (no ruff, mypy, biome). Consider enabling GitHub Discussions — low-friction feedback channel for repos where formal bug reports are overkill.
osv-scanner-action has no floating @v2 tag. Only point releases (@v2.3.8). Also a reusable workflow, not a composite action — cannot be used as a step. Always use the CLI download in templates/checks-typescript-bun.yml.
Codecov empty token in reusable workflow. secrets: inherit in ci.yml passes repo secrets through, but checks.yml must declare CODECOV_TOKEN under on.workflow_call.secrets. If INPUT_CODECOV_TOKEN: is blank in CI logs, check the declaration and secret name match exactly.
Codecov badge shows "unknown". Repo must be activated on codecov.io after the first upload. Go to codecov.io/gh/<owner>/<repo> and activate. Takes 30 seconds.
Scorecard badge delay. Shows "unknown" for a few hours after first push. securityscorecards.dev needs to index the first run. Resolves automatically.
lcov not generated by default in Bun. bun test --coverage prints a table but does not write a file. Pass --coverage-reporter=lcov. Output: coverage/lcov.info relative to working-directory.
Biome schema version mismatch in pre-commit. After updating biome, run bunx biome migrate --write. Otherwise pre-commit fails with a schema version error.
knip flags UI barrel exports. Add UI barrel files (shadcn etc.) to entry, not ignore. See section 3i.
Skill description over 150 characters blocks commit. If this repo runs validate.py as a pre-commit hook, skill descriptions over 150 chars will fail on the first commit. Check length before writing: python3 -c "print(len('your description here'))". Fix by shortening — do not widen the schema limit.
CHANGELOG discipline — two steps, both required. First: add the change under [Unreleased]. Second: once the version is known, promote [Unreleased] entries to a proper versioned section (## [x.y.z] — dd.MM.yyyy). Leaving changes stranded under [Unreleased] after a version bump is incomplete. Do both in the same commit.
Skill description too long blocks every commit. If the repo runs a schema validator as a pre-commit hook, descriptions over the maxLength (150 chars in this library) block all commits — not just the one touching the skill file. Check lengths before installing pre-commit, not after.
CHANGELOG.md is easy to forget. Every professionalisation run touches multiple files. Add the CHANGELOG update to the commit checklist explicitly — it will be missed otherwise.
git push rejected when sync-skills ran in the same session. sync-skills push commits and pushes to the remote. If you then commit locally and push, the push is rejected. Always git pull --rebase && git push.
Shell injection in composite Action run: blocks. ${{ inputs.* }} in a run: block is template substitution that happens before the shell sees the script — any input value containing shell metacharacters executes arbitrary code. Fix pattern: assign all inputs to env vars in the step's env: block, build args as a bash array, drop eval.
run: |
ARGS="--section '${{ inputs.section }}'"
eval mk2conf publish $ARGS
env:
INPUT_SECTION: ${{ inputs.section }}
run: |
ARGS=()
[[ -n "$INPUT_SECTION" ]] && ARGS+=(--section "$INPUT_SECTION")
mk2conf publish "${ARGS[@]}"
Apply this pattern to every composite Action that builds shell commands from inputs. GitHub Marketplace reviewers flag eval with interpolated inputs — fix before submission.
.claude/commands/ filename collides with built-in slash commands. When shipping an AI skill that users install into .claude/commands/, a generic name like changelog.md becomes /changelog — which clashes with built-in commands in tools like Copilot CLI. Always use a namespaced filename: <tool>-<skill>.md (e.g. mk2conf-changelog.md → /mk2conf-changelog). Apply the same prefix discipline to Cursor .mdc files and Copilot .instructions.md files for consistency. Update docs and the invocation example (e.g. /changelog → /mk2conf-changelog) in the same commit.
raw.githubusercontent.com CDN lag. After a successful git push, the raw file URL may serve a stale version for 1–5 minutes. This is Fastly edge cache — browser cache clears do not help. If a user reports "the change isn't showing", confirm the push landed (git log origin/main) and wait. Do not re-push or re-patch based on CDN lag alone.
Skill version must be quoted SemVer with three parts. version: "1.0" is not valid — use "1.0.0". The schema accepts two-part versions silently but AGENTS.md requires three-part. If backfilling, set to "1.0.1" (patch bump) to signal the format correction without implying a content change. Validate before syncing: grep for version: " and check each value has two dots.