Update README: - Bump minimum common-repo version to 0.28.4 - Add 'Using a different GitHub App' section with override example - Note release.yaml sync exception in repo structure
cr-semantic-release
A common-repo source template for conventional commits and semantic releases.
What's Included
Files distributed from src/:
| File | Purpose |
|---|---|
.releaserc.yaml |
semantic-release config (conventionalcommits preset, changelog, git, GitHub release, major-tag) |
commitlint.config.js |
commitlint config extending @commitlint/config-conventional |
.github/workflows/commitlint.yml |
PR commit lint workflow using wagoid/commitlint-github-action |
.github/workflows/release.yaml |
Semantic release workflow (triggers on push to main, uses GitHub App token) |
Usage
Requires common-repo ≥ 0.28.4 for source-declared filtering and template variable overrides.
Add to an existing .common-repo.yaml
# .common-repo.yaml
- repo:
url: https://github.com/christmas-island/cr-semantic-release
ref: v1.1.0
That's it. The source repo's .common-repo.yaml handles scoping to src/ and stripping the prefix.
Apply
cr diff # preview changes
cr apply # apply
Repo Structure
cr-semantic-release/
├── .common-repo.yaml ← source-declared filtering (include src/, rename to root)
├── .github/workflows/ ← this repo's own CI (dogfooding)
│ ├── ci.yaml ← sync check: top-level == src/
│ ├── commitlint.yml ← commit linting for this repo
│ └── release.yaml ← semantic release for this repo
├── .releaserc.yaml ← this repo's own release config
├── commitlint.config.js ← this repo's own commitlint
├── README.md
├── LICENSE
└── src/ ← distributed to consumers
├── .github/workflows/
│ ├── commitlint.yml
│ └── release.yaml
├── .releaserc.yaml
└── commitlint.config.js
The top-level files and src/ files are identical — the repo eats its own dog food. CI enforces they stay in sync (except release.yaml, which uses template variables in src/ and hardcoded defaults at the top level).
Prerequisites
By default, the release workflow uses these GitHub org-level vars and secrets:
| Name | Type | Default | Purpose |
|---|---|---|---|
CHRISTMAS_ISLAND_APP_ID |
Variable | — | GitHub App ID for generating tokens |
CHRISTMAS_ISLAND_PRIVATE_KEY |
Secret | — | GitHub App private key |
These are used by actions/create-github-app-token to generate a token with write permissions for creating releases and pushing tags/changelogs.
Using a different GitHub App
Override the template variables in your consumer config to use your own app credentials:
- repo:
url: https://github.com/christmas-island/cr-semantic-release
ref: v2.0.0
with:
- template-vars:
GH_APP_ID_VAR: MY_APP_ID # GitHub vars name
GH_APP_KEY_SECRET: MY_APP_KEY # GitHub secrets name
GH_APP_OWNER: my-org # App installation owner
This renders the workflow with ${{ vars.MY_APP_ID }}, ${{ secrets.MY_APP_KEY }}, and owner: my-org.
Customization
Release workflow
The included release.yaml contains only the semantic-release job. It does not include a publish step (goreleaser, Docker, etc.) — add that in your repo's own workflow or extend via common-repo merge operators.
The workflow calls ./.github/workflows/ci.yaml as a prerequisite. Your repo must have a CI workflow at that path (or remove the ci job dependency).
Excluding files
If you only want a subset:
- repo:
url: https://github.com/christmas-island/cr-semantic-release
ref: v1.1.0
with:
- include: ["src/.releaserc.yaml", "src/commitlint.config.js"]
- rename:
- "^src/(.*)$": "$1"
Overriding .releaserc.yaml
Use common-repo's YAML merge operator to patch specific fields:
- repo:
url: https://github.com/christmas-island/cr-semantic-release
ref: v1.1.0
- yaml:
source: my-releaserc-overrides.yaml
dest: .releaserc.yaml
path: plugins
array_mode: replace