repo-guardrails
v0.2.0
Published
Reusable Conventional Commit and branch-name guardrails for Node.js and shell-based repositories.
Maintainers
Readme
repo-guardrails
repo-guardrails gives Node.js and shell-based repositories consistent Git contribution rules: Conventional Commit messages, predictable branch names, local hooks, matching GitHub Actions checks, and documented main branch protection.
It is designed to provide fast local feedback while making GitHub the authority for merging. Local hooks can be bypassed and are not a security boundary. A failed GitHub check blocks merging only when that exact check is required by an active ruleset.
Use it when you want contributors to follow the same commit and branch conventions locally and in pull requests without rebuilding the tooling in every repository.
Choose an adapter
- Node.js repositories: use the npm installation and Husky setup below.
- Shell-based repositories: clone a tagged release of this repository and run
bin/repo-guardrails.sh initfrom the target repository. It copies dependency-free Bash validators, repository-owned hooks, and GitHub workflow templates. It does not require Node.js or npm in the target repository.
Both adapters enforce the same branch-name policy. The shell adapter validates Conventional Commit subjects with the built-in types documented below.
See the architecture for the adapter approach.
Set up a Node repository
Follow these steps in order.
1. Check the requirements
You need Git, Node.js 20 or newer, an npm project with a committed lockfile, and repository administration access to configure GitHub rules.
2. Install and initialize
From the npm and Git repository root:
npm install --save-dev repo-guardrails
npx repo-guardrails initinit adds missing branchlint, commitlint, and prepare scripts and creates:
commitlint.config.mjs
.husky/commit-msg
.husky/pre-push
.github/workflows/commitlint.yml
.github/workflows/branchlint.ymlExisting files and differing scripts are reported and preserved, never silently replaced. Review all generated changes before committing them.
Set up a shell repository
You need Git, Bash, a checkout of a tagged Repo Guardrails release, and repository administration access to configure GitHub rules. From the target repository root:
/path/to/repo-guardrails/bin/repo-guardrails.sh initThis creates .repo-guardrails/, .githooks/, and matching GitHub workflows. It does not require Node.js or npm. Review generated files before committing them.
Protect main
Commit the generated files, plus package changes for Node repositories, on a conventionally named branch. Push it and open a pull request into main. This first pull request registers the Commitlint and Branchlint checks with GitHub.
Wait for both checks to finish. Fix any failure before configuring the ruleset.
The package cannot change repository rules without administration permission:
- Open Settings → Rules → Rulesets.
- Create a branch ruleset targeting the default branch, or import
templates/main-ruleset.json. - Require pull requests, at least one approval, and resolved conversations when appropriate.
- Block force pushes and branch deletion.
- Require branches to be up to date before merging.
- Require the exact
CommitlintandBranchlintstatus checks. - Review imported check names, integration identifiers, default branch, merge methods, and repository-specific settings.
Select checks whose source is GitHub Actions. Do not choose the generic Any source entry. If Branchlint is not listed with GitHub Actions as its source, return to the previous step and let it run on a pull request first.
Confirm both checks are required in the active ruleset. Test with a pull request from an invalid branch such as feature/invalid-name or with a commit such as bad message. The appropriate check should fail and GitHub should prevent merging.
You can also run the checks manually:
npx repo-guardrails branchlint
npx repo-guardrails branchlint feat/42-add-search
printf 'feat: add search\n' | npx repo-guardrails commitlintConventions
Commit messages
Use Conventional Commits:
<type>[optional scope]: <description>feat: add account settings
fix(auth): preserve the user session
docs: update contributor instructions
test(api): cover invalid requests
chore: update toolingCommon types include feat, fix, docs, test, refactor, chore, ci, build, perf, style, and revert. Scopes are optional. Defaults come from @commitlint/config-conventional.
Branch names
Human-created branches use:
<type>/<description>Branchlint supports the Conventional Branch 1.1
types feature, feat, bugfix, fix, hotfix, release, chore,
ai, copilot, cursor, claude, and codex, plus Repo Guardrails'
docs, test, refactor, perf, build, and ci types. All branch
names are lowercase. Descriptions use letters and numbers, with single hyphens
between segments and single dots within segments. Ticket numbers can be
included when applicable.
feat/42-add-search
fix/session-expiration
release/v1.2.0
codex/optimize-query
docs/git-workflowmain is the only exempt trunk branch, and dependabot/* is exempt for
automation. Names such as master, develop, feat/New_UI,
feature/new--ui, and release/v1.2.0. are rejected.
How enforcement works
- Node uses
.husky/commit-msgand.husky/pre-push. - Shell uses
.githooks/commit-msgand.githooks/pre-push. commitlint.ymlchecks commits on every branch push and pull request.branchlint.ymlchecks branch creates, updates, and pull-request source branches. It skips tag pushes and branch deletions.- The GitHub ruleset makes the remote checks authoritative for merging.
Local pre-push hooks follow the same ref policy: they validate creates and
updates under refs/heads/, skip deleted branches, and ignore tags. main and
dependabot/* remain explicit policy exemptions. GitHub merge-queue refs are
not linted as human branch names; pull-request checks validate the source branch
before it enters a queue.
Each repository must contain workflow YAML because GitHub reads workflows before npm installs dependencies; it cannot discover workflows inside node_modules. Small copied workflows are easy to inspect, but template updates must be applied manually. Contributors changing this project's workflow templates must follow the workflow conventions.
Update, configure, or remove a Node repository
npm install --save-dev repo-guardrails@latest
npx repo-guardrails initinit preserves existing files. Compare them with node_modules/repo-guardrails/templates/ when adopting template updates. Version one keeps branch rules fixed; projects can import validateBranchName from repo-guardrails for custom behavior.
To remove it, run npm uninstall repo-guardrails, delete its three scripts and five generated files if unused, and remove .husky/ when no hooks remain. You can then run git config --unset core.hooksPath.
Troubleshooting
- Hooks do not run: run
npm install, thennpm run prepare, and commit.husky/. npm cifails in Actions: commit the lockfile produced by the supported package manager and Node version.- Bad changes can merge: require the exact GitHub Actions-sourced
CommitlintandBranchlintchecks. initskipped a file: compare it with the matching packaged template and merge intentionally.- Detached HEAD: pass the branch explicitly:
repo-guardrails branchlint <name>.
Contributing, development, and publishing
Clone this repository and install its locked dependencies:
git clone https://github.com/srejames/repo-guardrails.git
cd repo-guardrails
npm ci
npm test
npm pack --dry-runDo not run npx repo-guardrails init in this repository. init installs Repo Guardrails into a consuming repository; this repository already contains its hooks, workflows, and configuration. Because init preserves existing files, it is not an update mechanism for checked-in templates or workflows.
Create a conventionally named branch, use Conventional Commit messages, and run the full test suite before opening a pull request. When changing workflows, follow the workflow conventions and update the Node and shell templates together. This repository uses the Node adapter, so its checked-in .github/workflows/ files must remain identical to the corresponding templates/node/workflows/ files.
Before publishing, confirm the package name is available, inspect the exact tarball contents, test installation in a disposable repository, and ensure no secrets or unrelated files are included. Releases follow semantic versioning.
Security and license
Hooks are bypassable, workflows can be changed, and administrators may be allowed to bypass rules. Review workflow and ruleset changes as security-sensitive configuration.
This project uses the MIT License, allowing use, modification, distribution, sublicensing, and sale while retaining the notice and providing no warranty.
