Skip to content

feat(stages): add alpha/beta pre-release markers to features#2511

Open
SkrubbySkrubInAShrub wants to merge 3 commits into
community-shaders:devfrom
SkrubbySkrubInAShrub:alpha-beta-features
Open

feat(stages): add alpha/beta pre-release markers to features#2511
SkrubbySkrubInAShrub wants to merge 3 commits into
community-shaders:devfrom
SkrubbySkrubInAShrub:alpha-beta-features

Conversation

@SkrubbySkrubInAShrub

@SkrubbySkrubInAShrub SkrubbySkrubInAShrub commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator

Summary

Introduces a release-maturity stage system for features. A feature can now declare itself Alpha or Beta in its .ini [Info] section; the stage is baked into FeatureVersions.h at build time alongside the existing core-feature list, and is used at runtime to auto-disable pre-release features, show colored [ALPHA]/[BETA] tags in the feature list and header, and drive stage-aware versioning in the version-audit tool.

UnifiedWater is the first feature to use this: it is marked Beta = True and versioned 0-2-0 accordingly.

Changes

Build (CMakeLists.txt / cmake/FeatureVersions.h.in)

  • Scans each feature .ini for Alpha/Beta flags (line-anchored regex to avoid false positives from settings keys like WaterAlpha = 1 or Nexus metadata keys like nexusbeta = on). Truthy values are true, 1, yes, on (case-insensitive); Alpha takes precedence over Beta.
  • Populates FEATURE_ALPHA_NAMES and FEATURE_BETA_NAMES lists and substitutes them into the new std::unordered_set<std::string_view> constants in FeatureVersions.h, following the same pattern as FEATURE_CORE_NAMES.

Runtime C++ API (src/Feature.h / src/Feature.cpp)

  • ReleaseStage enum (Release, Beta, Alpha) added to Feature.
  • GetReleaseStage() looks the short name up in the baked sets. Virtual so features can override if needed.
  • IsAlpha() / IsBeta() convenience predicates.
  • static GetReleaseStageTag(ReleaseStage) returns the localized [ALPHA] / [BETA] string (empty for Release). Static and takes the already-resolved stage so callers avoid a redundant hash-set lookup.
  • IsDisabledByDefault() now returns true for any non-Release stage; the UnifiedWater override that manually returned true is removed.

UI (src/Menu/FeatureListRenderer.cpp)

  • StageTagColor() helper maps stages to StatusPalette.Error (Alpha) and StatusPalette.Warning (Beta).
  • The feature list shows the tag via ImGui::SameLine after the selectable name; the feature header draws it bottom-aligned to the right of the feature title, before the version string.
  • Both sites resolve GetReleaseStage() once and pass the result through, so no redundant lookup occurs.

Translations (package/SKSE/Plugins/CommunityShaders/Translations/en.json)

  • menu.features.tag_alpha: "[ALPHA]"
  • menu.features.tag_beta: "[BETA]"

UnifiedWater (features/Unified Water / src/Features/UnifiedWater.h)

  • Version 1-0-20-2-0 (entering Beta baseline per the versioning convention).
  • Beta = True flag added to the ini.
  • Redundant IsDisabledByDefault() override { return true; } removed.

Version audit tool (tools/feature_version_audit.py)

  • Parses Alpha/Beta flags from ini content (stage_from_content, get_stage_from_ini, get_prior_stage).
  • propose_new_version is now stage-aware:
    • Entering Alpha from release/fresh: proposes 0-1-0; entering Beta: 0-2-0.
    • alpha → beta transition: minor bump, patch reset.
    • Breaking commit on a pre-release feature promotes to 1-0-0 and sets needs_flag_removal.
    • Within the same stage, normal semver applies inside 0.x.
  • Stage transitions use exact-match enforcement (a legitimate version decrease like 1.x → 0-2-0 would never satisfy the existing > check).
  • remove_stage_flag() strips the flag line from the ini; --apply-bumps calls it automatically on breaking-change promotion.
  • Actionable-state and stale-action cleanup extended to cover needs_flag_removal.

Summary by CodeRabbit

  • New Features
    • Added a release-stage system for features (Release / Alpha / Beta) with localized menu tag strings
    • Stage indicators (e.g., [ALPHA], [BETA]) now render in the Features UI with theme-colored styling
    • Alpha/Beta features start disabled by default; Release remains enabled
    • Unified Water is now marked as a core Beta feature (including updated version metadata)
  • Documentation
    • Documented release-stage declaration, parsing, and stage-transition rules
  • Chores / Tools
    • Made feature version auditing and bumping stage-aware, including automatic promotion to Release and stage-flag removal

@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: cdac3989-6eae-4f3e-b93f-cb4f6251c57c

📥 Commits

Reviewing files that changed from the base of the PR and between 27932e6 and f1db925.

📒 Files selected for processing (1)
  • src/Menu/FeatureListRenderer.cpp
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/Menu/FeatureListRenderer.cpp

📝 Walkthrough

