-
Notifications
You must be signed in to change notification settings - Fork 0
Docfx/context7 chat #25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1 @@ | ||||||
| [ ] | ||||||
|
||||||
| [ ] | |
| [] |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,133 @@ | ||||||
| #!/usr/bin/env python3 | ||||||
| """ | ||||||
| Simplified package bumping for Codebelt service updates (Option B). | ||||||
|
|
||||||
| Only updates packages published by the triggering source repo. | ||||||
| Does NOT update Microsoft.Extensions.*, BenchmarkDotNet, or other third-party packages. | ||||||
| Does NOT parse TFM conditions - only bumps Codebelt/Cuemon/Savvyio packages to the triggering version. | ||||||
|
|
||||||
| Usage: | ||||||
| TRIGGER_SOURCE=cuemon TRIGGER_VERSION=10.3.0 python3 bump-nuget.py | ||||||
|
|
||||||
| Behavior: | ||||||
| - If TRIGGER_SOURCE is "cuemon" and TRIGGER_VERSION is "10.3.0": | ||||||
| - Cuemon.Core: 10.2.1 → 10.3.0 | ||||||
| - Cuemon.Extensions.IO: 10.2.1 → 10.3.0 | ||||||
| - Microsoft.Extensions.Hosting: 9.0.13 → UNCHANGED (not a Codebelt package) | ||||||
| - BenchmarkDotNet: 0.15.8 → UNCHANGED (not a Codebelt package) | ||||||
| """ | ||||||
|
|
||||||
| import re | ||||||
| import os | ||||||
| import sys | ||||||
| from typing import Dict, List | ||||||
|
|
||||||
| TRIGGER_SOURCE = os.environ.get("TRIGGER_SOURCE", "") | ||||||
| TRIGGER_VERSION = os.environ.get("TRIGGER_VERSION", "") | ||||||
|
|
||||||
| # Map of source repos to their package ID prefixes | ||||||
| SOURCE_PACKAGE_MAP: Dict[str, List[str]] = { | ||||||
| "cuemon": ["Cuemon."], | ||||||
| "xunit": ["Codebelt.Extensions.Xunit"], | ||||||
| "benchmarkdotnet": ["Codebelt.Extensions.BenchmarkDotNet"], | ||||||
| "bootstrapper": ["Codebelt.Bootstrapper"], | ||||||
| "newtonsoft-json": [ | ||||||
| "Codebelt.Extensions.Newtonsoft.Json", | ||||||
| "Codebelt.Extensions.AspNetCore.Mvc.Formatters.Newtonsoft", | ||||||
| ], | ||||||
| "aws-signature-v4": ["Codebelt.Extensions.AspNetCore.Authentication.AwsSignature"], | ||||||
| "unitify": ["Codebelt.Unitify"], | ||||||
| "yamldotnet": [ | ||||||
| "Codebelt.Extensions.YamlDotNet", | ||||||
| "Codebelt.Extensions.AspNetCore.Mvc.Formatters.Text.Yaml", | ||||||
| ], | ||||||
| "globalization": ["Codebelt.Extensions.Globalization"], | ||||||
| "asp-versioning": ["Codebelt.Extensions.Asp.Versioning"], | ||||||
| "swashbuckle-aspnetcore": ["Codebelt.Extensions.Swashbuckle"], | ||||||
| "savvyio": ["Savvyio."], | ||||||
| "shared-kernel": [], | ||||||
| } | ||||||
|
|
||||||
|
|
||||||
| def is_triggered_package(package_name: str) -> bool: | ||||||
| """Check if package is published by the triggering source repo.""" | ||||||
| if not TRIGGER_SOURCE: | ||||||
| return False | ||||||
| prefixes = SOURCE_PACKAGE_MAP.get(TRIGGER_SOURCE, []) | ||||||
| return any(package_name.startswith(prefix) for prefix in prefixes) | ||||||
|
|
||||||
|
|
||||||
| def main(): | ||||||
| if not TRIGGER_SOURCE or not TRIGGER_VERSION: | ||||||
| print( | ||||||
| "Error: TRIGGER_SOURCE and TRIGGER_VERSION environment variables required" | ||||||
| ) | ||||||
| print(f" TRIGGER_SOURCE={TRIGGER_SOURCE}") | ||||||
| print(f" TRIGGER_VERSION={TRIGGER_VERSION}") | ||||||
| sys.exit(1) | ||||||
|
|
||||||
| # Strip 'v' prefix if present in version | ||||||
| target_version = TRIGGER_VERSION.lstrip("v") | ||||||
|
|
||||||
| print(f"Trigger: {TRIGGER_SOURCE} @ {target_version}") | ||||||
| print(f"Only updating packages from: {TRIGGER_SOURCE}") | ||||||
| print() | ||||||
|
|
||||||
| try: | ||||||
| with open("Directory.Packages.props", "r") as f: | ||||||
| content = f.read() | ||||||
| except FileNotFoundError: | ||||||
| print("Error: Directory.Packages.props not found") | ||||||
| sys.exit(1) | ||||||
|
|
||||||
| changes = [] | ||||||
| skipped_third_party = [] | ||||||
|
|
||||||
| def replace_version(m: re.Match) -> str: | ||||||
| pkg = m.group(1) | ||||||
| current = m.group(2) | ||||||
|
|
||||||
| if not is_triggered_package(pkg): | ||||||
| skipped_third_party.append(f" {pkg} (skipped - not from {TRIGGER_SOURCE})") | ||||||
| return m.group(0) | ||||||
|
|
||||||
| if target_version != current: | ||||||
| changes.append(f" {pkg}: {current} → {target_version}") | ||||||
| return m.group(0).replace( | ||||||
| f'Version="{current}"', f'Version="{target_version}"' | ||||||
| ) | ||||||
|
|
||||||
| return m.group(0) | ||||||
|
|
||||||
| # Match PackageVersion elements (handles multiline) | ||||||
| pattern = re.compile( | ||||||
| r"<PackageVersion\b" | ||||||
| r'(?=[^>]*\bInclude="([^"]+)")' | ||||||
| r'(?=[^>]*\bVersion="([^"]+)")' | ||||||
| r"[^>]*>", | ||||||
| re.DOTALL, | ||||||
| ) | ||||||
| new_content = pattern.sub(replace_version, content) | ||||||
|
|
||||||
| # Show results | ||||||
| if changes: | ||||||
| print(f"Updated {len(changes)} package(s) from {TRIGGER_SOURCE}:") | ||||||
| print("\n".join(changes)) | ||||||
| else: | ||||||
| print(f"No packages from {TRIGGER_SOURCE} needed updating.") | ||||||
|
|
||||||
| if skipped_third_party: | ||||||
| print() | ||||||
| print(f"Skipped {len(skipped_third_party)} third-party package(s):") | ||||||
| print("\n".join(skipped_third_party[:5])) # Show first 5 | ||||||
| if len(skipped_third_party) > 5: | ||||||
| print(f" ... and {len(skipped_third_party) - 5} more") | ||||||
|
|
||||||
| with open("Directory.Packages.props", "w") as f: | ||||||
| f.write(new_content) | ||||||
|
|
||||||
| return 0 if changes else 0 # Return 0 even if no changes (not an error) | ||||||
|
||||||
| return 0 if changes else 0 # Return 0 even if no changes (not an error) | |
| return 0 # Return 0 even if no changes (not an error) |
| 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 | ||||||
|
|
||||||
| - name: Determine new version for this repo | ||||||
| id: newver | ||||||
| run: | | ||||||
| CURRENT=$(grep -oP '(?<=## \[)[\d.]+(?=\])' CHANGELOG.md | head -1) | ||||||
|
||||||
| CURRENT=$(grep -oP '(?<=## \[)[\d.]+(?=\])' CHANGELOG.md | head -1) | |
| CURRENT=$(grep -oP '^## \[\K[0-9]+\.[0-9]+\.[0-9]+(?=\])' CHANGELOG.md | head -1) |
| 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: | ||||||
|
||||||
| with urllib.request.urlopen(req) as r: | |
| with urllib.request.urlopen(req, timeout=30) as r: |
Copilot
AI
Feb 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The inline Python script has no error handling for failed HTTP requests. If a dispatch to a downstream repository fails (e.g., due to authentication issues, network problems, or the repository not existing), the script will crash and stop processing remaining repositories. Consider wrapping the urlopen call in a try-except block to log the error and continue processing other repositories.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding an external JavaScript widget from context7.com directly in the footer. Ensure that this third-party script is trusted and that loading it doesn't pose security risks. Consider verifying that the script uses Subresource Integrity (SRI) hashes or that context7.com has appropriate security measures in place. Additionally, the async attribute is good for performance, but consider whether the script should have defer instead if it needs to maintain document order execution.