From fe5539e9c9cd5f7b202b1a2e250fb93ead8bacd9 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 9 Jun 2026 13:54:15 -0400 Subject: [PATCH] ci: add contracts-guard caller (ADR 0022) Thin caller of the reusable contract-change guard in nccs-contracts, per ADR 0022 Migration step 3. As a consumer, this repo's paths_regex covers the read/url/vintage/catalog/column surface, so a PR changing how it consumes a contract must carry an ADR breadcrumb or contracts-ack label. CLAUDE.md pointer added. ADR 0022 --- .github/workflows/contracts-guard.yml | 25 +++++++++++++++++++++++++ CLAUDE.md | 14 ++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 .github/workflows/contracts-guard.yml diff --git a/.github/workflows/contracts-guard.yml b/.github/workflows/contracts-guard.yml new file mode 100644 index 0000000..e2a5028 --- /dev/null +++ b/.github/workflows/contracts-guard.yml @@ -0,0 +1,25 @@ +name: contracts-guard + +# Thin caller of the reusable contract-change guard in nccs-contracts (ADR 0022). +# The guard logic lives once there; this file passes only this repo's +# paths_regex. nccsdata is a CONSUMER, so the contract-relevant surface is how +# it READS and PINS contracted artifacts — the read/url/vintage/catalog/column +# code. Tune the regex as that surface evolves. +# +# The guard verifies ACKNOWLEDGMENT, not correctness: a PR that touches the +# matched paths must carry an `ADR NNNN` breadcrumb (commit message or PR body) +# or the `contracts-ack` label, so the nccs-contracts reconcile isn't silently +# skipped. See nccs-contracts/CONTRIBUTING.md. + +on: + pull_request: + types: [opened, synchronize, reopened, edited, labeled, unlabeled] + +permissions: + contents: read + +jobs: + contracts-guard: + uses: UrbanInstitute/nccs-contracts/.github/workflows/contracts-guard.yml@main + with: + paths_regex: '^R/nccs_(read|read_core|vintage_url|core_url|catalog|core_columns|core_coverage)\.R$' diff --git a/CLAUDE.md b/CLAUDE.md index 294e77e..c90e853 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -206,3 +206,17 @@ Tests use testthat edition 3. Network-dependent integration tests use `skip_on_c - `test-nccs_read.R` — S3 path construction, input validation (offline), integration reads (network) - `test-nccs_normalize_ein.R` — EIN coercion happy/edge paths (offline) - `test-nccs_as_indicator.R` — yn/efile coercion, unknown-value warning (offline) + +## Contract-change guard (ADR 0022) + +A PR that changes how this package **reads or pins** contracted artifacts — the +read/url/vintage/catalog/column code — must acknowledge the +[`nccs-contracts`](https://github.com/UrbanInstitute/nccs-contracts) impact, or +CI fails. The `.github/workflows/contracts-guard.yml` caller (a thin wrapper +over the reusable guard in `nccs-contracts`) fires on PRs that change +`R/nccs_read*.R`, `R/nccs_vintage_url.R`, `R/nccs_core_url.R`, +`R/nccs_catalog.R`, or `R/nccs_core_columns.R`/`R/nccs_core_coverage.R`. To +pass: add an `ADR NNNN` breadcrumb to a commit message or the PR body (and queue +the `nccs-contracts` reconcile if a contract pin/version moved), **or** add the +`contracts-ack` label if there's genuinely no contract impact. The guard checks +*acknowledgment, not correctness*.