Walkthrough

Introduces an end-to-end Alpha/Beta release-stage system: CMake parses feature INI files for Alpha/Beta flags and bakes named sets into a generated FeatureVersions.h. The Feature C++ API gains a ReleaseStage enum with helpers that default Alpha/Beta features to disabled. The UI renders colored [ALPHA]/[BETA] markers. The version audit tool enforces stage-transition and breaking-change promotion rules.

Changes

Alpha/Beta Release Stage System

Layer / File(s) Summary
CMake stage detection and header generation
CMakeLists.txt, cmake/FeatureVersions.h.in
CMake regex-parses each feature INI for truthy Alpha/Beta flags, accumulates them into FEATURE_ALPHA_NAMES/FEATURE_BETA_NAMES lists, serializes to comma/newline format, and the header template exposes them as std::unordered_set<std::string_view> constants.
Feature runtime API: ReleaseStage enum, helpers, and default-disable
src/Feature.h, src/Feature.cpp, src/Features/UnifiedWater.h, features/Unified Water/Shaders/Features/UnifiedWater.ini, package/.../Translations/en.json
Feature gains ReleaseStage enum, GetReleaseStage() that queries baked feature sets, IsAlpha()/IsBeta() helpers, and GetReleaseStageTag() for localized markers. IsDisabledByDefault() now returns true for non-Release stages. UnifiedWater gains IsCore() override and drops manual IsDisabledByDefault(), its INI is set to Beta = True at version 0-2-0, and [ALPHA]/[BETA] translation keys are added.
UI stage marker rendering
src/Menu/FeatureListRenderer.cpp
Adds StageTagColor helper that maps stages to theme colors (Alpha→Error, Beta→Warning). Extends DrawFeatureHeader to accept optional stage tag and color, rendering the marker bottom-aligned right of the title with shifted version placement. Left-panel rows and right-panel headers compute and wire stage tag/color into the renderer.
Stage-aware version audit tool and documentation
tools/feature_version_audit.py, .claude/CLAUDE.md
Adds stage regex constants, stage-resolution helpers (stage_from_content, get_stage_from_ini, get_prior_stage, remove_stage_flag), extends propose_new_version with stage parameters for auto-promotion to 1-0-0 on breaking changes or release transition, updates analyze_features with needs_flag_removal and strict equality enforcement for stage transitions, auto-strips INI flags in --apply-bumps mode, and documents all conventions.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • alandtse

Poem

🐇 A bunny hopped in, .ini in paw,
Stamped Beta = True with a proud little claw.
The CMake list sniffed it, the header agreed,
[BETA] glows amber — in warning indeed!
No more secret alphas, all stages laid bare,
This rabbit loves semver done with proper care! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely describes the main change: introducing alpha/beta pre-release stage markers for features.
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

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 OpenGrep (1.22.0)

OpenGrep fatal error (exit code 2): [00.11][ERROR]: Error: exception Unix_error: No such file or directory stat src/Menu/FeatureListRenderer.cpp
Raised by primitive operation at UTmp.replace_named_pipe_by_regular_file_if_needed in file "libs/commons/UTmp.ml", line 145, characters 8-27
Called from Scan_CLI.replace_target_roots_by_regular_files_where_needed.(fun) in file "src/osemgrep/cli_scan/Scan_CLI.ml", lines 1086-1087, characters 19-65
Called from List_.fast_map in file "libs/commons/List_.ml", line 81, characters 17-20
Called


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

Actionable Suggestions

  • Unified Water (Skrubby Skrub In A Shrub): Needs version bump to 1-1-0

@SkrubbySkrubInAShrub

Copy link
Copy Markdown
Collaborator Author

CI will complain about UW version due to it being bumped down to 0.2.0

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🧹 Nitpick comments (3)
CMakeLists.txt (1)

236-259: Add a conventional-commit title and issue reference in PR metadata

Suggested title: feat(features): add alpha/beta release stages
Suggested issue linkage (if applicable): Implements #<id> / Addresses #<id>.

As per coding guidelines, "When reviewing PRs, please provide suggestions for: Conventional Commit Titles ... [and] Issue References."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CMakeLists.txt` around lines 236 - 259, The PR metadata needs to be updated
to follow conventional commit guidelines. Update the pull request title to
follow the conventional commit format as `feat(features): add alpha/beta release
stages` and add an issue reference (either `Implements #<id>` or `Addresses
#<id>` depending on the issue being resolved) in the PR description to establish
traceability. These changes should be made in the PR title and description
fields on the pull request, not in the code itself.

Source: Coding guidelines

.claude/CLAUDE.md (1)

337-371: Suggested PR metadata update (title + issue linkage).

Suggested Conventional Commit title:

  • feat(audit): add stage-aware version promotions

Suggested issue reference line in PR description (as applicable):

  • Implements #<issue-number> (or Addresses #<issue-number>)

As per coding guidelines, "When reviewing PRs, please provide suggestions for Conventional Commit Titles ... [and] Issue References".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/CLAUDE.md around lines 337 - 371, Update the PR title to follow the
Conventional Commit format by changing it to "feat(audit): add stage-aware
version promotions" or a similarly structured title that clearly describes the
feature being added. Then update the PR description to include an issue
reference line such as "Implements #<issue-number>" or "Addresses
#<issue-number>" as applicable to link this change to the relevant GitHub issue,
per the coding guidelines for PR metadata.

Source: Coding guidelines

src/Menu/FeatureListRenderer.cpp (1)

58-64: ⚡ Quick win

Use a switch statement for explicit enum case handling.

The ternary operator only checks for Alpha explicitly, treating all other cases (including Release) as Beta/Warning. While this works today because the function is primarily called for Beta and Alpha features, it's semantically incorrect to return Warning for Release and fragile if the enum is extended. A switch statement would make all cases explicit and enable compile-time exhaustiveness checking.

♻️ Suggested refactor with explicit enum handling
 ImVec4 StageTagColor(Feature::ReleaseStage stage)
 {
 	const auto& statusPalette = globals::menu->GetTheme().StatusPalette;
-	return stage == Feature::ReleaseStage::Alpha ? statusPalette.Error : statusPalette.Warning;
+	switch (stage) {
+	case Feature::ReleaseStage::Alpha:
+		return statusPalette.Error;
+	case Feature::ReleaseStage::Beta:
+		return statusPalette.Warning;
+	case Feature::ReleaseStage::Release:
+		// Release features do not render a stage marker, so this color is unused.
+		// Return a default to avoid undefined behavior if called incorrectly.
+		return ImVec4{};
+	}
+	// Unreachable if enum is exhaustive
+	return ImVec4{};
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/Menu/FeatureListRenderer.cpp` around lines 58 - 64, The StageTagColor
function currently uses a ternary operator that only explicitly checks for
Feature::ReleaseStage::Alpha and implicitly treats all other cases (including
Release) as Warning, which is semantically incorrect and fragile. Replace the
ternary operator with a switch statement that explicitly handles all enum cases
(Alpha, Beta, Release, and any others) with their corresponding status palette
colors. This will make the enum handling explicit and enable compile-time
exhaustiveness checking.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tools/feature_version_audit.py`:
- Around line 1348-1352: The statement setting fa['needs_flag_removal'] = False
is executing unconditionally after the remove_stage_flag() call, even when the
function returns False (fails). Move the line `fa['needs_flag_removal'] = False`
inside the `if remove_stage_flag(fa['ini_path']):` block so that the flag is
only cleared when the flag removal actually succeeds. Apply the same fix at line
1374 where this pattern is also present.

---

Nitpick comments:
In @.claude/CLAUDE.md:
- Around line 337-371: Update the PR title to follow the Conventional Commit
format by changing it to "feat(audit): add stage-aware version promotions" or a
similarly structured title that clearly describes the feature being added. Then
update the PR description to include an issue reference line such as "Implements
#<issue-number>" or "Addresses #<issue-number>" as applicable to link this
change to the relevant GitHub issue, per the coding guidelines for PR metadata.

In `@CMakeLists.txt`:
- Around line 236-259: The PR metadata needs to be updated to follow
conventional commit guidelines. Update the pull request title to follow the
conventional commit format as `feat(features): add alpha/beta release stages`
and add an issue reference (either `Implements #<id>` or `Addresses #<id>`
depending on the issue being resolved) in the PR description to establish
traceability. These changes should be made in the PR title and description
fields on the pull request, not in the code itself.

In `@src/Menu/FeatureListRenderer.cpp`:
- Around line 58-64: The StageTagColor function currently uses a ternary
operator that only explicitly checks for Feature::ReleaseStage::Alpha and
implicitly treats all other cases (including Release) as Warning, which is
semantically incorrect and fragile. Replace the ternary operator with a switch
statement that explicitly handles all enum cases (Alpha, Beta, Release, and any
others) with their corresponding status palette colors. This will make the enum
handling explicit and enable compile-time exhaustiveness checking.
🪄 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 Plus

Run ID: c1e14fdb-fde4-4241-8383-0241f2f9cc5e

📥 Commits

Reviewing files that changed from the base of the PR and between 45fbb03 and bc6b91e.

📒 Files selected for processing (10)
  • .claude/CLAUDE.md
  • CMakeLists.txt
  • cmake/FeatureVersions.h.in
  • features/Unified Water/Shaders/Features/UnifiedWater.ini
  • package/SKSE/Plugins/CommunityShaders/Translations/en.json
  • src/Feature.cpp
  • src/Feature.h
  • src/Features/UnifiedWater.h
  • src/Menu/FeatureListRenderer.cpp
  • tools/feature_version_audit.py
💤 Files with no reviewable changes (1)
  • src/Features/UnifiedWater.h

Comment thread tools/feature_version_audit.py
@github-actions

github-actions Bot commented Jun 14, 2026

Copy link
Copy Markdown

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

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.

1 participant