Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions .github/actions/commitlint/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Lint commit messages
description: >-
Lints a pull request's commit messages against the Radius Red commitlint
config shipped in this directory (Conventional Commits). The action does
not check out: the caller runs actions/checkout with fetch-depth 0 first,
from a job named exactly "Lint commit messages" (the org ruleset
require-lint pins that check context). See CONTRIBUTING.md.

runs:
using: composite
steps:
- name: Place the shared commitlint config in the workspace
id: stage
shell: bash
# wagoid/commitlint-github-action is a Docker action. It resolves
# configFile against GITHUB_WORKSPACE inside its container, and the
# runner's _actions directory (where this action is checked out) is
# not mounted there, so a path into the action directory would fall
# back silently to bare config-conventional. Copy the config into the
# workspace instead, into a directory this action creates itself:
# mktemp -d makes a fresh, uniquely named directory and fails rather
# than reuse one, so nothing the caller owns is overwritten, and the
# cleanup below removes only that directory.
run: |
dir="$(mktemp -d "${GITHUB_WORKSPACE}/.radiusred-commitlint-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}.XXXXXXXX")"
cp "${{ github.action_path }}/commitlint.config.mjs" "${dir}/commitlint.config.mjs"
echo "dir=${dir#"${GITHUB_WORKSPACE}/"}" >> "${GITHUB_OUTPUT}"
echo "commitlint config placed at ${dir}/commitlint.config.mjs:"
cat "${dir}/commitlint.config.mjs"

- name: Lint the commit messages
uses: wagoid/[email protected]
with:
configFile: ${{ steps.stage.outputs.dir }}/commitlint.config.mjs

- name: Remove the copied config
if: always() && steps.stage.outputs.dir != ''
shell: bash
env:
STAGE_DIR: ${{ steps.stage.outputs.dir }}
run: rm -rf "${GITHUB_WORKSPACE}/${STAGE_DIR}"
File renamed without changes.
8 changes: 7 additions & 1 deletion .github/workflows/commitlint.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
# Reference caller for the shared commitlint action. Other repositories copy
# this file and replace the local `uses:` path with
# `radiusred/.github/.github/actions/commitlint@main`; this repository calls
# the action by path so a PR here tests the version of the action it carries.
# The job name is the check context the org ruleset require-lint requires.
name: Lint commit messages

on:
pull_request:

permissions:
contents: read
pull-requests: read

jobs:
commitlint:
Expand All @@ -14,4 +20,4 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: wagoid/commitlint-github-action@v6
- uses: ./.github/actions/commitlint
64 changes: 60 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,19 @@ other repositories consume:
from their `prepare-release` and `finalize-release` workflows.
- `.github/actions/calculate_version` — the version-calculation action the
release workflow runs.
- `.github/actions/commitlint` — the shared commit-message lint action, with
the organisation's `commitlint.config.mjs` inside it. Any repository that
lints commit messages calls it from a thin workflow (see
[Linting commit messages in a repository](#linting-commit-messages-in-a-repository));
this repository's own `.github/workflows/commitlint.yml` is the reference
caller.
- `profile/` — the organisation profile shown at
[github.com/radiusred](https://github.com/radiusred).

Beyond those, the repository carries only its own housekeeping: this file,
`.gitignore`, and `.codecrew.yml`, which points CodeCrew coordination for this
repository at the company hub. Each project's documentation lives with the
`.gitignore`, `.codecrew.yml`, which points CodeCrew coordination for this
repository at the company hub, and `.github/workflows/commitlint.yml`, its own
call of the shared commit lint. Each project's documentation lives with the
project.

## Contributing to a project
Expand All @@ -38,16 +45,65 @@ is its contributing guide.)
If you are unsure whether a change is wanted, open an issue in the repository
concerned describing the goal before writing the code.

## Linting commit messages in a repository

Every Radius Red repository lints pull-request commit messages against
[Conventional Commits](https://www.conventionalcommits.org/) through the
shared action in this repository, so the config and the pinned
`wagoid/commitlint-github-action` version change in one place. Do not add a
`commitlint.config.mjs` to the calling repository; the action carries it.

Copy this file to `.github/workflows/commitlint.yml` in the repository:

```yaml
name: Lint commit messages

on:
pull_request:

permissions:
contents: read
pull-requests: read

jobs:
commitlint:
name: Lint commit messages
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: radiusred/.github/.github/actions/commitlint@main
```

- **The job name must be exactly `Lint commit messages`.** It is the check
context the organisation ruleset `require-lint` requires on the default
branch of every public repository; a job named anything else reports a
different context, and pull requests cannot merge until a check with the
required one passes. (This is why the shared piece is a composite action
rather than a reusable workflow: GitHub reports a called workflow's job as
`caller job / called job`, which can never equal the required context.)
- **Permissions.** `contents: read` is for the checkout. `pull-requests: read`
lets the action list the pull request's commits; a private repository
fails without it, a public one merely gets it for free. Keep both.
- **The action does not check out.** Run `actions/checkout` with
`fetch-depth: 0` before it, as above.
- This repository calls the action by local path (`./.github/actions/commitlint`)
instead of `@main`, so a pull request here tests the version of the action
it carries. Every other repository uses `@main`.

## Changing this repository

`main` is protected: changes arrive by pull request, history is linear (rebase
only, no merge commits), and commit messages follow
[Conventional Commits](https://www.conventionalcommits.org/).

- Callers reference the reusable workflows and the action at `@main`, so a
- Callers reference the reusable workflows and the actions at `@main`, so a
merge here is live for every caller at once. Say in the PR which callers you
checked, and keep workflow inputs, secrets and outputs backward compatible
or land the callers' change alongside.
or land the callers' change alongside. A change to the commitlint config or
to the pinned `wagoid/commitlint-github-action` version is proved by this
repository's own `Lint commit messages` check before it can merge.
- Keep the profile accurate; it is what a visitor to the organisation sees
first.
- Never include secrets or internal data in a public PR.
Expand Down
Loading