Skip to content

ci(nexus): fix GITHUB_OUTPUT delimiter and auto-generate changelogs#2254

Merged
alandtse merged 2 commits into
community-shaders:devfrom
alandtse:fix/ci-build-issues
May 1, 2026
Merged

ci(nexus): fix GITHUB_OUTPUT delimiter and auto-generate changelogs#2254
alandtse merged 2 commits into
community-shaders:devfrom
alandtse:fix/ci-build-issues

Conversation

@alandtse
Copy link
Copy Markdown
Collaborator

@alandtse alandtse commented May 1, 2026

Summary

  • Fix: json.dump() produces no trailing newline, causing the GITHUB_OUTPUT multiline delimiter to land on the same line as the last JSON character instead of its own line. GitHub Actions requires the delimiter at column 0. Fixed by using printf '\n%s\n' for both closing delimiters.
  • Feature: Auto-generate per-feature and core changelogs for Nexus uploads:
    • feature_version_audit.py now adds a changelog field to each feature row in the upload matrix, built from feat/fix/perf/breaking commits touching that feature's files since the previous stable tag
    • Core row's changelog is the GitHub release body (fetched via gh api list endpoint, JSON-encoded for safe multiline handling) injected into the matrix before the split step
    • upload-to-nexus job uses matrix.changelog || inputs.changelog || '' so manual workflow_dispatch with an explicit changelog still works as override

Test plan

  • Delimiter fix: run the Nexus upload workflow on a published stable release and confirm prepare-nexus-matrix succeeds (matrix output parses correctly)
  • Core changelog: confirm the Nexus upload for the core mod includes the GitHub release notes
  • Feature changelogs: confirm feature uploads (e.g. ScreenSpaceGI, Skylighting) include relevant commit bullet points
  • Manual dispatch with changelog input: confirm the explicit value is used when matrix.changelog is absent

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Automated changelog generation now included in release uploads, extracting commit-derived information for both core and feature components.

alandtse and others added 2 commits May 1, 2026 14:48
json.dump() produces no trailing newline, so the closing delimiter
was appended to the last JSON character instead of being on a line
by itself. GitHub Actions requires the delimiter to start at column 0.

Fix: use printf '\n%s\n' so there is always a newline before the
closing delimiter regardless of whether the JSON ends with one.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add get_feature_changelog() to feature_version_audit.py: collects
  feat/fix/perf/breaking commits for each feature dir + src/Features/
  since the previous stable release tag, formatted as bullet points
- build_nexus_upload_matrix() now accepts base_ref and populates a
  'changelog' field on each feature row; core row is left empty as a
  placeholder (filled by the workflow from the GitHub release body)
- upload-nexus.yaml: after running the audit script, fetch the GitHub
  release body via gh api (list endpoint, jq-JSON-encoded for safety)
  and inject it into the core matrix row before the matrix is split
- upload-to-nexus job uses matrix.changelog with fallback to
  inputs.changelog (manual workflow_dispatch override) then ''

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

coderabbitai Bot commented May 1, 2026

📝 Walkthrough

Walkthrough

The changes enhance the Nexus matrix export workflow by adding commit-derived changelog generation. The GitHub workflow now fetches release body information using the GitHub API and injects it into the matrix configuration, while a Python tool extracts relevant commits from feature directories to generate user-facing changelogs during matrix building.

Changes

Cohort / File(s) Summary
Workflow Release Changelog Integration
.github/workflows/upload-nexus.yaml
Fetches GitHub release body via gh api for RELEASE_TAG, stores in core-body.json, and injects into the matrix JSON by setting the changelog field for the core row. Updates downstream workflow call to prioritize matrix.changelog over inputs.changelog. Adds GH_TOKEN to job environment and adjusts heredoc delimiter formatting for GITHUB_OUTPUT.
Feature Changelog Generation
tools/feature_version_audit.py
Introduces get_feature_changelog() helper that extracts and filters commit messages from feature directories between base_ref and HEAD_REF, formatting them as changelog bullets. Updates build_nexus_upload_matrix() signature to accept optional base_ref parameter and conditionally populates changelog fields in the matrix output for core and each feature.

Sequence Diagram

