create-pr
GitHub pull requests with titles validated against n8n's commit convention standards. Enforces conventional commit format with type, optional scope, and summary; supports nine commit types (feat, fix, perf, test, docs, refactor, build, ci, chore) with configurable changelog inclusion Provides predefined scopes for common areas (API, core, editor, benchmark, specific nodes) and validates title format including breaking change indicators and capitalization rules Includes PR body template with...
npx skills add https://github.com/n8n-io/n8n --skill create-prCreate Pull Request
Creates GitHub PRs with titles that pass n8n's check-pr-title CI validation
and short descriptions that tell the reviewer what the diff does not show.
PR Title Format
<type>(<scope>): <summary>
Types (required)
| Type | Description | Changelog |
|---|---|---|
feat | New feature | Yes |
fix | Bug fix | Yes |
perf | Performance improvement | Yes |
test | Adding/correcting tests | No |
docs | Documentation only | No |
refactor | Code change (no bug fix or feature) | No |
build | Build system or dependencies | No |
ci | CI configuration | No |
chore | Routine tasks, maintenance | No |
Scopes (optional but recommended)
API- Public API changesai-builder- AI Workflow Builder and Instance AIbenchmark- Benchmark CLI changescore- Core/backend/private APIeditor- Editor UI changesengine- New workflow execution engine v2 (@n8n/engine package & engine-v2 module in cli)* Node- Specific node (e.g.,Slack Node,GitHub Node)
check-pr-title accepts only these scopes. Do not use a package or folder
name as the scope (for example instance-ai, cli, evals or docker).
If no scope fits, omit the scope. To give two scopes, separate them with a
comma and a space: fix(core, editor): ....
Title Summary Rules
- Use imperative present tense: "Add" not "Added"
- Capitalize first letter
- No period at the end
- No ticket IDs (e.g., N8N-1234) and no PR numbers (e.g., #12345)
- Add
(no-changelog)as the last part to exclude the PR from the changelog, unless the type already excludes it - Put the exclamation mark for a breaking change before the colon
Steps
-
Check current state:
git status git diff --stat git log origin/master..HEAD --oneline -
Check for implementation plan: Look for a plan file in the repository plan directories (
.claude/plans/or.agents/plans/when present) that matches the current branch's ticket ID (e.g. if branch isscdekov/PAY-1234-some-feature, check forPAY-1234.md). If a plan file exists, ask the user whether they want to include it in the PR description as a collapsible<details>section (see Plan Section below). Only include the plan if the user explicitly approves. -
If this is a security fix, audit every public-facing artifact before proceeding (see Security Fixes below).
-
Analyze changes to determine:
- Type: What kind of change is this?
- Scope: Which scope from the Scopes list fits? Omit the scope if none fits.
- Title summary: What does the change do?
- Insights: What did the session (debugging, measurements, user discussion) find that a reviewer would otherwise miss?
-
Identify feature flag test settings: Inspect the full PR diff for new PostHog flags. Record the keys and values needed to test the new behavior as described in Feature Flag Test Settings below.
-
Push branch if needed:
git push -u origin HEAD -
Create PR using gh CLI. Read
.github/pull_request_template.mdas the body structure, then populate each section with actual content before creating the PR:- Summary: what the PR does and why, plus any surprises (see PR Body Guidelines below)
- How to test: the steps that a person follows in the product to see the change work, and the command that runs the tests
- Related tickets: add the Linear ticket URL (
https://linear.app/n8n/issue/[TICKET-ID]), any GitHub issue links, and the docs link if there is one
Before you create the PR, proofread the Summary against the Summary Section rules. Delete each sentence that restates the diff, or that is not the what-and-where sentence, the why, or a surprise. Make sure that each sentence is true for the diff.
When a later commit changes a fact in the body, update the body.
gh pr create --draft --title "<type>(<scope>): <summary>" --body "$(cat <<'EOF' <populated body based on pull_request_template.md> EOF )"
Feature Flag Test Settings
- Compare the branch with
origin/masterusinggit diff origin/master...HEAD. If the PR targets another branch, useorigin/<target-branch>instead. Inspect new experiment definitions inpackages/frontend/editor-ui/src/app/constants/experiments.ts, shared flag constants inpackages/@n8n/api-types, and new PostHog checks elsewhere in the diff. Resolve constants to the exact PostHog key string. Exclude removed flags, existing flags that the PR only references, and flag names that appear only in tests or documentation. - Select a test value for each new flag. Use
trueto enable a boolean flag. Read the flag's consumers and variant definitions for an A/B experiment. Use the exact variant that shows the new behavior. Do not assume that booleantrueselects a named variant. If the required variant is unclear, report it instead of guessing. Preserve any value that the user explicitly requested for the same key. - If step 1 found at least one new flag, include
N8N_FEATURE_FLAG_OVERRIDESin How to test. This environment variable accepts a JSON object that maps PostHog keys to boolean values or named variants. Tell the tester to set it before starting the test instance. For example:
Use JSONexport N8N_FEATURE_FLAG_OVERRIDES='{"136_skill_sync":true}'falseto disable a boolean flag, or a string for a named variant. Combine multiple overrides in one JSON object.
The Codespace preview runner does not read flag: labels. Do not create or
apply them. For supported preview settings, see the Preview toggles and Preview
environment from a webhook sections in .github/WORKFLOWS.md.
PR Body Guidelines
Based on .github/pull_request_template.md.
Keep the description short. The reviewer reads the diff for the details. The description gives only what the diff cannot show: why the change exists, and what could surprise the reviewer. Keep the length in proportion to the complexity of the change: a complex change usually has more surprises. A change with no surprises needs only the first two paragraphs of the Summary.
Write for an engineer. Use exact technical terms, and do not simplify them. Use ASD-STE100 Simplified Technical English: short sentences, active voice, plain technical verbs, no metaphors.
Summary Section
Write the Summary as up to three paragraphs:
<Verb> <what> in <area>.
<Why: the product value or the problem, and the rationale for the main choices.>
<Important details, only if there are surprises.>
- What and where: one sentence in the imperative mood, like the PR title ("Fix the ...", "Add ...", "Change the ..."). Do not start with "This PR". State the area of the product or code (for example, a node, the editor, or the CI pipeline) and the nature of the change, for example a bug fix or a feature. Do not name functions or fields. The diff shows them.
- Why: one or two sentences: the product value that the change adds or the problem that it fixes, and the rationale for the main choices.
- Important details: add this paragraph only when the change has one of
these surprises. Give each surprise one or two sentences:
- Unexpected behaviour: a change in behaviour for users or for other code paths, a changed default, a migration, or a side effect outside the obvious scope.
- Technical challenge: a root cause that is not obvious, a constraint that forced the design, a workaround, or a known gap or follow-up.
- Rejected alternative: only when a reviewer would suggest it. Give one sentence with the concrete reason it fails.
- Insight from the work: a surprising fact that you found while you made the change and that the diff and the ticket do not show. For example, a measurement, a reproduction detail, a cause found while debugging, or an error in the ticket.
Leave out what the diff shows: file lists, renamed fields, call order, test
names, error cases, and descriptions of the code. Leave out framework behaviour
that reviewers know. Do not add background or a closing sentence. Define an
n8n-internal term only if an engineer from another team would not know it.
For UI changes, add screenshots or videos in a | Before | After | table.
How to test Section
- Write short steps for a person who tests the product change by hand: the setup, the action in the n8n UI or API, and the expected result
- Add an example workflow only if the test needs one
- If the change needs a non-default module (
N8N_ENABLED_MODULES), an enterprise license, a feature flag, or similar, give the setting - If nothing changes for a user, write one short line that starts with "No visible changes", for example "No visible changes, only tests." or "No visible changes, only CI configuration."
- Give the command that runs the tests for the change, for example
pnpm agent:test --filter <package> -- <test-file>. If there are no tests, give the reason in one line. A bug fix needs a regression test. A feature needs tests
Related Links Section
- Link to Linear ticket:
https://linear.app/n8n/issue/[TICKET-ID] - Link to GitHub issues using keywords to auto-close:
closes #123/fixes #123/resolves #123
- Link to Community forum posts if applicable
- If the change has docs, link the n8n-docs PR or the docs follow-up ticket. Otherwise leave out the docs line
Backport labels
Backport bugs with urgent or high priority and regression fixes. Add the
labels that .github/backport_conventions.md gives.
Title Examples
Feature in editor
feat(editor): Add workflow performance metrics display
Bug fix in core
fix(core): Resolve memory leak in execution engine
Node-specific change
fix(Slack Node): Handle rate limiting in message send
Breaking change (add exclamation mark before colon)
feat(API)!: Remove deprecated v1 endpoints
No changelog entry
feat(core): Experimental feature not enabled yet (no-changelog)
No scope (affects multiple areas)
chore: Update dependencies to latest versions
Validation
The PR title must match this pattern:
^(feat|fix|perf|test|docs|refactor|build|ci|chore|revert)(\((API|core|editor|benchmark|ai-builder|engine|[A-Za-z0-9 .]+ Node)(, (API|core|editor|benchmark|ai-builder|engine|[A-Za-z0-9 .]+ Node))*\))?!?: [A-Z].+[^.]$
Check the title against this pattern and the Title Summary Rules before you
run gh pr create. The two most frequent failures are a package name as the
scope and a lowercase first letter in the summary.
Plan Section
If a matching plan file was found in a repository plan directory and the user has approved
including it, add a collapsible section at the end of the PR body (after the
Related Links section, before EOF):
<details>
<summary>Implementation plan</summary>
<!-- paste plan file contents here -->
</details>
Security Fixes
This repo is public. Never expose the attack vector in any public artifact. Describe what the code does, not what threat it prevents.
| Artifact | BAD | GOOD |
|---|---|---|
| Branch | fix-sql-injection-in-webhook | fix-webhook-input-validation |
| PR title | fix(core): Prevent SSRF | fix(core): Validate outgoing URLs |
| Commit msg | fix: prevent denial of service | fix: add payload size validation |
| PR body | "attacker could trigger SSRF…" | "validates URL protocol and host" |
| Linear ref | URL with slug (leaks title) | URL without slug or ticket ID only |
| Test name | 'should prevent SQL injection' | 'should sanitize query parameters' |
Before pushing a security fix, verify: no branch name, commit, PR title, PR body, Linear URL, test name, or code comment hints at the vulnerability.
When in doubt, check the Linear issue for possible extra precautions