Skip to content

fix(is-ignored): strip CI skip markers from release commits#4637

Merged
escapedcat merged 2 commits intoconventional-changelog:masterfrom
Br1an67:fix/issue-4594-fix-4594
Mar 12, 2026
Merged

fix(is-ignored): strip CI skip markers from release commits#4637
escapedcat merged 2 commits intoconventional-changelog:masterfrom
Br1an67:fix/issue-4594-fix-4594

Conversation

@Br1an67
Copy link
Copy Markdown
Contributor

@Br1an67 Br1an67 commented Mar 7, 2026

Fixes #4594

Description

This PR fixes the issue where semantic-release commits containing CI skip markers were not being properly ignored by commitlint. The isSemver function in @commitlint/is-ignored now strips common CI skip markers before validating the version string.

Motivation and Context

Automated release tools like semantic-release often include CI skip markers (e.g., [skip ci], [ci skip]) in commit messages to prevent triggering duplicate CI pipelines. However, these markers were causing the semver validation to fail, resulting in false positives when linting legitimate automated release commits.

Example commit that was incorrectly flagged:

chore(release): 2.3.3-beta.1 [skip ci]

Usage examples

# These commits are now correctly ignored:
echo "chore(release): 2.3.3-beta.1 [skip ci]" | commitlint  # passes
echo "chore(release): 1.0.0 [ci skip]" | commitlint            # passes
echo "2.3.3 [skip-ci]" | commitlint                           # passes

How Has This Been Tested?

  • Added 2 new test cases covering CI skip markers in various formats:
    • Test for version messages with CI skip markers (bracket and parenthesis variants)
    • Test for chore-prefixed version messages with CI skip markers
  • All 31 tests in @commitlint/is-ignored pass

Types of changes

  • Bug fix (non-breaking change which fixes an issue)

Checklist:

  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

Semantic-release commits with CI skip markers like [skip ci], [ci skip],
[skip-ci], [ci-skip] should be ignored to prevent
false positives when linting automated release commits.
@qodo-code-review
Copy link
Copy Markdown

Review Summary by Qodo

Strip CI skip markers from semantic-release commits

🐞 Bug fix

Grey Divider

Walkthroughs

Description
• Strip CI skip markers from release commits before semver validation
• Support bracket and parenthesis variants of CI skip markers
• Add comprehensive test coverage for CI skip marker scenarios
Diagram
flowchart LR
  A["Commit message with CI skip marker"] -->|Remove chore prefix| B["Extract version string"]
  B -->|Strip bracket markers| C["Remove [skip ci] variants"]
  C -->|Strip parenthesis markers| D["Remove (skip ci) variants"]
  D -->|Validate semver| E["Pass validation"]
Loading

Grey Divider

File Changes

1. @commitlint/is-ignored/src/defaults.ts 🐞 Bug fix +5/-1

Strip CI skip markers from version validation

• Enhanced isSemver function to strip CI skip markers before validation
• Added regex patterns to remove bracket-style markers like [skip ci], [ci skip], [skip-ci],
 [ci-skip]
• Added regex patterns to remove parenthesis-style markers like (skip ci), (ci skip),
 (skip-ci), (ci-skip)
• Maintains existing chore prefix removal logic while adding marker stripping

@commitlint/is-ignored/src/defaults.ts


2. @commitlint/is-ignored/src/is-ignored.test.ts 🧪 Tests +18/-0

Add CI skip marker test coverage

• Added test case for semver commits with bracket-style CI skip markers
• Added test case for semver commits with parenthesis-style CI skip markers
• Added test case for chore-prefixed commits with CI skip markers
• Tests cover all common CI skip marker variants (space and hyphen separated)

@commitlint/is-ignored/src/is-ignored.test.ts


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review Bot commented Mar 7, 2026

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Remediation recommended

1. Unanchored marker stripping 🐞 Bug ✓ Correctness
Description
CI skip markers are stripped anywhere in the first line (not just as a trailing suffix), which can
turn some malformed release headers into a valid semver string and cause commitlint to skip linting
entirely. This widens the ignore condition beyond the PR’s stated goal of handling suffix markers on
release commits.
Code

@commitlint/is-ignored/src/defaults.ts[R11-15]

+	const stripped = firstLine
+		.replace(/^chore(\([^)]+\))?:/, "")
+		.replace(/\[(skip|ci)(-|\s)(ci|skip)\]/i, "")
+		.replace(/\((skip|ci)(-|\s)(ci|skip)\)/i, "")
+		.trim();
Evidence
isSemver removes CI markers via unanchored regex replacements, so a header like `chore: [skip ci]
1.2.3 becomes 1.2.3 after replacements and trim(), making semver.valid(...)` succeed. Since
lint() returns early with valid: true on any isIgnored(...) match, such a message would bypass
all rules.

@commitlint/is-ignored/src/defaults.ts[4-17]
@commitlint/is-ignored/src/is-ignored.ts[26-28]
@commitlint/lint/src/lint.ts[28-38]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`isSemver` currently strips `[skip ci]` / `(skip ci)` markers anywhere in the first line. Because `isIgnored()` causes `lint()` to skip all validation when `isSemver` returns true, this can ignore some malformed/oddly-formatted headers that become semver after stripping.

### Issue Context
The intent is to support semantic-release-style commit headers where CI skip markers are appended at the end (suffix), e.g. `chore(release): 2.3.3 [skip ci]`.

### Fix Focus Areas
- @commitlint/is-ignored/src/defaults.ts[11-16]

### Suggested approach
- After removing the optional `chore(...)?:` prefix, remove **one or more** trailing CI markers only.
- Consider a single regex that matches both bracket and paren forms and is anchored to end-of-line, e.g. remove `((\s*[\[(](?:skip|ci)(?:-|\s)(?:ci|skip)[\])])\s*)+$` (case-insensitive), then `trim()`.
- Add tests that ensure markers *before* the version are not treated as semver ignore cases (if that’s the desired policy).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Advisory comments

2. Non-global marker replace 🐞 Bug ✓ Correctness
Description
The CI skip marker replacements are not global, so only the first occurrence of a marker is removed.
A semver commit containing repeated markers (e.g. 1.2.3 [skip ci] [skip ci]) may still fail semver
validation and not be ignored.
Code

@commitlint/is-ignored/src/defaults.ts[R12-15]

+		.replace(/^chore(\([^)]+\))?:/, "")
+		.replace(/\[(skip|ci)(-|\s)(ci|skip)\]/i, "")
+		.replace(/\((skip|ci)(-|\s)(ci|skip)\)/i, "")
+		.trim();
Evidence
Both regexes are missing the /g flag, so .replace(...) only removes the first match. The new
tests validate only single-marker cases, so this behavior is currently untested.

@commitlint/is-ignored/src/defaults.ts[11-15]
@commitlint/is-ignored/src/is-ignored.test.ts[127-143]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
CI skip marker `.replace()` calls are non-global, so repeated markers won’t be fully removed.

### Issue Context
While uncommon, repeated markers can happen via tooling or manual edits; failing to strip them defeats the purpose of normalizing the release commit header before semver validation.

### Fix Focus Areas
- @commitlint/is-ignored/src/defaults.ts[11-15]
- @commitlint/is-ignored/src/is-ignored.test.ts[127-143]

### Suggested approach
- Prefer the single-regex trailing-strip approach (anchored to `$`) that naturally handles repetition.
- If keeping the current approach, add `/g` to the regexes and add a test such as `expect(isIgnored("1.2.3 [skip ci] [skip ci]")).toBe(true)`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@codesandbox-ci
Copy link
Copy Markdown

codesandbox-ci Bot commented Mar 7, 2026

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

@escapedcat
Copy link
Copy Markdown
Member

Any idea why the checks are not running? I wonder if this is related to "ci skip" in the title

@knocte
Copy link
Copy Markdown
Contributor

knocte commented Mar 9, 2026

Maybe. That commit title is too long anyway, @Br1an67 you could rename it just to "fix(is-ignored): add semver markers for skipping ci"

@escapedcat escapedcat merged commit 56a6fd0 into conventional-changelog:master Mar 12, 2026
11 of 12 checks passed
This was referenced Mar 12, 2026
This was referenced Apr 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

fix: found error with line length in a release commit (inc skip ci)

3 participants