From cb5cd3fbcd7f02911e1a8e22427b4af3f6dc4a40 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 26 Oct 2025 14:14:11 +0000 Subject: [PATCH 1/2] chore(codex): bootstrap PR for issue #3053 --- agents/codex-3053.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 agents/codex-3053.md diff --git a/agents/codex-3053.md b/agents/codex-3053.md new file mode 100644 index 0000000000..7d8f923cec --- /dev/null +++ b/agents/codex-3053.md @@ -0,0 +1 @@ + From d0d395dbd253b38d4fe7fc83c867181dd4a42a6d Mon Sep 17 00:00:00 2001 From: stranske Date: Sun, 26 Oct 2025 12:38:51 -0500 Subject: [PATCH 2/2] Store Maint 46 preview screenshot as base64 artifact (#3061) * Store Maint 46 preview screenshot as base64 artifact * Update docs/evidence/maint-46-post-ci-summary.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix(ci): register maint-46-post-ci.yml in workflow inventory * fix(ci): suppress E402 on grouped imports and format test files - Add # noqa: E402 to opening line of grouped import statement - Remove redundant E402 suppression from individual import lines - Format 8 test files with Black Autofix failed because Ruff's import ordering created a grouped import, then the lint step found E402 on the opening line (noqa comments inside parentheses don't suppress errors on the 'from' line). This blocked the Black formatting step from running. * chore(autofix): formatting/lint --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: github-actions[bot] --- .github/workflows/maint-46-post-ci.yml | 188 +++++++++ docs/ci/WORKFLOWS.md | 1 + docs/ci/WORKFLOW_SYSTEM.md | 16 +- docs/evidence/maint-46-post-ci-summary.b64 | 424 +++++++++++++++++++++ docs/evidence/maint-46-post-ci-summary.md | 31 ++ src/trend_analysis/metrics/__init__.py | 10 +- tests/test_workflow_naming.py | 1 + tools/disable_legacy_workflows.py | 2 + 8 files changed, 665 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/maint-46-post-ci.yml create mode 100644 docs/evidence/maint-46-post-ci-summary.b64 create mode 100644 docs/evidence/maint-46-post-ci-summary.md diff --git a/.github/workflows/maint-46-post-ci.yml b/.github/workflows/maint-46-post-ci.yml new file mode 100644 index 0000000000..e89a0b2420 --- /dev/null +++ b/.github/workflows/maint-46-post-ci.yml @@ -0,0 +1,188 @@ +name: Maint 46 Post CI + +'on': + workflow_run: + workflows: + - Gate + types: + - completed + +permissions: + actions: read + contents: read + issues: write + pull-requests: write + statuses: write + +concurrency: + group: maint-46-post-ci-${{ github.event.workflow_run.id || github.run_id }} + cancel-in-progress: false + +jobs: + summary: + name: post ci summary + if: ${{ github.event.workflow_run.event == 'pull_request' }} + runs-on: ubuntu-latest + env: + ARTIFACT_ROOT: summary_artifacts + steps: + - name: Checkout helpers + uses: actions/checkout@v4 + with: + sparse-checkout: | + .github/scripts + tools/post_ci_summary.py + sparse-checkout-cone-mode: false + + - name: Validate workflow syntax + uses: rhysd/actionlint@v1 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + + - name: Discover Gate workflow runs + id: discover + uses: actions/github-script@v7 + with: + script: | + const { discoverWorkflowRuns } = require('./.github/scripts/maint-post-ci.js'); + await discoverWorkflowRuns({ github, context, core }); + + - name: Download Gate artifacts + if: ${{ steps.discover.outputs.gate_run_id != '' }} + uses: actions/download-artifact@v4 + with: + pattern: gate-* + merge-multiple: true + path: ${{ env.ARTIFACT_ROOT }}/downloads + run-id: ${{ steps.discover.outputs.gate_run_id }} + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Collect coverage payloads + if: ${{ steps.discover.outputs.gate_run_id != '' }} + id: coverage_payloads + run: | + python - <<'PY' + import json + import os + from pathlib import Path + + artifact_root = Path(os.environ.get('ARTIFACT_ROOT', 'summary_artifacts')) / 'downloads' + stats_text = '' + delta_text = '' + coverage_section = '' + + def find_file(name: str) -> Path | None: + candidates = sorted(artifact_root.rglob(name)) + for candidate in candidates: + if candidate.is_file(): + return candidate + return None + + stats_path = find_file('gate-coverage.json') + if stats_path: + stats_text = stats_path.read_text(encoding='utf-8') + + delta_path = find_file('gate-coverage-delta.json') + if delta_path: + delta_text = delta_path.read_text(encoding='utf-8') + + summary_path = find_file('gate-coverage-summary.md') + if summary_path: + coverage_section = summary_path.read_text(encoding='utf-8') + + output_path = Path(os.environ['GITHUB_OUTPUT']) + with output_path.open('a', encoding='utf-8') as handle: + if stats_text: + handle.write('stats_json< docs/evidence/maint-46-post-ci-summary.png +``` + +This preserves the evidence while keeping the repository text-only for easier reviews. diff --git a/src/trend_analysis/metrics/__init__.py b/src/trend_analysis/metrics/__init__.py index f5fb641501..0c43f38ba6 100644 --- a/src/trend_analysis/metrics/__init__.py +++ b/src/trend_analysis/metrics/__init__.py @@ -420,7 +420,9 @@ def information_ratio( setattr(_bi, "annualize_volatility", annualize_volatility) # Public submodule to expose summary helpers -from . import attribution # noqa: E402,F401 -from . import rolling # noqa: E402,F401 -from . import summary # noqa: E402,F401 -from . import turnover # noqa: E402,F401 +from . import ( # noqa: E402 + attribution, # noqa: F401 + rolling, # noqa: F401 + summary, # noqa: F401 + turnover, # noqa: F401 +) diff --git a/tests/test_workflow_naming.py b/tests/test_workflow_naming.py index 475abfb74e..37953ffcb4 100644 --- a/tests/test_workflow_naming.py +++ b/tests/test_workflow_naming.py @@ -200,6 +200,7 @@ def test_chatgpt_issue_sync_workflow_present_and_intact(): "health-43-ci-signature-guard.yml": "Health 43 CI Signature Guard", "health-44-gate-branch-protection.yml": "Health 44 Gate Branch Protection", "maint-45-cosmetic-repair.yml": "Maint 45 Cosmetic Repair", + "maint-46-post-ci.yml": "Maint 46 Post CI", "maint-coverage-guard.yml": "Maint Coverage Guard", "maint-47-disable-legacy-workflows.yml": "Maint 47 Disable Legacy Workflows", "maint-50-tool-version-check.yml": "Maint 50 Tool Version Check", diff --git a/tools/disable_legacy_workflows.py b/tools/disable_legacy_workflows.py index f91fb3b576..898bd37954 100644 --- a/tools/disable_legacy_workflows.py +++ b/tools/disable_legacy_workflows.py @@ -62,6 +62,7 @@ "health-43-ci-signature-guard.yml", "health-44-gate-branch-protection.yml", "maint-45-cosmetic-repair.yml", + "maint-46-post-ci.yml", "maint-47-disable-legacy-workflows.yml", "maint-50-tool-version-check.yml", "maint-coverage-guard.yml", @@ -94,6 +95,7 @@ "Health 43 CI Signature Guard", "Health 44 Gate Branch Protection", "Maint 45 Cosmetic Repair", + "Maint 46 Post CI", "Maint 47 Disable Legacy Workflows", "Maint 50 Tool Version Check", "Maint Coverage Guard",