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
19 changes: 19 additions & 0 deletions .github/workflows/windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,25 @@ jobs:
extension_config_path: config/extension.json
test_contract_path: config/test-contract.json

# Stable branch-protection context independent of PG14/PG19 matrix churn.
# This result requires the ENTIRE maintained-major reusable Windows build.
# No Release/dispatch/publish operations occur in this job.
windows_required:
name: Windows required summary
if: ${{ always() && !startsWith(github.ref, 'refs/heads/release/') }}
needs: windows
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Test required Windows aggregate allow/deny contract
run: python3 tests/test_required_windows_summary.py
- name: Require full maintained-PG Windows matrix success
env:
WINDOWS_MATRIX_RESULT: ${{ needs.windows.result }}
run: python3 scripts/required_windows_summary.py

candidate_report:
name: Verify candidate Windows matrix and immutable artifacts
if: ${{ always() && github.event_name == 'workflow_dispatch' && startsWith(github.ref, 'refs/heads/auto-candidate/') }}
Expand Down
27 changes: 27 additions & 0 deletions scripts/required_windows_summary.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env python3
"""Fail-closed, fixed-name Windows required CI result for maintained-PG matrix.

Never publishes or dispatches. Relies only on GitHub Actions 'needs.windows.result'
for the COMPLETE reusable Windows matrix (not on volatile per-PG job names).
"""
from __future__ import annotations
import os
import sys


def verified_matrix_result(value):
return type(value) is str and value == "success"


def main():
if not verified_matrix_result(os.environ.get("WINDOWS_MATRIX_RESULT")):
print("WINDOWS REQUIRED SUMMARY DENIED: full maintained-PG Windows matrix "
"was not successful", file=sys.stderr)
return 2
print("WINDOWS REQUIRED SUMMARY VERIFIED: full maintained-PG Windows matrix "
"completed successfully")
return 0


if __name__ == "__main__":
raise SystemExit(main())
50 changes: 50 additions & 0 deletions tests/test_required_windows_summary.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/usr/bin/env python3
"""Test the exact stable aggregate check used by Windows CI, without Release."""
import importlib.util
from pathlib import Path
import os
import subprocess
import sys
import unittest

ROOT = Path(__file__).resolve().parents[1]
spec = importlib.util.spec_from_file_location(
"summary", ROOT / "scripts" / "required_windows_summary.py")
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)


class WindowsSummaryTests(unittest.TestCase):
def test_success_only(self):
self.assertTrue(module.verified_matrix_result("success"))
for value in ("failure", "cancelled", "skipped", "", "Success",
"success ", True, 1, None):
with self.subTest(value=value):
self.assertFalse(module.verified_matrix_result(value))

def test_real_exit_status_allow_and_deny(self):
path = ROOT / "scripts" / "required_windows_summary.py"
for value, expected in (("success", 0), ("failure", 2),
("cancelled", 2), ("skipped", 2), ("", 2)):
env = dict(os.environ, WINDOWS_MATRIX_RESULT=value)
res = subprocess.run([sys.executable, str(path)], env=env,
capture_output=True, text=True)
with self.subTest(result=value):
self.assertEqual(res.returncode, expected)

def test_workflow_depends_on_complete_reusable_matrix_not_pg14_name(self):
contents = (ROOT / ".github" / "workflows" / "windows.yml").read_text()
self.assertIn(" windows_required:", contents)
summary = contents.split(" windows_required:", 1)[1].split(
"\n candidate_report:", 1)[0]
self.assertIn("name: Windows required summary", summary)
self.assertIn("needs: windows", summary)
self.assertIn("always()", summary)
self.assertIn("needs.windows.result", summary)
self.assertIn("scripts/required_windows_summary.py", summary)
self.assertNotIn("PostgreSQL 14", summary)
self.assertNotIn("workflow_dispatch:", summary)


if __name__ == "__main__":
unittest.main()
Loading