sequenceDiagram
    participant Workflow as Upload Workflow
    participant GH as GitHub API
    participant Python as Feature Version Audit
    participant Git as Git Repository
    participant Matrix as Nexus Matrix JSON

    Workflow->>GH: Fetch release body for RELEASE_TAG (with GH_TOKEN)
    GH-->>Workflow: Release body/changelog
    Workflow->>Matrix: Inject changelog into core row
    
    Workflow->>Python: Call build_nexus_upload_matrix(base_ref)
    Python->>Git: git log for each feature dir (base_ref..HEAD)
    Git-->>Python: Commit messages
    Python->>Python: Filter feat/fix/perf/breaking-change commits
    Python->>Python: Deduplicate and format as bullets
    Python-->>Matrix: Populate changelog field per feature
    
    Workflow->>Workflow: Pass matrix (with changelog) to downstream
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Suggested reviewers

  • doodlum
  • SkrubbySkrubInAShrub

Poem

🐰 Hop, hop! The changelogs now take flight,
From git commits extracted just right,
With releases fetched from GitHub's keep,
The matrix builds changelogs deep,
Feature by feature, shiny and bright!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR objectives describe CI/Nexus changelog generation, but linked issue #39 requests reverting a prior pull request with no connection to the code changes. Verify that issue #39 is correctly linked to this PR, or remove it if this PR is not meant to address it. The changelog generation work does not relate to reverting prior changes.
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately summarizes the two main changes: fixing GITHUB_OUTPUT delimiter placement and auto-generating changelogs for Nexus uploads.
Out of Scope Changes check ✅ Passed All changes are scoped to fixing GITHUB_OUTPUT delimiters and auto-generating changelogs in CI workflows, which aligns with PR objectives. No extraneous changes detected.

✏️ 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.

🔧 actionlint (1.7.12)
.github/workflows/upload-nexus.yaml

could not read ".github/workflows/upload-nexus.yaml": open .github/workflows/upload-nexus.yaml: no such file or directory

🔧 YAMLlint (1.38.0)
.github/workflows/upload-nexus.yaml

[Errno 2] No such file or directory: '.github/workflows/upload-nexus.yaml'

🔧 Checkov (3.2.525)
.github/workflows/upload-nexus.yaml

2026-05-01 21:48:52,570 [MainThread ] [ERROR] Template file not found: .github/workflows/upload-nexus.yaml
2026-05-01 21:48:52,547 [MainThread ] [ERROR] Template file not found: .github/workflows/upload-nexus.yaml
2026-05-01 21:48:52,613 [MainThread ] [ERROR] Template file not found: .github/workflows/upload-nexus.yaml
2026-05-01 21:48:52,658 [MainThread ] [WARNI] Secret scanning: could not process file .github/workflows/upload-nexus.yaml
2026-05-01 21:48:52,634 [MainThread ] [ERROR] Failed to invoke function /usr/local/lib/python3.11/dist-packages/checkov/common/runners/object_runner. with .github/workflows/upload-nexus.yaml
Traceback (most recent call last):
File "/usr/local/lib/python3.11/dist-packages/checkov/common/parallelizer/parallel_runner.py", line 88, in func_wrapper
result = original_func(item)
^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/checkov/common/runners/object_runner.py", line 74, in
results =

... [truncated 9182 characters] ...

  ^^^^^^^^^^^^^^^^^^^^

File "/usr/local/lib/python3.11/dist-packages/checkov/common/runners/runner_registry.py", line 839, in _parallel_run
report = runner.run(
^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/checkov/common/runners/object_runner.py", line 131, in run
self._load_files(files)
File "/usr/local/lib/python3.11/dist-packages/checkov/common/runners/object_runner.py", line 75, in _load_files
for file_result_pair in results:
File "/usr/local/lib/python3.11/dist-packages/checkov/common/parallelizer/parallel_runner.py", line 118, in _run_function_multiprocess_fork
raise v.internal_exception.with_traceback(v.internal_exception.traceback)
FileNotFoundError: [Errno 2] No such file or directory: '.github/workflows/upload-nexus.yaml'


Review rate limit: 9/10 reviews remaining, refill in 6 minutes.

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

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 1, 2026

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.

Actionable comments posted: 4

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

Inline comments:
In @.github/workflows/upload-nexus.yaml:
- Around line 151-153: Replace the paginated releases list call with the
releases-by-tag endpoint so the body is fetched server-side for the specific
tag: change the gh api invocation that currently calls
"repos/$GITHUB_REPOSITORY/releases" and uses --jq 'select(.tag_name ==
"$RELEASE_TAG") | .body' to call the tag endpoint for the given $RELEASE_TAG
(i.e., "repos/$GITHUB_REPOSITORY/releases/tags/$RELEASE_TAG") and write its
.body to core-body.json, preserving the existing error handling/redirect
behavior so older releases are not lost.
- Line 280: The changelog precedence currently uses "changelog: ${{
matrix.changelog || inputs.changelog || '' }}" which makes matrix.changelog win
over the manual workflow_dispatch input; swap the order so the manual input
overrides the matrix value by setting the expression to use inputs.changelog
first and fall back to matrix.changelog, e.g. change the expression so
inputs.changelog is evaluated before matrix.changelog while keeping the final
fallback of an empty string; update the line referencing matrix.changelog and
inputs.changelog accordingly.

In `@tools/feature_version_audit.py`:
- Around line 965-968: The code is directly constructing feature_dir as
FEATURES_DIR / name, bypassing the file-name fuzzy matching logic earlier;
modify the block that sets feature_dir (before calling get_feature_changelog) to
use the existing fuzzy resolver (the function used earlier in this file to map
display names to folder names—e.g., the resolve/find_feature_dir_by_name or
fuzzy matcher utility) to obtain the actual folder path and only fall back to
FEATURES_DIR / name if the matcher returns None; then pass that resolved
feature_dir into get_feature_changelog so folder-level commits like
"ScreenSpaceGI -> screen space gi" are detected.
- Around line 339-355: The git log call currently uses "--pretty=%s" so only
commit subjects are seen and FOOTER "BREAKING CHANGE:" entries are missed;
update the subprocess.check_output invocation (the raw variable creation) to
request commit body text as well (e.g., use "--pretty=%B" or a format that
includes subject and body like "%s%n%n%b") so RE_COMMIT_BREAKING can match
footers, keep the same decoding/error handling and downstream dedup logic that
iterates over raw and tests
RE_COMMIT_FEAT/RE_COMMIT_FIX/RE_COMMIT_PERF/RE_COMMIT_BREAKING.
🪄 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: fe4e5af0-d936-4465-8fd0-2fdc533a6775

📥 Commits

Reviewing files that changed from the base of the PR and between f5bd0a7 and f9f6614.

📒 Files selected for processing (2)
  • .github/workflows/upload-nexus.yaml
  • tools/feature_version_audit.py

Comment on lines +151 to +153
gh api "repos/$GITHUB_REPOSITORY/releases" \
--jq "[.[] | select(.tag_name == \"$RELEASE_TAG\") | .body][0] // \"\"" \
2>/dev/null > core-body.json || echo '""' > core-body.json
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:

# First, locate and examine the workflow file
find . -name "upload-nexus.yaml" -type f

Repository: community-shaders/skyrim-community-shaders

Length of output: 124


🏁 Script executed:

# Once found, examine the relevant section of the workflow file
cat -n .github/workflows/upload-nexus.yaml | sed -n '145,160p'

Repository: community-shaders/skyrim-community-shaders

Length of output: 1093


🌐 Web query:

GitHub REST API releases endpoint pagination default page size

💡 Result:

The default page size for the GitHub REST API releases endpoint (e.g., GET /repos/{owner}/{repo}/releases) is 30 items per page. This can be overridden using the per_page parameter (max 100).

Citations:


🌐 Web query:

GitHub API "releases/tags/{tag}" endpoint documentation

💡 Result:

The GitHub REST API endpoint for retrieving a release by tag name is GET /repos/{owner}/{repo}/releases/tags/{tag}. This endpoint gets a published release with the specified tag name. Parameters: - owner (string, required): The account owner of the repository. The name is not case sensitive. - repo (string, required): The name of the repository without the .git extension. The name is not case sensitive. - tag (string, required): The name of the tag. Headers: - accept (string): application/vnd.github+json is recommended. HTTP response status codes: - 200: OK - 404: Resource not found Example curl request: curl -L -X GET https://api.github.com/repos/OWNER/REPO/releases/tags/TAG Response schema (Status: 200): Same as the Create a release endpoint. Official documentation: https://docs.github.com/rest/releases/releases#Get-a-release-by-tag-name

Citations:


🏁 Script executed:

# Check how many releases are in this repository
gh release list --repo community-shaders/skyrim-community-shaders --limit 1000 2>/dev/null | wc -l

Repository: community-shaders/skyrim-community-shaders

Length of output: 89


Fetch the release body from the tag endpoint instead of the releases list.

This repository has 56 releases, which exceeds the GitHub API's default page size of 30. The current code filters the paginated /releases response client-side, causing tags on pages 2+ to fall off and resolve to "", which leaves the core Nexus changelog blank for older releases.

Suggested fix
-                  gh api "repos/$GITHUB_REPOSITORY/releases" \
-                    --jq "[.[] | select(.tag_name == \"$RELEASE_TAG\") | .body][0] // \"\"" \
+                  gh api "repos/$GITHUB_REPOSITORY/releases/tags/$RELEASE_TAG" \
+                    --jq '.body // ""' \
                     2>/dev/null > core-body.json || echo '""' > core-body.json
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
gh api "repos/$GITHUB_REPOSITORY/releases" \
--jq "[.[] | select(.tag_name == \"$RELEASE_TAG\") | .body][0] // \"\"" \
2>/dev/null > core-body.json || echo '""' > core-body.json
gh api "repos/$GITHUB_REPOSITORY/releases/tags/$RELEASE_TAG" \
--jq '.body // ""' \
2>/dev/null > core-body.json || echo '""' > core-body.json
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/upload-nexus.yaml around lines 151 - 153, Replace the
paginated releases list call with the releases-by-tag endpoint so the body is
fetched server-side for the specific tag: change the gh api invocation that
currently calls "repos/$GITHUB_REPOSITORY/releases" and uses --jq
'select(.tag_name == "$RELEASE_TAG") | .body' to call the tag endpoint for the
given $RELEASE_TAG (i.e., "repos/$GITHUB_REPOSITORY/releases/tags/$RELEASE_TAG")
and write its .body to core-body.json, preserving the existing error
handling/redirect behavior so older releases are not lost.

mod_version: ${{ matrix.mod_version || needs.prepare-nexus-matrix.outputs.version }}
mod_filename: ${{ matrix.mod_filename }}
changelog: ${{ inputs.changelog || '' }}
changelog: ${{ matrix.changelog || inputs.changelog || '' }}
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:

cat -n .github/workflows/upload-nexus.yaml | sed -n '270,290p'

Repository: community-shaders/skyrim-community-shaders

Length of output: 1323


🏁 Script executed:

# Check the broader context to understand the intent
cat -n .github/workflows/upload-nexus.yaml | sed -n '250,300p'

Repository: community-shaders/skyrim-community-shaders

Length of output: 3359


🏁 Script executed:

# Look for any documentation or comments about the changelog input precedence
rg -i "changelog.*input\|override\|precedence" .github/workflows/upload-nexus.yaml -B 3 -A 3

Repository: community-shaders/skyrim-community-shaders

Length of output: 68


🏁 Script executed:

# Check the workflow inputs definition to understand what inputs.changelog is
rg -i "workflow_dispatch\|inputs:" .github/workflows/upload-nexus.yaml -A 20 | head -50

Repository: community-shaders/skyrim-community-shaders

Length of output: 68


🏁 Script executed:

# Find workflow_dispatch and inputs definition
rg -i "on:\|workflow_dispatch\|inputs:" .github/workflows/upload-nexus.yaml -A 30 | head -80

Repository: community-shaders/skyrim-community-shaders

Length of output: 68


🏁 Script executed:

# Check git log for recent commits mentioning changelog or precedence
git log --oneline --all -20 -- .github/workflows/upload-nexus.yaml

Repository: community-shaders/skyrim-community-shaders

Length of output: 455


🏁 Script executed:

# Look for any PR or discussion context about this
git log --format="%B" --all -5 -- .github/workflows/upload-nexus.yaml | head -100

Repository: community-shaders/skyrim-community-shaders

Length of output: 1269


🌐 Web query:

GitHub Actions expression syntax || operator precedence behavior

💡 Result:

GitHub Actions expression syntax follows standard operator precedence where parentheses have the highest precedence, followed by indexing and property dereference, unary !, comparison operators (< <= > >= == !=), logical AND (&&), and logical OR (||) with the lowest precedence. This means && binds tighter than ||, so expressions like 'condition1 || condition2 && condition3' are parsed as 'condition1 || (condition2 && condition3)'. The || operator performs logical OR with short-circuit evaluation: it evaluates the left operand first; if truthy, returns it without evaluating the right; if falsy, evaluates and returns the right. This enables ternary-like patterns: '${{ condition && 'true_value' || 'false_value' }}', but requires the 'true_value' to be truthy (non-empty string, non-falsy), as empty strings are falsy. Falsy values (false, 0, -0, "", '', null) coerce to false; others to true. Comparisons are loose, case-insensitive for strings. Examples: - Always true due to precedence/logic: (branch != 'prod') || (branch != 'staging') — use && for "neither". - Ternary: github.ref == 'refs/heads/main' && 'prod' || 'dev' — works if 'prod' truthy.

Citations:


🌐 Web query:

GitHub Actions expression || operator "stops at first truthy value" how does it work

💡 Result:

The || (logical OR) operator in GitHub Actions expressions performs short-circuit evaluation, stopping at the first truthy value and returning it without evaluating subsequent operands. This behavior is demonstrated and relied upon in official documentation examples. Key evidence: - Official docs use the idiom condition && 'true_value' || 'false_value' as a ternary-like operator. They explicitly state: "It is important to note that the first value after the && condition must be truthy otherwise the value after the || will always be returned." This requires short-circuiting: if the condition is truthy, && returns the truthy 'true_value' (skipping ||), else && returns falsy, triggering || to return 'false_value'. - Operator precedence follows standard rules where && has higher precedence than || (as listed in docs with ! before comparisons before && before ||), and evaluation is left-to-right. - Community usage in GitHub issues (e.g., actions/runner#409) confirms this pattern works as expected for conditional value selection. Truthy/falsy coercion: falsy values include false, 0, '', null (coerced to false in conditionals per docs); all others are truthy. Example: env: MY_ENV_VAR: ${{ github.ref == 'refs/heads/main' && 'value_for_main_branch' || 'value_for_other_branches' }} If condition true (truthy), returns 'value_for_main_branch'; else 'value_for_other_branches'. Without short-circuit, it would always evaluate to the last operand. For boolean contexts like if:, the result is coerced to boolean (truthy/non-falsy -> true). No official docs explicitly state "short-circuit", but the documented behavior and examples confirm it functions identically to JavaScript logical operators (which GitHub expressions emulate).

Citations:


Swap the changelog precedence so manual input can override matrix-computed values.

The || operator stops at the first truthy value. With the current order, any non-empty matrix.changelog prevents inputs.changelog from being used, contradicting the documented intent that workflow_dispatch.inputs.changelog provides a "manual override."

Suggested fix
-            changelog: ${{ matrix.changelog || inputs.changelog || '' }}
+            changelog: ${{ inputs.changelog || matrix.changelog || '' }}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/upload-nexus.yaml at line 280, The changelog precedence
currently uses "changelog: ${{ matrix.changelog || inputs.changelog || '' }}"
which makes matrix.changelog win over the manual workflow_dispatch input; swap
the order so the manual input overrides the matrix value by setting the
expression to use inputs.changelog first and fall back to matrix.changelog, e.g.
change the expression so inputs.changelog is evaluated before matrix.changelog
while keeping the final fallback of an empty string; update the line referencing
matrix.changelog and inputs.changelog accordingly.

Comment on lines +339 to +355
raw = subprocess.check_output(
["git", "log", f"{base_ref}..{HEAD_REF}", "--pretty=%s", "--"] + paths,
cwd=str(PROJECT_ROOT),
stderr=subprocess.DEVNULL,
).decode("utf-8", errors="replace")
except Exception:
return ""
seen = set()
lines = []
for msg in raw.splitlines():
msg = msg.strip()
if not msg or msg in seen:
continue
seen.add(msg)
if (RE_COMMIT_FEAT.match(msg) or RE_COMMIT_FIX.match(msg) or
RE_COMMIT_PERF.match(msg) or RE_COMMIT_BREAKING.search(msg)):
lines.append(f"- {msg}")
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 | ⚡ Quick win

Include footer-based breaking changes in the changelog.

Using git log --pretty=%s means this filter only sees the subject line, so commits that mark a breaking change via a BREAKING CHANGE: footer are silently dropped even though the function says it includes them.

Suggested fix
-        raw = subprocess.check_output(
-            ["git", "log", f"{base_ref}..{HEAD_REF}", "--pretty=%s", "--"] + paths,
+        raw = subprocess.check_output(
+            ["git", "log", f"{base_ref}..{HEAD_REF}", "--pretty=%B%x1e", "--"] + paths,
             cwd=str(PROJECT_ROOT),
             stderr=subprocess.DEVNULL,
         ).decode("utf-8", errors="replace")
@@
-    for msg in raw.splitlines():
-        msg = msg.strip()
-        if not msg or msg in seen:
+    for entry in raw.split("\x1e"):
+        msg = entry.strip()
+        if not msg:
             continue
-        seen.add(msg)
+        subject = msg.splitlines()[0].strip()
+        if not subject or subject in seen:
+            continue
+        seen.add(subject)
         if (RE_COMMIT_FEAT.match(msg) or RE_COMMIT_FIX.match(msg) or
                 RE_COMMIT_PERF.match(msg) or RE_COMMIT_BREAKING.search(msg)):
-            lines.append(f"- {msg}")
+            lines.append(f"- {subject}")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tools/feature_version_audit.py` around lines 339 - 355, The git log call
currently uses "--pretty=%s" so only commit subjects are seen and FOOTER
"BREAKING CHANGE:" entries are missed; update the subprocess.check_output
invocation (the raw variable creation) to request commit body text as well
(e.g., use "--pretty=%B" or a format that includes subject and body like
"%s%n%n%b") so RE_COMMIT_BREAKING can match footers, keep the same
decoding/error handling and downstream dedup logic that iterates over raw and
tests RE_COMMIT_FEAT/RE_COMMIT_FIX/RE_COMMIT_PERF/RE_COMMIT_BREAKING.

Comment on lines +965 to +968
if base_ref:
feature_dir = FEATURES_DIR / name
changelog = get_feature_changelog(feature_dir, info, base_ref)
if changelog:
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 | 🟡 Minor | ⚡ Quick win

Resolve the feature folder with the existing fuzzy matcher.

Line 966 rebuilds the path as FEATURES_DIR / name, which skips the ScreenSpaceGI -> screen space gi fallback already implemented earlier in this file. For those features, folder-level commits are missed and the generated Nexus changelog is incomplete.

Suggested fix
         if mod_version:
             row['mod_version'] = mod_version
         if base_ref:
-            feature_dir = FEATURES_DIR / name
+            feature_dir = find_feature_dir(name) or (FEATURES_DIR / name)
             changelog = get_feature_changelog(feature_dir, info, base_ref)
             if changelog:
                 row['changelog'] = changelog
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if base_ref:
feature_dir = FEATURES_DIR / name
changelog = get_feature_changelog(feature_dir, info, base_ref)
if changelog:
if base_ref:
feature_dir = find_feature_dir(name) or (FEATURES_DIR / name)
changelog = get_feature_changelog(feature_dir, info, base_ref)
if changelog:
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tools/feature_version_audit.py` around lines 965 - 968, The code is directly
constructing feature_dir as FEATURES_DIR / name, bypassing the file-name fuzzy
matching logic earlier; modify the block that sets feature_dir (before calling
get_feature_changelog) to use the existing fuzzy resolver (the function used
earlier in this file to map display names to folder names—e.g., the
resolve/find_feature_dir_by_name or fuzzy matcher utility) to obtain the actual
folder path and only fall back to FEATURES_DIR / name if the matcher returns
None; then pass that resolved feature_dir into get_feature_changelog so
folder-level commits like "ScreenSpaceGI -> screen space gi" are detected.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 1, 2026

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

@alandtse alandtse merged commit ead7b32 into community-shaders:dev May 1, 2026
14 checks passed
ParticleTroned added a commit to ParticleTroned/skyrim-community-shaders that referenced this pull request May 15, 2026
ParticleTroned added a commit to ParticleTroned/skyrim-community-shaders that referenced this pull request May 16, 2026
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