From b7864565f557c346c6d46259da2961c88e14355c Mon Sep 17 00:00:00 2001 From: Brent Richardson Date: Thu, 27 Nov 2025 21:04:45 -0500 Subject: [PATCH 1/2] ci: add guardrail CI/CD workflows, orchestrator, and lanes --- .../workflows/guardrail-gate-nightly.yml | 79 +++++++++++++++++ .github/.github/workflows/guardrail-gate.yml | 80 ++++++++++++++++++ ai/out/GUARDRAIL_ENFORCER_REPORT.md | 11 +++ ai/out/LANE_INFRA.md | 10 +++ ai/out/LANE_SEC.md | 10 +++ docs/guardrail-gate.md | Bin 0 -> 170 bytes scripts/lanes/_lane-helper.ps1 | 17 ++++ scripts/lanes/check-a11y.ps1 | 2 + scripts/lanes/check-data.ps1 | 2 + scripts/lanes/check-gov.ps1 | 2 + scripts/lanes/check-infra.ps1 | 2 + scripts/lanes/check-obs.ps1 | 2 + scripts/lanes/check-perf.ps1 | 2 + scripts/lanes/check-sec.ps1 | 2 + scripts/lanes/check-web-build.ps1 | 2 + scripts/run-guardrail-enforcer.ps1 | 42 +++++++++ 16 files changed, 265 insertions(+) create mode 100644 .github/.github/workflows/guardrail-gate-nightly.yml create mode 100644 .github/.github/workflows/guardrail-gate.yml create mode 100644 ai/out/GUARDRAIL_ENFORCER_REPORT.md create mode 100644 ai/out/LANE_INFRA.md create mode 100644 ai/out/LANE_SEC.md create mode 100644 docs/guardrail-gate.md create mode 100644 scripts/lanes/_lane-helper.ps1 create mode 100644 scripts/lanes/check-a11y.ps1 create mode 100644 scripts/lanes/check-data.ps1 create mode 100644 scripts/lanes/check-gov.ps1 create mode 100644 scripts/lanes/check-infra.ps1 create mode 100644 scripts/lanes/check-obs.ps1 create mode 100644 scripts/lanes/check-perf.ps1 create mode 100644 scripts/lanes/check-sec.ps1 create mode 100644 scripts/lanes/check-web-build.ps1 create mode 100644 scripts/run-guardrail-enforcer.ps1 diff --git a/.github/.github/workflows/guardrail-gate-nightly.yml b/.github/.github/workflows/guardrail-gate-nightly.yml new file mode 100644 index 0000000..fc4efdc --- /dev/null +++ b/.github/.github/workflows/guardrail-gate-nightly.yml @@ -0,0 +1,79 @@ +name: Guardrail Gate (Nightly Drift Check) + +on: + schedule: + - cron: "17 3 * * *" + workflow_dispatch: + +permissions: + contents: read + +jobs: + guardrail-nightly: + name: Guardrail Gate Nightly + strategy: + matrix: + os: [ubuntu-latest, windows-latest] + runs-on: ${{ matrix.os }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install PowerShell (Ubuntu) + if: matrix.os == 'ubuntu-latest' + run: | + sudo apt-get update + sudo apt-get install -y wget apt-transport-https software-properties-common + wget -q https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb + sudo dpkg -i packages-microsoft-prod.deb + sudo apt-get update + sudo apt-get install -y powershell + + - name: Generate lane artifacts + shell: pwsh + run: | + pwsh scripts/lanes/check-infra.ps1 + pwsh scripts/lanes/check-sec.ps1 + pwsh scripts/lanes/check-web-build.ps1 + pwsh scripts/lanes/check-data.ps1 + pwsh scripts/lanes/check-obs.ps1 + pwsh scripts/lanes/check-perf.ps1 + pwsh scripts/lanes/check-a11y.ps1 + pwsh scripts/lanes/check-gov.ps1 + + - name: Run guardrail enforcer + shell: pwsh + run: pwsh -File scripts/run-guardrail-enforcer.ps1 -OutDir ai/out + + - name: Append report to job summary + if: always() + shell: pwsh + run: | + if (Test-Path "ai/out/GUARDRAIL_ENFORCER_REPORT.md") { + $content = Get-Content "ai/out/GUARDRAIL_ENFORCER_REPORT.md" -Raw + Write-Host "$content" + echo "$content" >> $env:GITHUB_STEP_SUMMARY + } else { + Write-Host "Report missing" + } + + - name: Upload artifacts + if: failure() || success() + uses: actions/upload-artifact@v4 + with: + name: guardrail-artifacts-nightly-${{ matrix.os }} + path: | + ai/out/LANE_*.md + ai/out/GUARDRAIL_ENFORCER_REPORT.md + + - name: Slack notify on failure (optional) + if: failure() && env.SLACK_WEBHOOK_URL != '' + uses: slackapi/slack-github-action@v1.24.0 + with: + payload: | + { + "text": "Nightly Guardrail Gate failed on ${{ matrix.os }} for ${{ github.repository }}@${{ github.ref }}. See artifacts and report." + } + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + diff --git a/.github/.github/workflows/guardrail-gate.yml b/.github/.github/workflows/guardrail-gate.yml new file mode 100644 index 0000000..b93f9e9 --- /dev/null +++ b/.github/.github/workflows/guardrail-gate.yml @@ -0,0 +1,80 @@ +name: Guardrail Gate (PR & Push) + +on: + push: + branches: ["**"] + pull_request: + branches: ["**"] + +permissions: + contents: read + +jobs: + guardrail: + name: Guardrail Gate + strategy: + matrix: + os: [ubuntu-latest, windows-latest] + runs-on: ${{ matrix.os }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install PowerShell (Ubuntu) + if: matrix.os == 'ubuntu-latest' + run: | + sudo apt-get update + sudo apt-get install -y wget apt-transport-https software-properties-common + wget -q https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb + sudo dpkg -i packages-microsoft-prod.deb + sudo apt-get update + sudo apt-get install -y powershell + + - name: Generate lane artifacts + shell: pwsh + run: | + pwsh scripts/lanes/check-infra.ps1 + pwsh scripts/lanes/check-sec.ps1 + pwsh scripts/lanes/check-web-build.ps1 + pwsh scripts/lanes/check-data.ps1 + pwsh scripts/lanes/check-obs.ps1 + pwsh scripts/lanes/check-perf.ps1 + pwsh scripts/lanes/check-a11y.ps1 + pwsh scripts/lanes/check-gov.ps1 + + - name: Run guardrail enforcer + shell: pwsh + run: pwsh -File scripts/run-guardrail-enforcer.ps1 -OutDir ai/out + + - name: Append report to job summary + if: always() + shell: pwsh + run: | + if (Test-Path "ai/out/GUARDRAIL_ENFORCER_REPORT.md") { + $content = Get-Content "ai/out/GUARDRAIL_ENFORCER_REPORT.md" -Raw + Write-Host "$content" + echo "$content" >> $env:GITHUB_STEP_SUMMARY + } else { + Write-Host "Report missing" + } + + - name: Upload artifacts + if: failure() || success() + uses: actions/upload-artifact@v4 + with: + name: guardrail-artifacts-${{ matrix.os }} + path: | + ai/out/LANE_*.md + ai/out/GUARDRAIL_ENFORCER_REPORT.md + + - name: Slack notify on failure (optional) + if: failure() && env.SLACK_WEBHOOK_URL != '' + uses: slackapi/slack-github-action@v1.24.0 + with: + payload: | + { + "text": "Guardrail Gate failed on ${{ matrix.os }} for ${{ github.repository }}@${{ github.ref }}. See artifacts and report." + } + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + diff --git a/ai/out/GUARDRAIL_ENFORCER_REPORT.md b/ai/out/GUARDRAIL_ENFORCER_REPORT.md new file mode 100644 index 0000000..6e962da --- /dev/null +++ b/ai/out/GUARDRAIL_ENFORCER_REPORT.md @@ -0,0 +1,11 @@ +# Guardrail Enforcer Report + +OutDir: ai/out +Generated: 2025-11-27 20:10:10 + +Lanes: +- LANE_INFRA: INFRA_OK +- LANE_SEC: SEC_OK + + +Decision: RELEASE_GO diff --git a/ai/out/LANE_INFRA.md b/ai/out/LANE_INFRA.md new file mode 100644 index 0000000..c86ee0d --- /dev/null +++ b/ai/out/LANE_INFRA.md @@ -0,0 +1,10 @@ +# Lane: INFRA +Date: 2025-11-27 20:10:09 + +Summary: +INFRA baseline OK (placeholder). + +Checks: +- Placeholder pass + +Result: INFRA_OK diff --git a/ai/out/LANE_SEC.md b/ai/out/LANE_SEC.md new file mode 100644 index 0000000..9eb7287 --- /dev/null +++ b/ai/out/LANE_SEC.md @@ -0,0 +1,10 @@ +# Lane: SEC +Date: 2025-11-27 20:10:10 + +Summary: +SEC baseline OK (placeholder). + +Checks: +- Placeholder pass + +Result: SEC_OK diff --git a/docs/guardrail-gate.md b/docs/guardrail-gate.md new file mode 100644 index 0000000000000000000000000000000000000000..6617b04b4e709fc03166c55b3631e018e8bc52ad GIT binary patch literal 170 zcmWlS!3x4a3wu{?MNp|t~tqcQmn;rVXHX4VBp0m_d zU3I4Jhc$A3t1alxh@8Z+nvP`<+{H`G$oi4w2nifoExElMucz0(Sw?W$#7)0qk6B`b p+Axb} Date: Thu, 27 Nov 2025 21:05:20 -0500 Subject: [PATCH 2/2] fix: move workflows to correct .github/workflows directory --- .github/{.github => }/workflows/guardrail-gate-nightly.yml | 0 .github/{.github => }/workflows/guardrail-gate.yml | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename .github/{.github => }/workflows/guardrail-gate-nightly.yml (100%) rename .github/{.github => }/workflows/guardrail-gate.yml (100%) diff --git a/.github/.github/workflows/guardrail-gate-nightly.yml b/.github/workflows/guardrail-gate-nightly.yml similarity index 100% rename from .github/.github/workflows/guardrail-gate-nightly.yml rename to .github/workflows/guardrail-gate-nightly.yml diff --git a/.github/.github/workflows/guardrail-gate.yml b/.github/workflows/guardrail-gate.yml similarity index 100% rename from .github/.github/workflows/guardrail-gate.yml rename to .github/workflows/guardrail-gate.yml