Skip to content

Latest commit

 

History

History
225 lines (177 loc) · 19.8 KB

File metadata and controls

225 lines (177 loc) · 19.8 KB

⚙️ .github/workflows/ — GitHub Actions Catalog

This directory holds 50 workflow files (22 standard .yml + 14 agentic Markdown sources + 14 compiled .lock.yml siblings) that power Riksdagsmonitor's CI/CD, security, data pipeline, agentic news generation, and monitoring.

Canonical long-form workflow reference: WORKFLOWS.md at the repository root — version matrices, Mermaid pipeline diagrams, ISMS control mapping, troubleshooting, and KPIs. Agentic workflow contract (imports, analysis gate, 23-artifact baseline): .github/prompts/README.md.


📊 File inventory at a glance

File kind Count Notes
Standard GitHub Actions (*.yml, not *.lock.yml) 22 Run natively on the GitHub Actions runner
Agentic workflow sources (news-*.md) 14 Authored in Markdown with gh-aw frontmatter + prompt imports
Agentic workflow compiled lock files (news-*.lock.yml) 14 Auto-generated by compile-agentic-workflows.yml — these are what actually execute
Total 50 Verify with `ls .github/workflows/

Only the compiled .lock.yml files run. The .md sources are the source of truth and are reviewed in PRs; lock files are regenerated via the gh aw compile CLI.


🔐 Security & Compliance (5)

File Trigger Purpose
codeql.yml Push, PR, weekly CodeQL SAST — javascript-typescript matrix
dependency-review.yml Pull requests SCA gate — blocks PRs on critical/high vulnerabilities
scorecards.yml Push to main, weekly OpenSSF Scorecard supply-chain assessment
setup-labels.yml Manual dispatch Repository label management (.github/labeler.yml source)
labeler.yml Pull requests Auto-label PRs from .github/labeler.yml patterns

🧪 Testing & Validation (8)

File Trigger Purpose
javascript-testing.yml Push/PR on TS/JS/HTML/config TypeScript type-check + Vitest (2 890 tests) + Vite build
jsdoc-validation.yml Manual dispatch TypeDoc generation + coverage report
quality-checks.yml Push/PR to main ESLint + HTMLHint + linkinator (parallel jobs)
knip.yml Push/PR to main Knip dead-code detector — blocks on unused files / dependencies / binaries / duplicate exports; reports unused exports & types informationally
translation-validation.yml Push/PR on HTML 14-language completeness + RTL + hreflang
test-dashboard.yml Push/PR on dashboards Cypress E2E for dashboard pages
test-homepage.yml Push/PR on homepage Cypress E2E for the 14 index*.html homepages
test-news.yml Push/PR on news/** Cypress E2E for news article pages

🚀 Release & Deployment (3)

File Trigger Purpose
release.yml Tag v*, manual SLSA provenance + SBOM + dual deploy (S3 + GitHub Pages)
deploy-s3.yml Push to main AWS S3 sync + CloudFront invalidation via OIDC
lighthouse-ci.yml Push/PR, weekly Lighthouse CI: performance, a11y, SEO, best practices

📊 Data Pipeline (1)

File Trigger Purpose
update-cia-csv-data.yml Nightly 03:30 UTC, manual Refresh every tracked data/cia/** + cia-data/** CSV from upstream Hack23/cia; refresh production-stats.json; inject counts into 14× index*.html; open a single PR on changes

🤖 Agentic News Generation (14 × 2 = 28 files)

Each agentic workflow is a pair: an authored .md source + a compiled .lock.yml. The source imports bounded-context prompt modules from .github/prompts/. The compiled lock file is hardened (SHA-pinned actions, egress firewall, five-layer safe-outputs) and is what GitHub Actions actually runs.

Article-type workflows (single-type, 23-artifact baseline)

# Source (.md) Lock (.lock.yml) Schedule Primary MCP data
1 news-committee-reports.md news-committee-reports.lock.yml Mon–Fri 04:00 UTC get_betankanden, search_voteringar, search_anforanden, get_propositioner
2 news-propositions.md news-propositions.lock.yml Mon–Fri 05:00 UTC get_propositioner, search_dokument_fulltext, search_anforanden
3 news-motions.md news-motions.lock.yml Mon–Fri 06:00 UTC get_motioner, search_dokument_fulltext, search_anforanden
4 news-interpellations.md news-interpellations.lock.yml Mon–Fri 07:00 UTC get_interpellationer, search_anforanden, get_calendar_events

Aggregation & prospective workflows (Tier-C, 23-artifact baseline; year-ahead gate-blocking = 24, mandated = 26; election-cycle gate-blocking = 28)

# Source (.md) Lock (.lock.yml) Schedule Purpose
5 news-realtime-monitor.md news-realtime-monitor.lock.yml Mon–Fri 10:00 + 14:00 UTC, weekends 12:00 Breaking events, urgency classification
6 news-evening-analysis.md news-evening-analysis.lock.yml Mon–Fri 18:00, Sat 16:00 UTC Daily parliamentary pulse, coalition cohesion
7 news-week-ahead.md news-week-ahead.lock.yml Fri 07:00 UTC Prospective week preview; IMF WEO T+5 economic outlook
8 news-month-ahead.md news-month-ahead.lock.yml 1st of month 08:00 UTC Monthly legislative pipeline + pinned IMF projection vintage
9 news-quarter-ahead.md news-quarter-ahead.lock.yml 1st + 15th of month 09:00 UTC 90-day parliamentary-season + Riksbank/SCB calendar; long-horizon-forecasting × 1.7
10 news-year-ahead.md news-year-ahead.lock.yml 5 Jan + 5 Jul 09:00 UTC 365-day annual outlook anchored in IMF WEO Apr/Oct vintage; PESTLE gate-blocking (LH-4); wildcards + SWOT mandated by registry; × 2.0
11 news-election-cycle.md news-election-cycle.lock.yml workflow_dispatch (cron 0 9 13 3,9 * declared but disabled until runtime measured) Full 4-year mandate; current Tidö + next post-2026 cycle; 28-artifact contract (23 + 5 blocking supplementary via LH-4 + LH-5); × 2.5
12 news-weekly-review.md news-weekly-review.lock.yml Sat 09:00 UTC Week-over-week trends, throughput metrics
13 news-monthly-review.md news-monthly-review.lock.yml 28th 10:00 UTC Monthly retrospective, party productivity rankings

Manual & translation workflows

# Source (.md) Lock (.lock.yml) Schedule Purpose
14 news-translate.md news-translate.lock.yml Daily 09:00 + 14:00 + 19:00 UTC Translate analysis/daily/**/executive-brief.md into executive-brief_<lang>.md for the 13 non-English target languages (default batch: 3 sources × 13 languages = 39 files/run)

Every news workflow imports the bounded-context prompt modules in this exact order (full contract in .github/prompts/README.md):

  1. ../prompts/00-base-contract.md — role, ethics, GDPR/ISMS, AI-FIRST rule
  2. ../prompts/01-bash-and-shell-safety.md — AWF-safe shell patterns, UTF-8
  3. ../prompts/02-mcp-access.md — MCP server inventory + health gate
  4. ../prompts/03-data-download.md — download pipeline, manifest
  5. ../prompts/04-analysis-pipeline.md — methodologies, templates, 23 required artifacts (Family A–D), Pass 1 + Pass 2
  6. ../prompts/05-analysis-gate.mdsingle blocking gate — no article until it passes
  7. ../prompts/06-article-generation.md — article sections, banned patterns, visualisation, translations
  8. ../prompts/07-commit-and-pr.md — stage → commit → exactly one create_pull_request
  9. (Tier-C workflows only) ../prompts/ext/tier-c-aggregation.md — depth multipliers, cross-type synthesis, higher article floor (same 23 artifacts)

Common tool surface (every news-*.md)

Every news workflow declares the same tool & runtime surface for parity, resilience, and full gh-aw v0.74.3 capability coverage:

Field Value Purpose
runtimes.node.version "26" Pinned Node 26 for IMF CLI + render scripts
engine.id / engine.model copilot / claude-sonnet-4.6 Faster Sonnet model (adopted in the v0.71.3 refactor for throughput within the 60-min budget; carried forward to v0.74.3 — GPT-5.4 / GPT-5.4-mini eligibility now resolved upstream per v0.74.3 release notes #31695 + #32197 but not yet A/B-tested on this repo)
engine.mcp.session-timeout 1h removed Was added in gh-aw v0.71.3 and rejected by MCP Gateway v0.3.1. v0.74.3 lock files now ship MCP Gateway v0.3.9; re-acceptance has not yet been validated on this repo, so the field stays removed until verified.
tools.github.toolsets [all] Full GitHub MCP surface (issues, PRs, repos, code-search, actions, releases, discussions, …); see github-tools.md
tools.bash / tools.edit / tools.web-fetch / tools.agentic-workflows enabled Full local tool surface; web-fetch reaches non-MCP public sources (statskontoret.se, riksdagsmonitor.com) through the AWF firewall
tools.cache-memory keyed by news-${workflow}-${article_date}; best-effort cache persistence aligned with a 14-day recovery window Resilience knob — analysis artifacts persisted at /tmp/gh-aw/cache-memory/; may be restored on the next run if the previous PR failed and the cache entry is still available (see 07-commit-and-pr.md §Cache-memory recovery)
tools.playwright enabled in news-evening-analysis + news-realtime-monitor only Live HTML validation for tier-C aggregation runs
features.mcp-gateway true Routes all MCP traffic through the gh-aw mcp-gateway (single audit point)
timeout-minutes 60 Job ceiling measured from job start; agent phases target completion by agent minute 40, PR by agent minute 42 (hard 45) to reserve setup/safe-output headroom
safe-outputs.create-pull-request.fallback-as-issue true (explicit) If org disables Actions PR creation, fall back to an issue + branch link instead of failing
safe-outputs.create-pull-request.if-no-changes warn Empty patches emit a warning instead of failing the run (e.g. duplicate-date dispatches)
network.allowed node, github, defaults + explicit Docker Hub hosts (docker.io, registry-1.docker.io, auth.docker.io, production.cloudflare.docker.com) + IMF/SCB/Riksdag/Statskontoret/site domains Ecosystem identifiers preferred per upstream network.md. The broad containers ecosystem (which would also permit ghcr.io, quay.io, gcr.io, mcr.microsoft.com, pkgs.k8s.io, …) is deliberately omitted to keep least-privilege egress; only the minimal Docker Hub hosts actually required to resolve node:26-alpine for the SCB and World Bank MCP servers are enumerated. Any future switch to ghcr.io, quay.io, or other registries must add the specific hosts and be reviewed against the egress allowlist policy before merge.
permissions contents: read, issues: read, pull-requests: read, actions: read, discussions: read, security-events: read Least-privilege agent token; write capabilities live exclusively in the safe-outputs runner job

v0.74.3 capabilities — adoption status

Tracking grid for the features called out in the gh-aw v0.74.3 release notes. All 14 news-*.lock.yml files compile against v0.74.3 today; the rows below classify each new capability as adopted, planned (follow-up PR), or non-applicable.

v0.74.3 feature Status Notes
Glob patterns in add-labels safe outputs (#32022) Planned Replace hard-coded labels: [agentic-news, analysis-data] with agentic-* glob to allow agent-driven self-labelling of agentic-tier-c, agentic-long-horizon, agentic-election-cycle.
Issue Fields in safe outputs (#30846) Planned Move severity / horizon-band / election-cycle metadata off labels into issue fields on uptime-monitor and PIR roll-forward issues.
Stable slash_command / label_command triggers (#32348) Planned Add /regen-news <date> <type> and regen-news label triggers to news-propositions / news-motions / news-committee-reports / news-interpellations.
aw-compat codemods (#32341): run-expression hoisting, engine pinning, toolset-permission synthesis Adopted Verified clean: gh aw fix (dry-run) reports "No fixes needed" against all 14 news workflows on v0.74.3 (validated 2026-05-15). gh aw fix --list-codemods shows the highest registered codemod targeting our migration range introduced in v0.68.4 — there are no v0.71→v0.74 codemods that apply.
Warn-mode threat guardrails for safe outputs (#32399) Planned Tighten safe-outputs.threat-detection.continue-on-error: true → warn-mode with structured warning ingested into analysis-quality.md.
Agent compatibility matrix and validation (#32396) Planned Declare agent-compatibility: matrix: claude-sonnet-4.6 accepted; gpt-5.4, gpt-5.4-mini opt-in after A/B test.
Enhanced OTel spans + Grafana MCP shared component (#32425, #32340) Planned Add Grafana MCP to news-evening-analysis + news-realtime-monitor; pipe agent-phase timings and gate-pass/fail counts.
excessivefuncparams linter (#32402) Planned Run against scripts/imf-fetch.ts, scripts/aggregate-analysis.ts, scripts/render-articles.ts; refactor opportunity, non-blocking.
experiments.* valid in runtime-import expressions (#32375) Planned Expose experiments.tier_c_compression, experiments.lh_pestle_blocking, experiments.cycle_rollover_window.
MCP Gateway upgrade to ghcr.io/github/gh-aw-mcpg:v0.3.9 Adopted Now present in every news-*.lock.yml manifest. Field-level effects (e.g. engine.mcp.session-timeout re-acceptance) still pending re-validation.
GPT-5.4 / GPT-5.4-mini fixes (#31695, #32197) Available Models now compatible; not yet A/B-tested against claude-sonnet-4.6 on this repo.
gh aw compile --staged (v0.74.2) Planned Adopt in compile-agentic-workflows.yml for PR previews of the compiled .lock.yml.
REST API for agent session task creation (v0.74.2) Adopted Default in compiled .lock.yml files.
Higher default max-runs (100 → 500, v0.74.2) Adopted Inherited from compiler defaults; no explicit cap needed for current scheduling fan-out.

Tracker: Article-Generation.md §"Modularization roadmap" carries the per-feature follow-up PR titles.

🛠️ Automation & Tooling (4)

File Trigger Purpose
compile-agentic-workflows.yml Push/PR touching news-*.md, manual Run gh aw compile → regenerate .lock.yml; enforce firewall + safe-outputs + SHA-pinning
agentics-maintenance.yml Scheduled + manual Hygiene of the agentic environment: stale branch cleanup, secret-rotation hooks, runtime-cache eviction
copilot-setup-steps.yml Push, manual Bootstrap GitHub Copilot coding-agent environment for this repo

📡 Monitoring & Infrastructure (1)

File Trigger Purpose
uptime-monitor.yml Every 15 minutes Availability checks for all 14 language homepages; auto-creates/closes GitHub issues on outage/recovery; validates HSTS/CSP/X-Frame-Options headers

🔄 Triggers at a glance

flowchart LR
  subgraph "⏰ Cron"
    C1[Every 15 min → uptime-monitor]
    C2[Nightly 03:30 UTC → update-cia-csv-data]
    C3[Mon-Fri 04:00-18:00 → news-* article + analysis]
    C4[Daily 09 + 14 + 19 UTC → news-translate (exec-brief markdown)]
    C5[Fri 07:00 → news-week-ahead]
    C6[Sat 09:00 → news-weekly-review]
    C7[28th 10:00 → news-monthly-review]
    C8[1st 08:00 → news-month-ahead]
    C9[1st + 15th 09:00 → news-quarter-ahead]
    C10[5 Jan + 5 Jul 09:00 → news-year-ahead]
    C11[Weekly → codeql + scorecards + lighthouse-ci]
  end
  subgraph "🔀 Event"
    E1[push/PR → quality-checks + knip + javascript-testing + translation-validation + codeql + test-*]
    E2[Tag v*.*.* → release]
    E3[push main → deploy-s3]
    E4[PR → dependency-review + labeler]
  end
  subgraph "👆 Manual"
    M1[workflow_dispatch → any workflow]
    M2[news-election-cycle → dispatch-only initially, until runtime measured]
  end
  style C3 fill:#0a0e27,stroke:#00d9ff,color:#e0e0e0
  style E2 fill:#1a1e3d,stroke:#ffbe0b,color:#e0e0e0
Loading

🔒 Universal security posture

Every workflow in this directory implements defence-in-depth — see WORKFLOWS.md §"Workflow Security Architecture" for the full matrix.

Control How it's enforced
step-security/harden-runner First step of every job; egress audit/allow-list
SHA-pinned uses: 100 % coverage — any third-party Action pinned to commit SHA
Least-privilege permissions: Default contents: read; only required scopes added
OIDC for AWS id-token: write + role-to-assume (no long-lived keys)
Five-layer safe outputs (agentic) Sanitise → schema-validate → policy-check → human-review → merge
Squid + iptables egress firewall (agentic) Only domains in network.allowed: reach the internet

🧭 Where to go next

I want to… Read
Understand a specific pipeline stage end-to-end WORKFLOWS.md
Author or modify an agentic news workflow .github/prompts/README.md + .github/skills/gh-aw-workflow-authoring/
Understand how safe outputs and the firewall work .github/skills/gh-aw-safe-outputs/ + .github/skills/gh-aw-firewall/
Compile .md.lock.yml locally Run gh aw compile .github/workflows/<name>.md (workflow compile-agentic-workflows.yml does this in CI)
See ISMS control mapping WORKFLOWS.md §"ISMS Compliance Mapping"
Trace the analysis artifact contract analysis/README.md + analysis/methodologies/README.md + analysis/templates/README.md

📋 Document owner: CEO | 🏷️ Classification: Public | 🔄 Review cycle: Quarterly