Skip to content

Scoped commits never trigger a release (releaseRules scope negations) #207

Open

Description

@fefi95

Priority: P1

Context

Raised in the approving review of #202. This bug predates #202.

Each package's .releaserc.json has two negated-scope rules. Here is packages/core/.releaserc.json:

"releaseRules": [
  { "scope": "!all", "release": false },
  { "scope": "!core", "release": false }
]

The intent is "release this package only for commits scoped to core or all". In practice every scoped commit matches at least one of the two rules, so it maps to release: false:

  • feat(core) matches !all, so no release.
  • feat(all) matches !core, so no release.
  • feat(dom) matches both, so no release.

Only unscoped feat: / fix: (and breaking changes) reach the default rules and trigger a release. @fefi95 confirmed this on #202 by running analyzeCommits from commit-analyzer 12.0.0 and 13.0.1 with the core rules:

Commit Result (12 and 13)
feat(core), fix(core), feat(dom), feat(all), chore(all) no release
feat: minor
fix: patch
feat(core)!: + BREAKING CHANGE major

Impact: @assertive-ts/dom and @assertive-ts/native have never been published to npm (npm view returns 404), even though toHaveAccessibleDescription (#174), toContainHTML (#173), toBePressed (#172), toContainElement (#146) and others have merged. @assertive-ts/core is stuck at 2.1.0 and @assertive-ts/sinon at 1.0.0.

The same rules appear in all four files: packages/{core,dom,native,sinon}/.releaserc.json.

Tasks

  1. Reproduce first. Write a throwaway script (don't commit it) that calls analyzeCommits from the @semantic-release/commit-analyzer version in yarn.lock with each package's releaseRules. Feed it these commit messages: feat(<pkg>), fix(<pkg>), feat(all), fix(all), feat(<other-pkg>), chore(<pkg>), unscoped feat: / fix:, and feat(<pkg>)!: with a BREAKING CHANGE footer. Confirm it shows the bug from the table above.
  2. Fix the rules in all four .releaserc.json files. Replace the two rules with one that suppresses only commits whose scope is neither the package nor all. For example, in core:
    { "scope": "!(core|all)", "release": false }
    commit-analyzer matches scopes with micromatch, so check that the extglob works with the installed version. If it doesn't, find another rule set that gives the target behavior below. Don't change any other plugin config.
  3. Re-run the script and include the before/after table for every package in the PR. Target behavior for package X:
    Commit Expected
    feat(X), feat(all) minor
    fix(X), fix(all) patch
    feat(X)!: / BREAKING CHANGE major
    feat(other), fix(other) no release
    chore(X), chore(all) no release
    unscoped feat: / fix: unchanged from today (minor / patch). Call this out in the PR, see "Open question" below.
  4. Preview the backlog the fix unlocks. Run the same analyzer over the real commits since each package's last tag (core/v2.1.0, sinon/v1.0.0; dom and native have no tag, so use the full history). Then put in the PR the release type and the version each package would get on the next Release run. Expect the first-ever publish of @assertive-ts/dom and @assertive-ts/native. Flag any commit in the backlog that looks breaking but isn't marked as breaking, for example feat(all): Upgrade Node.js and drop EoLs support (#161).
  5. Run yarn build, yarn lint and yarn test. Nothing should change, but run them anyway.

Constraints

  • Do not run yarn release or semantic-release without --dry-run, and do not trigger the Release workflow. Publishing is a maintainer action after merge.
  • Only touch the four .releaserc.json files. Don't change dependencies, the workflow or the commit conventions in this PR.
  • Use the commit message fix(all): .... Under the current (broken) rules this won't release anything by itself, which is what we want.

Open question (maintainer decides; agent should not)

Today an unscoped feat: / fix: releases every package. Keep it that way, or require a scope? Leave the current behavior in place and raise the question in the PR description.

Done when

  • All four .releaserc.json files produce the target table above, and the PR shows the evidence.
  • The PR lists what the next Release run would publish (package → version).
  • After merge, a maintainer runs the Release workflow and confirms @assertive-ts/dom and @assertive-ts/native appear on npm. This step is [human].

Source: review of #202 by @rojasTob; analyzer comparison by @fefi95.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions