Skip to content

ci: fix ERELEASEBRANCHES and allow RC version bump to dev#2188

Merged
alandtse merged 2 commits into
community-shaders:devfrom
alandtse:semantic-release2
Apr 22, 2026
Merged

ci: fix ERELEASEBRANCHES and allow RC version bump to dev#2188
alandtse merged 2 commits into
community-shaders:devfrom
alandtse:semantic-release2

Conversation

@alandtse
Copy link
Copy Markdown
Collaborator

@alandtse alandtse commented Apr 22, 2026

  • Add 'main' as non-prerelease anchor for RC mode (semantic-release v25 requires >= 1 non-prerelease branch; prerelease-only config throws ERELEASEBRANCHES with empty [])
  • Stable mode uses 'dev' directly as release branch
  • Strip prerelease suffix in CMakeLists replacement so CMake gets '1.5.0' not '1.5.0-rc.1' (CMake VERSION rejects prerelease syntax)
  • Add git identity config step so @semantic-release/git can commit version bump back to dev for both RC and stable releases

Prereq: 'main' branch must exist on remote (create from v1.4.11 tag).

Summary by CodeRabbit

  • Chores
    • Made release automation deterministic by configuring a consistent commit author for automated version updates.
    • Improved release/version handling so prerelease and stable flows produce correct version strings and branch selection for releases.

- Add 'main' as non-prerelease anchor for RC mode (semantic-release v25
  requires >= 1 non-prerelease branch; prerelease-only config throws
  ERELEASEBRANCHES with empty [])
- Stable mode uses 'dev' directly as release branch
- Strip prerelease suffix in CMakeLists replacement so CMake gets
  '1.5.0' not '1.5.0-rc.1' (CMake VERSION rejects prerelease syntax)
- Add git identity config step so @semantic-release/git can commit
  version bump back to dev for both RC and stable releases

Prereq: 'main' branch must exist on remote (create from v1.4.11 tag).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 22, 2026

📝 Walkthrough

Walkthrough

The PR updates CI/release configuration: it sets a deterministic Git author in the release workflow before running version-audit tooling, and changes release branching and CMake version replacement logic to strip prerelease suffixes and treat RC releases differently.

Changes

Cohort / File(s) Summary
GitHub Release Workflow
\.github/workflows/release.yaml
Sets local Git user.name and user.email to github-actions[bot] prior to running python tools/feature_version_audit.py --apply-bumps, ensuring deterministic author for version-bump commits.
Release Configuration
.releaserc.js
Adjusts branch selection when RELEASE_TYPE is rc (anchors main, marks dev as prerelease: 'rc') and changes CMake version replacement to use the base version (split on '-') instead of the full prerelease string; removes prior replacement verification logic.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • doodlum
  • jiayev

Poem

🐰 I nibble commits with tidy paws,

set author names and mend release laws.
RC lanes split, CMake trims the tail,
version hops steady down the trail.
A bunny's bump—neat, small, and hale. 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly addresses the main issues fixed in the changeset: configuring the release branches to fix ERELEASEBRANCHES and enabling RC version bumps to the dev branch.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

No actionable suggestions for changed features.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.releaserc.js (1)

19-27: ⚠️ Potential issue | 🟠 Major

Allow no-op CMake replacements after stripping RC suffix.

Line 20 strips the RC suffix, writing only the base version (e.g., 1.5.0 instead of 1.5.0-rc.1). When releasing a second RC for the same base version or the final stable release after an RC, the same VERSION x.y.z may already exist in CMakeLists.txt. In this case, replace-in-file reports hasChanged: false / numReplacements: 0 while the configured results require hasChanged: true / numReplacements: 1. The semantic-release-replace-plugin uses exact comparison (isEqual) on line 212 of its source, so this mismatch causes the release to fail despite finding a valid match.

🛠️ Proposed fix
             // Strip prerelease suffix so CMake gets '1.5.0' not '1.5.0-rc.1'
             to: "VERSION ${nextRelease.version.split('-')[0]}",
-            results: [
-              {
-                file: 'CMakeLists.txt',
-                hasChanged: true,
-                numReplacements: 1,
-                numMatches: 1,
-              },
-            ],
-            countMatches: true,

If match validation is still required, use a custom prepare step that accepts both "changed" and "already at base version" outcomes.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.releaserc.js around lines 19 - 27, The replace step that writes "to:
\"VERSION ${nextRelease.version.split('-')[0]}\"" can be a no-op when the
CMakeLists.txt already contains the base version; update the semantic-release
replace configuration to accept both outcomes by removing the strict results
assertion or making the results entry permissive (allow hasChanged: false /
numReplacements: 0) or implement a custom prepare step that treats "already at
base version" as success; target the replace rule that contains the "to:
\"VERSION ${nextRelease.version.split('-')[0]}\"" entry and adjust the
results/validation logic used by the semantic-release-replace-plugin (currently
enforcing isEqual at its validation) to not fail on zero replacements.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In @.releaserc.js:
- Around line 19-27: The replace step that writes "to: \"VERSION
${nextRelease.version.split('-')[0]}\"" can be a no-op when the CMakeLists.txt
already contains the base version; update the semantic-release replace
configuration to accept both outcomes by removing the strict results assertion
or making the results entry permissive (allow hasChanged: false /
numReplacements: 0) or implement a custom prepare step that treats "already at
base version" as success; target the replace rule that contains the "to:
\"VERSION ${nextRelease.version.split('-')[0]}\"" entry and adjust the
results/validation logic used by the semantic-release-replace-plugin (currently
enforcing isEqual at its validation) to not fail on zero replacements.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 90f73974-0615-416d-a123-359adaa3460f

📥 Commits

Reviewing files that changed from the base of the PR and between 9543ada and bf14a79.

📒 Files selected for processing (2)
  • .github/workflows/release.yaml
  • .releaserc.js

When stable runs after RC, CMakeLists already has the base version
(e.g. 1.5.0), making the replace a no-op. The strict results assertion
(hasChanged: true, numReplacements: 1) causes the plugin to throw on
mismatch. Drop it so stable-after-RC completes cleanly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.releaserc.js:
- Around line 18-21: Replace the string "from" in .releaserc.js with a callback
that reads the file contents (use fs.readFileSync) and first checks whether the
file already contains a stable VERSION pattern (e.g., /VERSION
\d+\.\d+\.\d+(?!-)/) to allow the no-op case; if that stable pattern is absent,
verify the prerelease/version pattern (/VERSION \d+\.\d+\.\d+/) exists and only
then return the regex (/VERSION [0-9]+\.[0-9]+\.[0-9]+/gm) to perform the
replacement, otherwise throw a clear error about the missing VERSION line so you
catch regex drift without breaking stable-after-RC no-ops.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a9b2324e-3274-4a03-bcc6-7baa03179595

📥 Commits

Reviewing files that changed from the base of the PR and between bf14a79 and fe47aad.

📒 Files selected for processing (1)
  • .releaserc.js

Comment thread .releaserc.js
Comment on lines 18 to +21
from: 'VERSION [0-9]+\\.[0-9]+\\.[0-9]+',
to: 'VERSION ${nextRelease.version}',
results: [
{
file: 'CMakeLists.txt',
hasChanged: true,
numReplacements: 1,
numMatches: 1,
},
],
countMatches: true,
// Strip prerelease suffix so CMake gets '1.5.0' not '1.5.0-rc.1'.
// No results assertion: stable after RC is a no-op (version already set).
to: "VERSION ${nextRelease.version.split('-')[0]}",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Inspect release plugin/action version references in repo config and lock files.
# Expected: Find the semantic-release action and any pinned replace-plugin versions, if present.

rg -n -C3 '(`@google/semantic-release-replace-plugin`|semantic-release-replace-plugin|cycjimmy/semantic-release-action)' \
  --iglob 'package*.json' \
  --iglob 'pnpm-lock.yaml' \
  --iglob 'yarn.lock' \
  --iglob '*.yaml' \
  --iglob '*.yml'

Repository: doodlum/skyrim-community-shaders

Length of output: 58


🏁 Script executed:

# Check if .releaserc.js exists and view its content
find . -name ".releaserc.js" -o -name ".releaserc" -o -name "releaserc*" | head -20

Repository: doodlum/skyrim-community-shaders

Length of output: 91


🏁 Script executed:

# Check package.json for semantic-release dependencies
fd -name 'package.json' -exec grep -l 'semantic-release\|release' {} \;

Repository: doodlum/skyrim-community-shaders

Length of output: 306


🏁 Script executed:

# Look at the repository structure
ls -la . | head -20

Repository: doodlum/skyrim-community-shaders

Length of output: 1300


🏁 Script executed:

# Read the .releaserc.js file
cat -n .releaserc.js

Repository: doodlum/skyrim-community-shaders

Length of output: 1386


🏁 Script executed:

# Check package.json for semantic-release dependencies
cat package.json

Repository: doodlum/skyrim-community-shaders

Length of output: 120


🏁 Script executed:

# Search for package.json anywhere in the repo
find . -name 'package.json' -type f

Repository: doodlum/skyrim-community-shaders

Length of output: 58


🏁 Script executed:

# Search for lock files
find . -name 'pnpm-lock.yaml' -o -name 'yarn.lock' -o -name 'package-lock.json' | head -5

Repository: doodlum/skyrim-community-shaders

Length of output: 58


🏁 Script executed:

# Check for any dependency specifications in other config files
grep -r 'google.*semantic-release-replace-plugin' . --include='*.json' --include='*.yaml' --include='*.yml' 2>/dev/null | head -10

Repository: doodlum/skyrim-community-shaders

Length of output: 170


🏁 Script executed:

# Read the release workflow to understand how the plugin is invoked
cat -n .github/workflows/release.yaml

Repository: doodlum/skyrim-community-shaders

Length of output: 1751


🌐 Web query:

@google/semantic-release-replace-plugin from callback support API documentation

💡 Result:

The @google/semantic-release-replace-plugin (also published as semantic-release-replace-plugin) supports callback functions for both the 'from' and 'to' options in its Replacement configuration interface. This is an advanced feature primarily for use with release.config.js (JavaScript config files), as JSON configs cannot express functions. Key details from the official API documentation: - from: Can be From or From[], where From is string | RegExp | FromCallback. FromCallback is defined as (filename: string, ...args: unknown[]) => RegExp | string. Consult replace-in-file docs for advanced matching with callbacks, RegExps, etc. - to: Can be To or To[], where To is string | ToCallback. ToCallback is (match: string, ...args: unknown[]) => string. Callback args vary: - For simple string 'from', 'to' callback simplest form receives the filename. - For RegExp 'from', args include captures, offset, matched string, etc. (per String.replace docs). Example for 'to' callback (from docs): { from: VERSION = 11, to: (matched) => VERSION: ${parseInt(matched.split('=')[1].trim) + 1}, } The plugin uses replace-in-file under the hood, adapting its API (single from/to vs. arrays). Templates like ${nextRelease.version} are rendered first using semantic-release context. Note: Requires release.config.js for callbacks; package.json configs are limited to strings. Pair with @semantic-release/git to commit changes. Official sources: GitHub repo at https://github.com/jpoehnelt/semantic-release-replace-plugin (docs/interfaces/Replacement.md and types). NPM pages confirm @google/ namespace is the same package.

Citations:


The callback proposal has a critical flaw: it breaks no-op behavior for stable releases.

The concern is valid—dropping results validation lets regex drift silently—and @google/semantic-release-replace-plugin does support callback-based from options. However, the proposed guard would throw an error when the CMake version pattern is absent, which occurs on stable releases after RC (when the pattern was already replaced). The comment explicitly states "stable after RC is a no-op (version already set)," but the callback would fail instead of allowing that no-op state.

To preserve no-op replacements while catching regex drift, consider this approach instead:

Alternative guard preserving no-op behavior

Rather than asserting the match exists upfront, validate that the pattern was either replaced OR already matched the desired state:

from: (filename) => {
  const contents = fs.readFileSync(filename, 'utf8');
  const alreadyMatches = /VERSION \d+\.\d+\.\d+(?!-)/m.test(contents);
  // Ensure pattern exists OR file already has desired version format (for no-op case)
  if (!alreadyMatches && !/VERSION \d+\.\d+\.\d+/.test(contents)) {
    throw new Error(`Missing CMake VERSION pattern in ${filename}`);
  }
  return /VERSION [0-9]+\.[0-9]+\.[0-9]+/gm;
},

This allows the regex to match (replacing any prerelease version) while still catching if the VERSION line is missing entirely.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.releaserc.js around lines 18 - 21, Replace the string "from" in
.releaserc.js with a callback that reads the file contents (use fs.readFileSync)
and first checks whether the file already contains a stable VERSION pattern
(e.g., /VERSION \d+\.\d+\.\d+(?!-)/) to allow the no-op case; if that stable
pattern is absent, verify the prerelease/version pattern (/VERSION
\d+\.\d+\.\d+/) exists and only then return the regex (/VERSION
[0-9]+\.[0-9]+\.[0-9]+/gm) to perform the replacement, otherwise throw a clear
error about the missing VERSION line so you catch regex drift without breaking
stable-after-RC no-ops.

@github-actions
Copy link
Copy Markdown

✅ A pre-release build is available for this PR:
Download

@alandtse alandtse merged commit d9c4b91 into community-shaders:dev Apr 22, 2026
15 checks passed
@alandtse alandtse deleted the semantic-release2 branch April 22, 2026 23:04
ParticleTroned pushed a commit to ParticleTroned/skyrim-community-shaders that referenced this pull request May 2, 2026
…shaders#2188)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
(cherry picked from commit d9c4b91)
IgorAlanAlbuquerque pushed a commit to IgorAlanAlbuquerque/skyrim-community-shaders that referenced this pull request May 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants