Appearance
Commit Message Format
We use conventional commits:
<type>(<scope>): <short summary> #<ticketid|0>Types and scopes are listed in .github/scripts/pr-title-lint.config.json — the source of truth, kept current because the library and move generators append new project scopes to it. Local commits are not linted, but reuse those values: the PR title is auto-filled from your first commit subject, and it is linted (see below).
Just before committing, ensure that:
- Ticket ID is provided, prompt user if missing.
- Short summary is concise and descriptive.
- The commit subject line has a hard limit of 72 characters — the whole
<type>(<scope>): <summary> #<ticketid>, prefix and ticket included. Character counts cannot be estimated reliably, so measure it, do not guess: after writing the message rungit log -1 --format=%s | awk '{print length}'and, if it prints more than 72, shorten the summary and amend the commit until it does. A PR's title is auto-filled from the first commit's subject, and GitHub truncates longer subjects with a…, which can cut off the trailing ticket id. If a longer, more descriptive title is genuinely warranted, keep the commit subject within 72 and set/edit the PR title manually instead — a manually entered PR title is not subject to that truncation. - All tests pass and that linting is successful.
- If linting fails, run
pnpm run lint:fix && pnpm run formatto automatically fix issues where possible.
- If linting fails, run
Pull Request Title
CI lints the PR title (PR · Title Lint) because we squash-merge — the title, not your commits, becomes the commit on master. Local commit messages are intentionally left free.
<type>(<scope>): <short summary> <ticket>- Type and scope must appear in
.github/scripts/pr-title-lint.config.json, the source of truth. Scopes are app/domain names (recruitee,grow,manage,workspace, …), never feature names —feat(grow): …, notfeat(custom-surveys): …. - The ticket must end the title, unbracketed:
… #86cauuv77, not… (CU-86cauuv77). Prefixes#,CU-andKI-are accepted; one ticket is enough. - The
workspacescope needs no ticket. Draft and bot PRs are skipped.
Since the title is auto-filled from the first commit's subject, end that subject with a bare ticket id and the PR title passes as-is.
A red X here is informational — it comments and fails the step, but does not block merging. Why → decision log FE-0002.