Engineering

Contractor-Friendly Repo Hygiene

By C. V. Wooster

README truth, env samples, and deploy notes beat tribal knowledge.

A small studio's software is often touched by many hands over time: the original builder, a contractor brought in for a feature, an automated assistant fixing a bug, and someone months later who has to figure out why a deploy failed. Each of those people starts with the same question: how does this thing work, and how do I change it without breaking anything?

If the answer lives only in someone's head, every change is slow and risky. If it lives in the repository, anyone competent can be productive in an afternoon. That's what we mean by contractor-friendly repo hygiene: a repository that explains itself.

Why it matters more for small teams

Large companies can absorb the cost of tribal knowledge with onboarding programs and internal wikis. A small studio can't. When the one person who knows how a site deploys is unavailable, work stops. When a contractor spends two days reverse-engineering environment variables, that's two days of budget gone before any real work begins.

Good hygiene also reduces risk. Most outages and security incidents we've heard about in small projects trace back to undocumented assumptions: a variable nobody knew was required, a manual step nobody wrote down, a secret committed to the code years ago.

The README should tell the truth

A README is the front door of a repository. The most common problem isn't a missing README but an outdated one, describing a setup that no longer exists. A wrong README is worse than none, because people trust it.

A useful README answers, briefly:

  • What this is. One paragraph: what the project does, which site or product it powers, and who uses it.
  • How to run it locally. The exact commands, in order, including the package manager and runtime version.
  • How it's deployed. Where it runs, what triggers a deploy (a merge to the main branch, a manual command) and how to check whether a deploy succeeded.
  • Where configuration lives. Which environment variables are required and where to find their values (not the values themselves).
  • Known quirks. Anything surprising: a service that isn't connected to automatic deploys, a scheduled job that runs at a certain time, a dependency pinned for a reason.

We try to update the README in the same pull request as any change that affects it. If a reviewer notices a setup change without a README change, the pull request isn't finished.

Environment samples instead of secrets

The Twelve-Factor App methodology, published by developers at Heroku in 2011, recommends storing configuration in the environment rather than in code. That principle has become standard practice, and it pairs naturally with an example environment file.

A .env.example file lists every environment variable the application expects, with dummy values and a short comment on what each does. It's committed to the repository; the real .env file with actual secrets never is.

Rules we follow:

  • Never commit secrets. API keys, database passwords and tokens stay out of the repository. If one is ever committed by mistake, assume it's compromised and rotate it; removing it from the latest commit doesn't remove it from history.
  • Fail loudly when configuration is missing. An application that starts without a required variable and silently misbehaves is much harder to debug than one that refuses to start with a clear message.
  • Keep the example in sync. Adding a new variable without updating the example file is a bug.

GitHub and other hosts offer secret scanning that can catch some accidental commits, but it's a safety net, not a strategy.

Deploy notes and runbooks

Every repository should explain how code gets from a merged change to production, and what to do when that fails. For simple projects, that can be a short section in the README. For anything more involved, a separate docs/deploy.md or runbook helps.

Useful contents:

  • The hosting platform and project name.
  • Whether merges deploy automatically, and if not, the exact command to deploy.
  • How to view logs and recent deployment status.
  • How to roll back to a previous version.
  • Any post-deploy checks, such as visiting key pages or confirming a sitemap loads.

When something goes wrong at an inconvenient hour, a clear runbook turns panic into a checklist.

Tests that protect what matters

Not every small project needs extensive automated tests, but every project benefits from a few that guard its most important behavior. For our sites, that often means tests that confirm key pages render, that unknown URLs return a real 404, that legal pages exist, and that advertising and analytics code appear where they should and nowhere else. Those tests act as documentation too: they tell a newcomer what the project promises.

Commit and pull request habits

Small habits make history readable:

  • Descriptive commit messages. "Fix soft 404 for unknown blog slugs" is useful; "updates" is not.
  • Focused pull requests. One concern per pull request makes review and rollback easier.
  • A short "why" in each pull request description. Code shows what changed; the description should explain why.
  • Changelogs for anything with users. The Keep a Changelog convention is a simple format for recording notable changes.

Dependency upkeep

Dependencies age. Tools like GitHub's Dependabot can open pull requests when updates are available, including security updates. Even without automation, scheduling a periodic dependency review keeps projects from drifting so far behind that updating becomes a major project.

A quick self-audit

If you inherit or maintain a repository, try this: imagine a capable stranger has one afternoon to make a small change and deploy it. Could they?

  • Can they run it locally from the README alone?
  • Do they know which environment variables they need?
  • Can they tell how it deploys and confirm it worked?
  • Would they know how to roll back?

Every "no" is a small documentation task worth doing now. This kind of hygiene supports everything else we care about as a studio, from building small tools for specific jobs to keeping shared standards across our sites. It isn't glamorous, but it's what lets a small team move quickly without breaking things.