@acme-skunkworks/commitlint-config
v1.0.0
Published
Shared commitlint configuration for ACME Skunkworks packages.
Maintainers
Readme
@acme-skunkworks/commitlint-config
Shared commitlint configuration for ACME Skunkworks packages.
It single-sources the estate's allowed Conventional Commit types into one published package, consumed by both layers of the commit gate so the ruleset can never drift between them:
- the reusable CI workflow (
reusable-validate-commits.yml) that validates a PR'sbase..headcommit range, and - the local husky
pre-pushhook that runs the same range check before a push ever reaches CI.
It extends @commitlint/config-conventional and retains all of its defaults — only the list of allowed commit types is pinned to the estate's set.
Install
pnpm add -D @acme-skunkworks/commitlint-config @commitlint/cli@commitlint/config-conventional is a runtime dependency of this package, so installing this config pulls it in automatically — you do not need to add it yourself.
Usage
Point your commitlint config at this package:
// commitlint.config.mjs
export default {
extends: ["@acme-skunkworks/commitlint-config"],
};The example uses .mjs so the export default works regardless of the consuming project's module type. In an ESM project ("type": "module") a plain commitlint.config.js works too; in a CommonJS project use .mjs (as above) or module.exports in a .js/.cjs file.
Then validate a commit-message range — exactly what the CI workflow and the pre-push hook do:
# lint every commit on the branch that isn't on the base
pnpm exec commitlint --from "origin/main" --to "HEAD"Allowed commit types
The type-enum rule is set explicitly and is aligned to the estate's release-please bump rules:
| Type | Release bump | Notes |
| ---------- | ------------ | -------------------------------------- |
| feat | minor | A new feature |
| fix | patch | A bug fix |
| perf | patch | A performance improvement |
| revert | patch | Reverts a previous commit |
| chore | none | Tooling / housekeeping |
| docs | none | Documentation only |
| ci | none | CI configuration and pipelines |
| build | none | Build system or external dependencies |
| refactor | none | Neither fixes a bug nor adds a feature |
| test | none | Adding or correcting tests |
| style | none | Formatting; no code-behaviour change |
A ! marker or a BREAKING CHANGE: footer promotes any type to a major bump.
Everything else is inherited from @commitlint/config-conventional unchanged, including:
- a non-empty commit type and subject,
- the header max-length limit, and
defaultIgnores— merge (Merge …), revert (Revert …),fixup!andsquash!messages are skipped automatically, so this config never needs to blanket-ignore them by author identity.
Versioning: float on latest
The gate is designed to track this config's latest published version rather than pinning it, mirroring how the estate floats on its shared GitHub workflows (@v1). The reusable CI workflow installs the config fresh on each run, so a caret range with no committed lockfile resolves to the latest published version — a ruleset change reaches the gate on its next run, with no per-repo bump PR.
Where a consumer instead commits a lockfile (for example the local pre-push hook running in a repo that pins its dev-dependencies), the resolved version stays put until it is updated: the package is Dependabot-versioned like the estate's other shared packages, so those consumers get update PRs. The trade-off is deliberate — because a ruleset change reaches the floating consumers immediately, edits must be made carefully.
Development
pnpm install
pnpm build # tsc → dist/ (the published artifact)
pnpm test # vitest — behavioural tests over the resolved ruleset
pnpm tsc # type-check
pnpm lint # eslintThe ruleset itself is src/index.ts; src/index.test.ts exercises the effective config by resolving extends through @commitlint/load and linting sample messages with @commitlint/lint.
Licence
MIT
