When a company decides to open-source something, the code is usually the easy part. It already exists. What decides whether the project is trusted, found and contributed to is everything around the code. That's the part I do. Here is my checklist, in the order I do it.
1. Audit the history before anything goes public
Making a repository public publishes every commit, not just the latest version. Scan the whole history first:
gitleaks detect --source . --log-opts="--all"
trufflehog git file://. --only-verified
Also search for internal hostnames, IP ranges, customer names and emails. If something is found you have two options:
- rewrite history with
git filter-repo, then rotate the secret anyway, because once it has been pushed you must assume it has leaked; - or start the public repository from one clean initial commit and keep the old history private.
Check that you aren't about to push private branches or tags too.
2. Choose the licence on purpose
- Apache-2.0: permissive, with an explicit patent grant. Legal teams like it, so it's my default for tools and standards you want adopted.
- MIT: shortest and simplest, with no patent clause.
- Source-available (e.g. BSL): readable and usable, but protects commercial interests. Be honest that it isn't OSI open source.
Put the full text in LICENSE at the root so GitHub detects it and shows it in the sidebar.
3. A structure people recognise
README.md LICENSE CHANGELOG.md
CONTRIBUTING.md CODE_OF_CONDUCT.md SECURITY.md GOVERNANCE.md CODEOWNERS
.github/ISSUE_TEMPLATE/bug_report.yml feature_request.yml config.yml
.github/PULL_REQUEST_TEMPLATE.md
.github/workflows/ci.yml release.yml
.github/dependabot.yml
docs/ examples/ src/ tests/
Use lowercase, hyphenated, descriptive names. Version docs and schemas with the code (docs/v0.1/) so old links keep working.
4. Be findable: GitHub SEO
- Name: short, lowercase, searchable. Avoid internal codenames nobody would type.
- Description: one sentence, main keywords first. It's what GitHub search and Google show.
- Topics: up to 20, specific rather than generic, so the repo appears on topic pages:
gh repo edit --description "Read-only GPU waste scanner for Kubernetes inference clusters" \ --homepage "https://example.com" --add-topic kubernetes,gpu,llm-inference,vllm,mlops - README: an H1 with the name, one line saying what it does, then the problem, a copy-paste quick start, examples and links. Use real headings, because search engines index them. Add badges (licence, CI, version) and alt text on images.
- Social preview: a 1280×640 image in Settings, so links look good when shared.
- Profile: pin the repository on the organisation profile, and link it from the company website and docs.
5. Commit and merge rules
- Conventional Commits:
feat:,fix:,docs:,chore:,refactor:. The history becomes readable and release notes can be generated. - Squash merge only (Settings → General → Pull Requests), with the PR title as the commit message. One PR becomes one clean commit that is easy to revert.
- Automatically delete head branches after merge, so old branches don't pile up.
- Semantic versioning with tags and generated release notes:
git tag -a v0.1.0 -m "v0.1.0" git push origin v0.1.0 gh release create v0.1.0 --generate-notes
6. Rulesets on the default branch
Settings → Rules → Rulesets → new branch ruleset, targeting the default branch:
- Restrict deletions and block force pushes.
- Require linear history.
- Require a pull request before merging, with 1+ approvals, dismissing stale approvals and requiring review from Code Owners.
- Require status checks to pass (your CI jobs).
Pair it with a CODEOWNERS file so the right people are requested on the right files automatically.
7. Security from day one
- SECURITY.md: supported versions and how to report privately. Turn on private vulnerability reporting so reports never start as a public issue.
- Dependabot alerts and security updates, plus a
dependabot.ymlcovering the package ecosystem andgithub-actions. - Secret scanning with push protection. It's free on public repositories and blocks a leaked token before it lands in history.
- Code scanning (CodeQL default setup) where the language is supported.
- Least-privilege workflows. Start every workflow with
permissions: contents: readand grant more only where needed. Be careful withpull_request_targeton code from forks.
8. Workflows that protect quality
- CI on every pull request: lint, tests, build.
- Project-specific checks. For a specification, validate every example against the schema, so a broken example can never be merged.
- A release workflow that builds and publishes the package when a version tag is pushed.
9. Make contributing easy
- CONTRIBUTING: local setup, branch naming, commit style and a PR checklist.
- Issue forms (YAML), not free text, so bug reports arrive with versions and steps to reproduce.
- Labels such as
good first issueandhelp wanted, which GitHub surfaces to new contributors. - Discussions for questions and ideas, so issues stay for actual work.
- Check Insights → Community standards until every item is ticked.
10. Launch
Flip the repository to public, then check it logged out in a private window. Read the README as a stranger would. Publish the first release, and announce it with a link straight to the quick start.
That's the job: the client brings the code, and I make sure the world can find it, trust it and contribute to it. I did exactly this for three AI-infrastructure projects. You can read the case study.
Written by Ameer Hamza, Linux systems engineer in Lahore. Need help with something like this? Get in touch.