From cf5cc25392378597dac863ec8da867366897c703 Mon Sep 17 00:00:00 2001 From: Andrei Kislichenko Date: Tue, 4 Aug 2026 16:52:48 +0000 Subject: [PATCH] =?UTF-8?q?feat(data-index):=20Pages=20rollout=20kit=20?= =?UTF-8?q?=E2=80=94=2028-repo=20generator,=20consistency=20guards,=20200-?= =?UTF-8?q?checker?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make the relaton-data-* GitHub Pages rollout push-button and defect-proof from the support repo (relaton/relaton#48). No sibling repo is modified. - generator: add optional per-entry favicon/description/pubid_require overrides (fall back to defaults/template) and fold in the 3 already-live repos (ids/oasis/w3c) so configs.yml is the single source for all 28 sites. w3c keeps its Relaton::W3c::PubId + relaton/w3c/pubid; branch: v2 corrects their stale /main/ baseurl (index-v1.yaml is served from v2). - lib: extract baseurl helper; add pages_url / raw_index_url builders. - bin/check-data-pages: HTTP-check each repo's Pages site + raw-index, report 200, exit non-zero otherwise ("confirm each site returns 200" gate). - spec/cimas_data_pages_spec.rb: guard configs.yml <-> cimas.yml agreement (entry + data group + deploy.yml/Gemfile.deploy mapping + matching branch) to close the silent-404 class where a branch drift skips the Pages publish. - data-index/generated/: drift-guarded snapshot of all 28 rendered _config.yml. - cimas.yml: reconcile w3c/oasis/ids branch main -> v2 (verified real default). - data-index/README.adoc: finished rollout runbook + Pages-enablement status. --- bin/check-data-pages | 140 +++++++++++++++++++ cimas-config/cimas.yml | 6 +- data-index/README.adoc | 92 ++++++++++-- data-index/configs.yml | 40 ++++++ data-index/generated/3gpp_config.yml | 9 ++ data-index/generated/README.adoc | 10 ++ data-index/generated/adobe_config.yml | 11 ++ data-index/generated/bipm_config.yml | 9 ++ data-index/generated/calconnect_config.yml | 9 ++ data-index/generated/ccsds_config.yml | 11 ++ data-index/generated/cie_config.yml | 11 ++ data-index/generated/easc_config.yml | 11 ++ data-index/generated/ecma_config.yml | 9 ++ data-index/generated/etsi_config.yml | 11 ++ data-index/generated/gost_config.yml | 11 ++ data-index/generated/iana_config.yml | 9 ++ data-index/generated/ids_config.yml | 9 ++ data-index/generated/iec_config.yml | 11 ++ data-index/generated/ieee_config.yml | 11 ++ data-index/generated/iho_config.yml | 11 ++ data-index/generated/iso_config.yml | 11 ++ data-index/generated/itu-r_config.yml | 11 ++ data-index/generated/jcgm_config.yml | 11 ++ data-index/generated/jis_config.yml | 11 ++ data-index/generated/nist_config.yml | 11 ++ data-index/generated/oasis_config.yml | 9 ++ data-index/generated/ogc_config.yml | 9 ++ data-index/generated/oiml_config.yml | 11 ++ data-index/generated/plateau_config.yml | 11 ++ data-index/generated/rfcs_config.yml | 9 ++ data-index/generated/rfcsubseries_config.yml | 9 ++ data-index/generated/w3c_config.yml | 11 ++ data-index/generated/xsf_config.yml | 9 ++ lib/data_index_config.rb | 66 ++++++++- spec/check_data_pages_spec.rb | 41 ++++++ spec/cimas_data_pages_spec.rb | 79 +++++++++++ spec/data_index_config_spec.rb | 45 ++++-- spec/generated_configs_spec.rb | 30 ++++ 38 files changed, 802 insertions(+), 33 deletions(-) create mode 100755 bin/check-data-pages create mode 100644 data-index/generated/3gpp_config.yml create mode 100644 data-index/generated/README.adoc create mode 100644 data-index/generated/adobe_config.yml create mode 100644 data-index/generated/bipm_config.yml create mode 100644 data-index/generated/calconnect_config.yml create mode 100644 data-index/generated/ccsds_config.yml create mode 100644 data-index/generated/cie_config.yml create mode 100644 data-index/generated/easc_config.yml create mode 100644 data-index/generated/ecma_config.yml create mode 100644 data-index/generated/etsi_config.yml create mode 100644 data-index/generated/gost_config.yml create mode 100644 data-index/generated/iana_config.yml create mode 100644 data-index/generated/ids_config.yml create mode 100644 data-index/generated/iec_config.yml create mode 100644 data-index/generated/ieee_config.yml create mode 100644 data-index/generated/iho_config.yml create mode 100644 data-index/generated/iso_config.yml create mode 100644 data-index/generated/itu-r_config.yml create mode 100644 data-index/generated/jcgm_config.yml create mode 100644 data-index/generated/jis_config.yml create mode 100644 data-index/generated/nist_config.yml create mode 100644 data-index/generated/oasis_config.yml create mode 100644 data-index/generated/ogc_config.yml create mode 100644 data-index/generated/oiml_config.yml create mode 100644 data-index/generated/plateau_config.yml create mode 100644 data-index/generated/rfcs_config.yml create mode 100644 data-index/generated/rfcsubseries_config.yml create mode 100644 data-index/generated/w3c_config.yml create mode 100644 data-index/generated/xsf_config.yml create mode 100644 spec/check_data_pages_spec.rb create mode 100644 spec/cimas_data_pages_spec.rb create mode 100644 spec/generated_configs_spec.rb diff --git a/bin/check-data-pages b/bin/check-data-pages new file mode 100755 index 0000000..dd180f6 --- /dev/null +++ b/bin/check-data-pages @@ -0,0 +1,140 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# Confirm each relaton-data-* GitHub Pages index site is live. For every repo in +# data-index/configs.yml this checks two URLs and prints their HTTP status: +# +# site - https://relaton.github.io/relaton-data-/ (the Pages site) +# raw-index - (the index the theme plugin fetches at build +# time; a 404 here is why a built site can render empty) +# +# Exits non-zero if any checked URL is not 200, so it doubles as a rollout gate. +# This is the operator's "confirm each site returns 200" step: run it AFTER the +# Cimas push + _config.yml commits + Pages enablement have landed. +# +# Usage: +# bin/check-data-pages # check every repo (site + raw-index) +# bin/check-data-pages iso ieee # check only these repos +# bin/check-data-pages --raw-only # skip the Pages site, check raw-index +# bin/check-data-pages --site-only # skip raw-index, check the Pages site +# bin/check-data-pages --base https://data.relaton.org # custom Pages host +# bin/check-data-pages --list # list known repos and exit +# bin/check-data-pages --config PATH ... # use an alternate configs.yml + +require "optparse" +require "net/http" +require "uri" + +require_relative "../lib/data_index_config" + +options = { + config: DataIndexConfig::DEFAULT_CONFIG_PATH, + base: DataIndexConfig::PAGES_HOST, + list: false, + site: true, + raw: true, + timeout: 15, +} +parser = OptionParser.new do |o| + o.banner = "Usage: bin/check-data-pages [repo...] [options]" + o.on("--base HOST", "Pages host (default #{DataIndexConfig::PAGES_HOST})") { |v| options[:base] = v } + o.on("--site-only", "Check only the Pages site URL") { options[:raw] = false } + o.on("--raw-only", "Check only the raw-index URL") { options[:site] = false } + o.on("--timeout SECONDS", Integer, "Per-request timeout (default 15)") { |v| options[:timeout] = v } + o.on("--config PATH", "Path to configs.yml") { |v| options[:config] = v } + o.on("--list", "List known repos and exit") { options[:list] = true } + o.on("-h", "--help", "Show this help") do + puts o + exit + end +end +parser.parse!(ARGV) + +if !options[:site] && !options[:raw] + warn "nothing to check: --site-only and --raw-only are mutually exclusive" + exit 2 +end + +config = DataIndexConfig.load(options[:config]) +known = config.repos.map { |e| e["repo"] } + +if options[:list] + puts known + exit +end + +selected = ARGV.empty? ? known : ARGV.dup +unknown = selected - known +unless unknown.empty? + warn "unknown repo(s): #{unknown.join(', ')}" + warn "known repos: #{known.join(', ')}" + exit 1 +end + +# Follow up to a few redirects (custom Pages domains 301 to https/apex) and +# return the final numeric status, or a short error token on a network failure. +def http_status(url, timeout:, hops: 5) + uri = URI.parse(url) + return "BADURI" unless uri.is_a?(URI::HTTP) + + http = Net::HTTP.new(uri.host, uri.port) + http.use_ssl = (uri.scheme == "https") + http.open_timeout = timeout + http.read_timeout = timeout + # Pass a block so Net::HTTP hands back the response without buffering the body + # (we only need the status + Location; index files can be large). + res = http.request_get(uri.request_uri) { |_response| } + code = res.code.to_i + if [301, 302, 307, 308].include?(code) && hops.positive? && res["location"] + return http_status(URI.join(url, res["location"]).to_s, timeout: timeout, hops: hops - 1) + end + + code +rescue StandardError => e + "ERR:#{e.class.to_s.split('::').last}" +end + +checks = [] +checks << :site if options[:site] +checks << :raw if options[:raw] + +# Precompute the URLs once (also lets us size each column to its widest URL so +# the status/URL columns line up regardless of repo-name or URL length). +site_urls = options[:site] ? selected.to_h { |r| [r, config.pages_url(r, base: options[:base])] } : {} +raw_urls = options[:raw] ? selected.to_h { |r| [r, config.raw_index_url(r)] } : {} + +repo_w = ([4] + selected.map(&:length)).max # 4 = len("repo") +site_w = (site_urls.values.map(&:length) + [0]).max + +header = format("%-#{repo_w}s", "repo") +header += " #{format('%-4s', 'site')} #{format("%-#{site_w}s", '')}" if options[:site] +header += " raw-index" if options[:raw] +puts header +puts "-" * header.length + +failures = 0 +selected.each do |repo| + row = format("%-#{repo_w}s", repo) + statuses = {} + + if options[:site] + st = http_status(site_urls[repo], timeout: options[:timeout]) + statuses[:site] = st + row += " #{format('%-4s', st)} #{format("%-#{site_w}s", site_urls[repo])}" + end + + if options[:raw] + st = http_status(raw_urls[repo], timeout: options[:timeout]) + statuses[:raw] = st + row += " #{format('%-4s', st)} #{raw_urls[repo]}" + end + + puts row + failures += 1 unless checks.all? { |k| statuses[k] == 200 } +end + +if failures.positive? + warn "\n#{failures} repo(s) not fully 200" + exit 1 +end +puts "\nall #{selected.size} repo(s) return 200" diff --git a/cimas-config/cimas.yml b/cimas-config/cimas.yml index 18dc392..dc2f9a8 100644 --- a/cimas-config/cimas.yml +++ b/cimas-config/cimas.yml @@ -340,7 +340,7 @@ repositories: .github/workflows/keep-alive.yml: gh-actions/master/keep-alive.yml relaton-data-w3c: remote: ssh://git@github.com/relaton/relaton-data-w3c - branch: main + branch: v2 files: .github/workflows/crawler.yml: gh-actions/data/crawler.yml .github/workflows/deploy.yml: gh-actions/data/deploy.yml @@ -364,7 +364,7 @@ repositories: .github/workflows/keep-alive.yml: gh-actions/master/keep-alive.yml relaton-data-oasis: remote: ssh://git@github.com/relaton/relaton-data-oasis - branch: main + branch: v2 files: .github/workflows/crawler.yml: gh-actions/data/crawler.yml .github/workflows/deploy.yml: gh-actions/data/deploy.yml @@ -409,7 +409,7 @@ repositories: .github/workflows/keep-alive.yml: gh-actions/master/keep-alive.yml relaton-data-ids: remote: ssh://git@github.com/relaton/relaton-data-ids - branch: main + branch: v2 files: .github/workflows/crawler.yml: gh-actions/data/crawler.yml .github/workflows/deploy.yml: gh-actions/data/deploy.yml diff --git a/data-index/README.adoc b/data-index/README.adoc index a8e4f22..630b05f 100644 --- a/data-index/README.adoc +++ b/data-index/README.adoc @@ -16,6 +16,12 @@ merges the theme's base `_config.yml` with the repo's own (repo values win), run real default branch — drives `baseurl`), and `pubid_class` (blank for flat indexes). Edit this to change any repo's config. `../bin/gen-data-index-config`:: Renders a repo's `_config.yml` from `configs.yml`. +`generated/`:: The committed snapshot of all 28 rendered `_config.yml` files (one + per target repo) — the exact bytes to commit into each data repo. Regenerate with + `../bin/gen-data-index-config --out data-index/generated`; kept honest by + `spec/generated_configs_spec.rb`. +`../bin/check-data-pages`:: Confirms each repo's Pages site and raw index URL return + 200 (the "confirm each site returns 200" gate). Run it after the rollout lands. == Why `_config.yml` lives in each data repo (not Cimas) @@ -64,30 +70,86 @@ bundle, the tier-C flavors below render citable DocIDs rather than a fallback li | adobe, ccsds, cie, easc, etsi, gost, iec, ieee, iho, iso, itu-r, jcgm, jis, nist, oiml, plateau |=== +== Status (verified 2026-08-03) + +`configs.yml` covers *28 repos*: the 25 rollout targets plus the 3 already-live +(*ids, oasis, w3c*), folded in so the generator is the single source for every site. +The 3 live ones carry per-repo `favicon`/`description` overrides (and w3c a +`pubid_require: relaton/w3c/pubid`); regenerating their `_config.yml` reproduces the +live site (with `baseurl` corrected from `/main/` to their real default `/v2/`). + +Live (200): *relaton-data-ids, -oasis, -w3c* — already rolled out. + +Pending (Pages 404): *the other 25 repos in `configs.yml`*. Every one's published index +(``) already returns 200 — i.e. the data side is ready. + +Pages *enablement* state (verified via `gh api repos/relaton/relaton-data-/pages`): + +* *Already enabled* (`build_type: workflow`, source = default branch, no build + published yet so the site 404s) — the *20 `v2`-default repos*. These need only + steps 2–3 below; *skip step 1*. +* *Not enabled* (Pages API 404) — the *5 `main`-default repos*: *adobe, easc, gost, + jcgm, oiml*. These need step 1, which requires *repo admin* (a plain `push`/`repo` + token gets HTTP 404 from the Create-Pages endpoint). + +Re-check current state any time with: + +[source,sh] +---- +bin/check-data-pages # site + raw-index for all 28 +bin/check-data-pages --site-only # just the Pages sites (the 404s to fix) +---- + == Rollout -. Enable GitHub Pages (source: *GitHub Actions*) on the target repo. -. Generate and commit the config onto the repo's default branch: +Do these per target repo (or batch the Cimas step across all of them). Steps 1–3 +all happen *in the data repo* / on GitHub — this `support` repo only holds the +source of truth and tooling. + +. *Enable GitHub Pages* (source: *GitHub Actions*) — *only for the 5 not-yet-enabled + `main`-default repos* (adobe, easc, gost, jcgm, oiml); the 20 `v2` repos already + have it (see Status). *Requires repo admin* — a `push`-only token gets HTTP 404: + [source,sh] ---- -# print one repo's config -bin/gen-data-index-config iso - -# or write files for several repos into a dir -bin/gen-data-index-config --out /tmp/cfg 3gpp ogc xsf -# then copy /tmp/cfg/_config.yml -> /_config.yml and commit +gh api -X POST repos/relaton/relaton-data-/pages \ + -f 'build_type=workflow' # 409 if already enabled (safe to ignore) +---- +. *Commit the `_config.yml`* onto the repo's default branch (from `configs.yml`'s + `branch:` — `v2` for most, `main` for adobe/easc/gost/jcgm/oiml). Use the + committed snapshot: ++ +[source,sh] +---- +# snapshot already rendered in data-index/generated/ +cp data-index/generated/_config.yml /_config.yml +# (or regenerate on the fly: bin/gen-data-index-config ) ---- -. Roll the Cimas plumbing (`deploy.yml`, `Gemfile.deploy`) to every data repo: +. *Roll the Cimas plumbing* (`deploy.yml`, `Gemfile.deploy`) to every data repo — + from the support repo root, per `../README.adoc`: + [source,sh] ---- -# from the support repo root, per cimas-config usage in ../README.adoc cimas sync -f $CIMAS_CONFIG -r $CIMAS_WD -d $CIMAS_MASTER_DIR -g data cimas push -f $CIMAS_CONFIG -r $CIMAS_WD -b data-pages -m 'Pages deploy' -g data +cimas open-prs -f $CIMAS_CONFIG -r $CIMAS_WD -b data-pages -m 'Pages deploy' -g data ---- -. Confirm the `Deploy` workflow goes green and the site lists DocID -> file with - working pagination. - -TIP: Start with Tier A (renders cleanly today); hold Tier B/C until the theme -hand-off lands. +. *Confirm* the `Deploy` workflow goes green and each site returns 200: ++ +[source,sh] +---- +bin/check-data-pages # exits non-zero until every repo is 200 +---- ++ +The site should list DocID -> file with working pagination and a citable DocID +per row. + +TIP: Start with Tier A (renders cleanly today); Tier B/C need the flavor pubid gem +in the build bundle, which `cimas-config/gh-actions/data/Gemfile.deploy` already +provides (it `eval_gemfile`s each repo's own Gemfile). See "Rendering readiness". + +NOTE: `configs.yml` and `../cimas-config/cimas.yml` must agree on every repo's +`branch:` and both must map `deploy.yml` + `Gemfile.deploy`; a drift silently +skips the publish (the deploy job only runs on the repo's default branch). +`spec/cimas_data_pages_spec.rb` enforces this — run `bundle exec rspec` after +editing either file. diff --git a/data-index/configs.yml b/data-index/configs.yml index 800bb71..2afe7f6 100644 --- a/data-index/configs.yml +++ b/data-index/configs.yml @@ -14,6 +14,12 @@ # MUST match the `pubid_class:` the flavor passes to # Relaton::Index.find_or_create in relaton's lib/relaton//data_fetcher.rb. # No leading "::" — the theme plugin resolves it with Object.const_get. +# +# Optional per-entry overrides (fall back to the defaults/template when absent) — +# used by the already-live ids/oasis/w3c to keep their own branding: +# favicon - override defaults.favicon +# description - override the templated "Welcome to the ..." line +# pubid_require - override defaults.pubid_require (w3c uses relaton/w3c/pubid) defaults: paginate: 100 @@ -48,3 +54,37 @@ repos: - { repo: rfcs, display: RFC, source: index-v1.yaml, branch: v2, pubid_class: } - { repo: rfcsubseries, display: RFC Subseries, source: index-v1.yaml, branch: v2, pubid_class: } - { repo: xsf, display: XSF, source: index-v1.yaml, branch: v2, pubid_class: } + + # Already-live repos (their sites returned 200 before this generator existed). + # Folded in so the generator covers all 28; they carry per-repo favicon/ + # description overrides (and w3c a non-default pubid_require). branch: v2 is + # each repo's real default (index-v1.yaml is served from v2). + - repo: ids + display: Internet-Drafts + source: index-v1.yaml + branch: v2 + pubid_class: + favicon: 'https://www.ietf.org/static/img/ietf-logo.dc9646b3c716.svg' + description: 'Bibliographic data information for Internet-Drafts in Relaton format' + - repo: oasis + display: OASIS + source: index-v1.yaml + branch: v2 + pubid_class: + favicon: 'https://www.oasis-open.org/wp-content/uploads/2020/11/cropped-2-layers@3x-32x32.png' + description: >- + Welcome to the OASIS standards index site! This is where you can find the + information you need about the various standards developed and maintained by + the OASIS open community. Explore the OASIS standards and learn how they can + help you solve your business and technical challenges! + - repo: w3c + display: W3C + source: index-v1.yaml + branch: v2 + pubid_class: Relaton::W3c::PubId + pubid_require: relaton/w3c/pubid + favicon: 'https://www.w3.org/assets/logos/w3c/w3c-no-bars.svg' + description: >- + Welcome to the World Wide Web Consortium standards index site! This is where + you can find the information you need about the various standards developed and + maintained by the W3C open community. diff --git a/data-index/generated/3gpp_config.yml b/data-index/generated/3gpp_config.yml new file mode 100644 index 0000000..5fe9697 --- /dev/null +++ b/data-index/generated/3gpp_config.yml @@ -0,0 +1,9 @@ +title: 3GPP Index +description: >- + Welcome to the 3GPP standards index site! +paginate: 100 +jekyll-index: + favicon: 'https://www.relaton.org/favicon.ico' + source: 'index-v1.yaml' + baseurl: 'https://raw.githubusercontent.com/relaton/relaton-data-3gpp/v2/' + add_type_to_reference: true diff --git a/data-index/generated/README.adoc b/data-index/generated/README.adoc new file mode 100644 index 0000000..7fc2a78 --- /dev/null +++ b/data-index/generated/README.adoc @@ -0,0 +1,10 @@ += Generated relaton-data-* `_config.yml` snapshot + +*Do not edit by hand.* These files are generated from `../configs.yml` by +`../../bin/gen-data-index-config --out data-index/generated` and are kept in sync +by `spec/generated_configs_spec.rb`. + +Each `_config.yml` is the exact `_config.yml` to commit into +`relaton/relaton-data-` (on that repo's default branch) as part of the Pages +rollout — see `../README.adoc`. To change a repo's config, edit `../configs.yml` +and regenerate; never edit these files directly. diff --git a/data-index/generated/adobe_config.yml b/data-index/generated/adobe_config.yml new file mode 100644 index 0000000..860d2f0 --- /dev/null +++ b/data-index/generated/adobe_config.yml @@ -0,0 +1,11 @@ +title: Adobe Index +description: >- + Welcome to the Adobe standards index site! +paginate: 100 +jekyll-index: + favicon: 'https://www.relaton.org/favicon.ico' + source: 'index-v2.yaml' + baseurl: 'https://raw.githubusercontent.com/relaton/relaton-data-adobe/main/' + add_type_to_reference: true + pubid_class: 'Pubid::Adobe::Identifier' + pubid_require: 'pubid' diff --git a/data-index/generated/bipm_config.yml b/data-index/generated/bipm_config.yml new file mode 100644 index 0000000..1a9a671 --- /dev/null +++ b/data-index/generated/bipm_config.yml @@ -0,0 +1,9 @@ +title: BIPM Index +description: >- + Welcome to the BIPM standards index site! +paginate: 100 +jekyll-index: + favicon: 'https://www.relaton.org/favicon.ico' + source: 'index-v1.yaml' + baseurl: 'https://raw.githubusercontent.com/relaton/relaton-data-bipm/v2/' + add_type_to_reference: true diff --git a/data-index/generated/calconnect_config.yml b/data-index/generated/calconnect_config.yml new file mode 100644 index 0000000..03552a7 --- /dev/null +++ b/data-index/generated/calconnect_config.yml @@ -0,0 +1,9 @@ +title: CalConnect Index +description: >- + Welcome to the CalConnect standards index site! +paginate: 100 +jekyll-index: + favicon: 'https://www.relaton.org/favicon.ico' + source: 'index-v1.yaml' + baseurl: 'https://raw.githubusercontent.com/relaton/relaton-data-calconnect/v2/' + add_type_to_reference: true diff --git a/data-index/generated/ccsds_config.yml b/data-index/generated/ccsds_config.yml new file mode 100644 index 0000000..63702a9 --- /dev/null +++ b/data-index/generated/ccsds_config.yml @@ -0,0 +1,11 @@ +title: CCSDS Index +description: >- + Welcome to the CCSDS standards index site! +paginate: 100 +jekyll-index: + favicon: 'https://www.relaton.org/favicon.ico' + source: 'index-v2.yaml' + baseurl: 'https://raw.githubusercontent.com/relaton/relaton-data-ccsds/v2/' + add_type_to_reference: true + pubid_class: 'Pubid::Ccsds::Identifier' + pubid_require: 'pubid' diff --git a/data-index/generated/cie_config.yml b/data-index/generated/cie_config.yml new file mode 100644 index 0000000..ae5aede --- /dev/null +++ b/data-index/generated/cie_config.yml @@ -0,0 +1,11 @@ +title: CIE Index +description: >- + Welcome to the CIE standards index site! +paginate: 100 +jekyll-index: + favicon: 'https://www.relaton.org/favicon.ico' + source: 'index-v2.yaml' + baseurl: 'https://raw.githubusercontent.com/relaton/relaton-data-cie/v2/' + add_type_to_reference: true + pubid_class: 'Pubid::Cie::Identifier' + pubid_require: 'pubid' diff --git a/data-index/generated/easc_config.yml b/data-index/generated/easc_config.yml new file mode 100644 index 0000000..513c767 --- /dev/null +++ b/data-index/generated/easc_config.yml @@ -0,0 +1,11 @@ +title: EASC Index +description: >- + Welcome to the EASC standards index site! +paginate: 100 +jekyll-index: + favicon: 'https://www.relaton.org/favicon.ico' + source: 'index-v2.yaml' + baseurl: 'https://raw.githubusercontent.com/relaton/relaton-data-easc/main/' + add_type_to_reference: true + pubid_class: 'Pubid::Easc::Identifier' + pubid_require: 'pubid' diff --git a/data-index/generated/ecma_config.yml b/data-index/generated/ecma_config.yml new file mode 100644 index 0000000..cecc67e --- /dev/null +++ b/data-index/generated/ecma_config.yml @@ -0,0 +1,9 @@ +title: ECMA Index +description: >- + Welcome to the ECMA standards index site! +paginate: 100 +jekyll-index: + favicon: 'https://www.relaton.org/favicon.ico' + source: 'index-v1.yaml' + baseurl: 'https://raw.githubusercontent.com/relaton/relaton-data-ecma/v2/' + add_type_to_reference: true diff --git a/data-index/generated/etsi_config.yml b/data-index/generated/etsi_config.yml new file mode 100644 index 0000000..79efb7f --- /dev/null +++ b/data-index/generated/etsi_config.yml @@ -0,0 +1,11 @@ +title: ETSI Index +description: >- + Welcome to the ETSI standards index site! +paginate: 100 +jekyll-index: + favicon: 'https://www.relaton.org/favicon.ico' + source: 'index-v2.yaml' + baseurl: 'https://raw.githubusercontent.com/relaton/relaton-data-etsi/v2/' + add_type_to_reference: true + pubid_class: 'Pubid::Etsi::Identifier' + pubid_require: 'pubid' diff --git a/data-index/generated/gost_config.yml b/data-index/generated/gost_config.yml new file mode 100644 index 0000000..80b6746 --- /dev/null +++ b/data-index/generated/gost_config.yml @@ -0,0 +1,11 @@ +title: GOST Index +description: >- + Welcome to the GOST standards index site! +paginate: 100 +jekyll-index: + favicon: 'https://www.relaton.org/favicon.ico' + source: 'index-v2.yaml' + baseurl: 'https://raw.githubusercontent.com/relaton/relaton-data-gost/main/' + add_type_to_reference: true + pubid_class: 'Pubid::Gost::Identifier' + pubid_require: 'pubid' diff --git a/data-index/generated/iana_config.yml b/data-index/generated/iana_config.yml new file mode 100644 index 0000000..b08c90b --- /dev/null +++ b/data-index/generated/iana_config.yml @@ -0,0 +1,9 @@ +title: IANA Index +description: >- + Welcome to the IANA standards index site! +paginate: 100 +jekyll-index: + favicon: 'https://www.relaton.org/favicon.ico' + source: 'index-v1.yaml' + baseurl: 'https://raw.githubusercontent.com/relaton/relaton-data-iana/v2/' + add_type_to_reference: true diff --git a/data-index/generated/ids_config.yml b/data-index/generated/ids_config.yml new file mode 100644 index 0000000..b072b97 --- /dev/null +++ b/data-index/generated/ids_config.yml @@ -0,0 +1,9 @@ +title: Internet-Drafts Index +description: >- + Bibliographic data information for Internet-Drafts in Relaton format +paginate: 100 +jekyll-index: + favicon: 'https://www.ietf.org/static/img/ietf-logo.dc9646b3c716.svg' + source: 'index-v1.yaml' + baseurl: 'https://raw.githubusercontent.com/relaton/relaton-data-ids/v2/' + add_type_to_reference: true diff --git a/data-index/generated/iec_config.yml b/data-index/generated/iec_config.yml new file mode 100644 index 0000000..6151eb1 --- /dev/null +++ b/data-index/generated/iec_config.yml @@ -0,0 +1,11 @@ +title: IEC Index +description: >- + Welcome to the IEC standards index site! +paginate: 100 +jekyll-index: + favicon: 'https://www.relaton.org/favicon.ico' + source: 'index-v2.yaml' + baseurl: 'https://raw.githubusercontent.com/relaton/relaton-data-iec/v2/' + add_type_to_reference: true + pubid_class: 'Pubid::Iec::Identifier' + pubid_require: 'pubid' diff --git a/data-index/generated/ieee_config.yml b/data-index/generated/ieee_config.yml new file mode 100644 index 0000000..403d86b --- /dev/null +++ b/data-index/generated/ieee_config.yml @@ -0,0 +1,11 @@ +title: IEEE Index +description: >- + Welcome to the IEEE standards index site! +paginate: 100 +jekyll-index: + favicon: 'https://www.relaton.org/favicon.ico' + source: 'index-v2.yaml' + baseurl: 'https://raw.githubusercontent.com/relaton/relaton-data-ieee/v2/' + add_type_to_reference: true + pubid_class: 'Pubid::Ieee::Identifier' + pubid_require: 'pubid' diff --git a/data-index/generated/iho_config.yml b/data-index/generated/iho_config.yml new file mode 100644 index 0000000..b6a6e73 --- /dev/null +++ b/data-index/generated/iho_config.yml @@ -0,0 +1,11 @@ +title: IHO Index +description: >- + Welcome to the IHO standards index site! +paginate: 100 +jekyll-index: + favicon: 'https://www.relaton.org/favicon.ico' + source: 'index-v3.yaml' + baseurl: 'https://raw.githubusercontent.com/relaton/relaton-data-iho/v2/' + add_type_to_reference: true + pubid_class: 'Pubid::Iho::Identifier' + pubid_require: 'pubid' diff --git a/data-index/generated/iso_config.yml b/data-index/generated/iso_config.yml new file mode 100644 index 0000000..b589a08 --- /dev/null +++ b/data-index/generated/iso_config.yml @@ -0,0 +1,11 @@ +title: ISO Index +description: >- + Welcome to the ISO standards index site! +paginate: 100 +jekyll-index: + favicon: 'https://www.relaton.org/favicon.ico' + source: 'index-v2.yaml' + baseurl: 'https://raw.githubusercontent.com/relaton/relaton-data-iso/v2/' + add_type_to_reference: true + pubid_class: 'Pubid::Iso::Identifier' + pubid_require: 'pubid' diff --git a/data-index/generated/itu-r_config.yml b/data-index/generated/itu-r_config.yml new file mode 100644 index 0000000..75a9b90 --- /dev/null +++ b/data-index/generated/itu-r_config.yml @@ -0,0 +1,11 @@ +title: ITU-R Index +description: >- + Welcome to the ITU-R standards index site! +paginate: 100 +jekyll-index: + favicon: 'https://www.relaton.org/favicon.ico' + source: 'index-v2.yaml' + baseurl: 'https://raw.githubusercontent.com/relaton/relaton-data-itu-r/v2/' + add_type_to_reference: true + pubid_class: 'Pubid::Itu::Identifier' + pubid_require: 'pubid' diff --git a/data-index/generated/jcgm_config.yml b/data-index/generated/jcgm_config.yml new file mode 100644 index 0000000..d482be8 --- /dev/null +++ b/data-index/generated/jcgm_config.yml @@ -0,0 +1,11 @@ +title: JCGM Index +description: >- + Welcome to the JCGM standards index site! +paginate: 100 +jekyll-index: + favicon: 'https://www.relaton.org/favicon.ico' + source: 'index-v1.yaml' + baseurl: 'https://raw.githubusercontent.com/relaton/relaton-data-jcgm/main/' + add_type_to_reference: true + pubid_class: 'Pubid::Jcgm::Identifier' + pubid_require: 'pubid' diff --git a/data-index/generated/jis_config.yml b/data-index/generated/jis_config.yml new file mode 100644 index 0000000..6c39441 --- /dev/null +++ b/data-index/generated/jis_config.yml @@ -0,0 +1,11 @@ +title: JIS Index +description: >- + Welcome to the JIS standards index site! +paginate: 100 +jekyll-index: + favicon: 'https://www.relaton.org/favicon.ico' + source: 'index-v2.yaml' + baseurl: 'https://raw.githubusercontent.com/relaton/relaton-data-jis/v2/' + add_type_to_reference: true + pubid_class: 'Pubid::Jis::Identifier' + pubid_require: 'pubid' diff --git a/data-index/generated/nist_config.yml b/data-index/generated/nist_config.yml new file mode 100644 index 0000000..0a9a480 --- /dev/null +++ b/data-index/generated/nist_config.yml @@ -0,0 +1,11 @@ +title: NIST Index +description: >- + Welcome to the NIST standards index site! +paginate: 100 +jekyll-index: + favicon: 'https://www.relaton.org/favicon.ico' + source: 'index-v2.yaml' + baseurl: 'https://raw.githubusercontent.com/relaton/relaton-data-nist/v2/' + add_type_to_reference: true + pubid_class: 'Pubid::Nist::Identifier' + pubid_require: 'pubid' diff --git a/data-index/generated/oasis_config.yml b/data-index/generated/oasis_config.yml new file mode 100644 index 0000000..93bad39 --- /dev/null +++ b/data-index/generated/oasis_config.yml @@ -0,0 +1,9 @@ +title: OASIS Index +description: >- + Welcome to the OASIS standards index site! This is where you can find the information you need about the various standards developed and maintained by the OASIS open community. Explore the OASIS standards and learn how they can help you solve your business and technical challenges! +paginate: 100 +jekyll-index: + favicon: 'https://www.oasis-open.org/wp-content/uploads/2020/11/cropped-2-layers@3x-32x32.png' + source: 'index-v1.yaml' + baseurl: 'https://raw.githubusercontent.com/relaton/relaton-data-oasis/v2/' + add_type_to_reference: true diff --git a/data-index/generated/ogc_config.yml b/data-index/generated/ogc_config.yml new file mode 100644 index 0000000..f9e4a46 --- /dev/null +++ b/data-index/generated/ogc_config.yml @@ -0,0 +1,9 @@ +title: OGC Index +description: >- + Welcome to the OGC standards index site! +paginate: 100 +jekyll-index: + favicon: 'https://www.relaton.org/favicon.ico' + source: 'index-v1.yaml' + baseurl: 'https://raw.githubusercontent.com/relaton/relaton-data-ogc/v2/' + add_type_to_reference: true diff --git a/data-index/generated/oiml_config.yml b/data-index/generated/oiml_config.yml new file mode 100644 index 0000000..70f3398 --- /dev/null +++ b/data-index/generated/oiml_config.yml @@ -0,0 +1,11 @@ +title: OIML Index +description: >- + Welcome to the OIML standards index site! +paginate: 100 +jekyll-index: + favicon: 'https://www.relaton.org/favicon.ico' + source: 'index-v2.yaml' + baseurl: 'https://raw.githubusercontent.com/relaton/relaton-data-oiml/main/' + add_type_to_reference: true + pubid_class: 'Pubid::Oiml::Identifier' + pubid_require: 'pubid' diff --git a/data-index/generated/plateau_config.yml b/data-index/generated/plateau_config.yml new file mode 100644 index 0000000..4a6d7a3 --- /dev/null +++ b/data-index/generated/plateau_config.yml @@ -0,0 +1,11 @@ +title: PLATEAU Index +description: >- + Welcome to the PLATEAU standards index site! +paginate: 100 +jekyll-index: + favicon: 'https://www.relaton.org/favicon.ico' + source: 'index-v2.yaml' + baseurl: 'https://raw.githubusercontent.com/relaton/relaton-data-plateau/v2/' + add_type_to_reference: true + pubid_class: 'Pubid::Plateau::Identifier' + pubid_require: 'pubid' diff --git a/data-index/generated/rfcs_config.yml b/data-index/generated/rfcs_config.yml new file mode 100644 index 0000000..c579cd9 --- /dev/null +++ b/data-index/generated/rfcs_config.yml @@ -0,0 +1,9 @@ +title: RFC Index +description: >- + Welcome to the RFC standards index site! +paginate: 100 +jekyll-index: + favicon: 'https://www.relaton.org/favicon.ico' + source: 'index-v1.yaml' + baseurl: 'https://raw.githubusercontent.com/relaton/relaton-data-rfcs/v2/' + add_type_to_reference: true diff --git a/data-index/generated/rfcsubseries_config.yml b/data-index/generated/rfcsubseries_config.yml new file mode 100644 index 0000000..1195ce3 --- /dev/null +++ b/data-index/generated/rfcsubseries_config.yml @@ -0,0 +1,9 @@ +title: RFC Subseries Index +description: >- + Welcome to the RFC Subseries standards index site! +paginate: 100 +jekyll-index: + favicon: 'https://www.relaton.org/favicon.ico' + source: 'index-v1.yaml' + baseurl: 'https://raw.githubusercontent.com/relaton/relaton-data-rfcsubseries/v2/' + add_type_to_reference: true diff --git a/data-index/generated/w3c_config.yml b/data-index/generated/w3c_config.yml new file mode 100644 index 0000000..c1ac4b8 --- /dev/null +++ b/data-index/generated/w3c_config.yml @@ -0,0 +1,11 @@ +title: W3C Index +description: >- + Welcome to the World Wide Web Consortium standards index site! This is where you can find the information you need about the various standards developed and maintained by the W3C open community. +paginate: 100 +jekyll-index: + favicon: 'https://www.w3.org/assets/logos/w3c/w3c-no-bars.svg' + source: 'index-v1.yaml' + baseurl: 'https://raw.githubusercontent.com/relaton/relaton-data-w3c/v2/' + add_type_to_reference: true + pubid_class: 'Relaton::W3c::PubId' + pubid_require: 'relaton/w3c/pubid' diff --git a/data-index/generated/xsf_config.yml b/data-index/generated/xsf_config.yml new file mode 100644 index 0000000..63f26cf --- /dev/null +++ b/data-index/generated/xsf_config.yml @@ -0,0 +1,9 @@ +title: XSF Index +description: >- + Welcome to the XSF standards index site! +paginate: 100 +jekyll-index: + favicon: 'https://www.relaton.org/favicon.ico' + source: 'index-v1.yaml' + baseurl: 'https://raw.githubusercontent.com/relaton/relaton-data-xsf/v2/' + add_type_to_reference: true diff --git a/lib/data_index_config.rb b/lib/data_index_config.rb index 2f1442a..e3bf57c 100644 --- a/lib/data_index_config.rb +++ b/lib/data_index_config.rb @@ -10,6 +10,11 @@ class DataIndexConfig DEFAULT_CONFIG_PATH = File.expand_path("../data-index/configs.yml", __dir__).freeze + # Default GitHub project-pages host for relaton-data-* sites + # (https://relaton.github.io/relaton-data-/). Override with --base when a + # repo serves Pages from a custom domain. + PAGES_HOST = "https://relaton.github.io".freeze + attr_reader :defaults, :repos def self.load(path = DEFAULT_CONFIG_PATH) @@ -34,35 +39,82 @@ def render_repo(repo) end # Render the `_config.yml` text for a raw entry hash (merged with defaults). + # + # `favicon`, `description`, and `pubid_require` accept an optional per-entry + # override (used by the already-live ids/oasis/w3c, which keep their own + # branding + w3c's non-default `relaton/w3c/pubid` require); absent, they fall + # back to the shared default / templated value. def render(entry) display = entry.fetch("display") - baseurl = format(defaults.fetch("baseurl_template"), - repo: entry.fetch("repo"), branch: entry.fetch("branch")) - description = format(defaults.fetch("description_template"), display: display) lines = [ "title: #{display} Index", "description: >-", - " #{description}", + " #{description(entry)}", "paginate: #{defaults.fetch('paginate')}", "jekyll-index:", - " favicon: #{sq(defaults.fetch('favicon'))}", + " favicon: #{sq(favicon(entry))}", " source: #{sq(entry.fetch('source'))}", - " baseurl: #{sq(baseurl)}", + " baseurl: #{sq(baseurl(entry))}", " add_type_to_reference: true", ] pubid = pubid_class(entry) if pubid lines << " pubid_class: #{sq(pubid)}" - lines << " pubid_require: #{sq(defaults.fetch('pubid_require'))}" + lines << " pubid_require: #{sq(pubid_require(entry))}" end "#{lines.join("\n")}\n" end + # The GitHub Pages site URL for a repo (what should return 200 once the + # rollout lands). `base` overrides the default project-pages host. + def pages_url(repo, base: PAGES_HOST) + entry(repo) # validate the repo is known + "#{base.chomp('/')}/relaton-data-#{repo}/" + end + + # The raw index URL the theme plugin fetches at build time (`baseurl` + the + # published `source`). A 404 here is the usual reason a built site renders + # empty even when the Pages deploy itself is green. + def raw_index_url(repo) + e = entry(repo) + "#{baseurl(e)}#{e.fetch('source')}" + end + private + # The raw.githubusercontent baseurl for an entry (repo + real default branch). + def baseurl(entry) + format(defaults.fetch("baseurl_template"), + repo: entry.fetch("repo"), branch: entry.fetch("branch")) + end + + # Per-entry override or the shared default favicon. + def favicon(entry) + override(entry, "favicon") || defaults.fetch("favicon") + end + + # Per-entry override or the templated "Welcome to the ..." line. + def description(entry) + override(entry, "description") || + format(defaults.fetch("description_template"), display: entry.fetch("display")) + end + + # Per-entry override or the shared default pubid require (`pubid`). + def pubid_require(entry) + override(entry, "pubid_require") || defaults.fetch("pubid_require") + end + + # Read a per-entry string override, treating nil/blank as "not set". + def override(entry, key) + value = entry[key] + return nil if value.nil? || value.to_s.strip.empty? + + value + end + # YAML single-quoted scalar with proper escaping ('' for a literal quote). def sq(value) "'#{value.to_s.gsub("'", "''")}'" diff --git a/spec/check_data_pages_spec.rb b/spec/check_data_pages_spec.rb new file mode 100644 index 0000000..cd41d15 --- /dev/null +++ b/spec/check_data_pages_spec.rb @@ -0,0 +1,41 @@ +# Offline unit tests for the URL builders behind bin/check-data-pages. The live +# HTTP 200 check lives only in the executable (it needs the rollout to have +# landed); here we pin only the URL construction so the suite never touches the +# network. +require "data_index_config" + +RSpec.describe "DataIndexConfig Pages URLs" do + let(:config) { DataIndexConfig.load } + + describe "#pages_url" do + it "builds the GitHub project-pages URL for a repo" do + expect(config.pages_url("iso")) + .to eq("https://relaton.github.io/relaton-data-iso/") + end + + it "honors a custom --base host without doubling the slash" do + expect(config.pages_url("iso", base: "https://data.relaton.org/")) + .to eq("https://data.relaton.org/relaton-data-iso/") + end + + it "raises for an unknown repo" do + expect { config.pages_url("nope") }.to raise_error(ArgumentError, /unknown repo/) + end + end + + describe "#raw_index_url" do + it "joins the repo baseurl (real default branch) with the published source" do + expect(config.raw_index_url("iso")) + .to eq("https://raw.githubusercontent.com/relaton/relaton-data-iso/v2/index-v2.yaml") + end + + it "uses the repo's own default branch (adobe -> main) and source" do + expect(config.raw_index_url("adobe")) + .to eq("https://raw.githubusercontent.com/relaton/relaton-data-adobe/main/index-v2.yaml") + end + + it "uses index-v3 for iho" do + expect(config.raw_index_url("iho")).to end_with("/v2/index-v3.yaml") + end + end +end diff --git a/spec/cimas_data_pages_spec.rb b/spec/cimas_data_pages_spec.rb new file mode 100644 index 0000000..8f40841 --- /dev/null +++ b/spec/cimas_data_pages_spec.rb @@ -0,0 +1,79 @@ +# Guards the two-track Pages rollout against the "silent 404" class the cimas.yml +# `# data` comment warns about: the per-repo config (data-index/configs.yml) and the +# Cimas plumbing (cimas-config/cimas.yml) must agree on every target relaton-data-* +# repo. If a repo's `branch:` drifts between the two files, or its deploy.yml / +# Gemfile.deploy mapping goes missing, the reusable data-deploy.yml silently skips +# the Pages publish (it only deploys from the repo's real default branch) and the +# site 404s with nothing red in CI. This spec makes that drift a test failure. +require "data_index_config" + +RSpec.describe "configs.yml <-> cimas.yml consistency" do + repo_root = File.expand_path("..", __dir__) + + configs = DataIndexConfig.load + cimas = YAML.safe_load_file( + File.join(repo_root, "cimas-config/cimas.yml"), + ) + repositories = cimas.fetch("repositories") + data_group = cimas.fetch("groups").fetch("data") + + # Local (not a constant) so it stays scoped to this example group rather than + # leaking to top-level Object; the nested `it` blocks close over it. + deploy_mapping = { + ".github/workflows/deploy.yml" => "gh-actions/data/deploy.yml", + "Gemfile.deploy" => "gh-actions/data/Gemfile.deploy", + }.freeze + + configs.repos.each do |entry| + repo = entry.fetch("repo") + cimas_key = "relaton-data-#{repo}" + + context "relaton-data-#{repo}" do + it "has a repositories: entry in cimas.yml" do + expect(repositories).to have_key(cimas_key), + "configs.yml lists #{repo.inspect} but cimas.yml has no " \ + "#{cimas_key.inspect} entry to sync deploy.yml into" + end + + it "is listed in the cimas.yml `data` group" do + expect(data_group).to include(cimas_key) + end + + it "targets the same branch cimas.yml pushes to" do + # Both drive the default-branch publish gate: configs.yml's branch builds + # the raw baseurl; cimas.yml's branch is where deploy.yml lands. A mismatch + # publishes from one branch while the site is served from another -> 404. + expect(repositories.fetch(cimas_key).fetch("branch")) + .to eq(entry.fetch("branch")) + end + + it "maps both deploy.yml and Gemfile.deploy from the data templates" do + files = repositories.fetch(cimas_key).fetch("files") + deploy_mapping.each do |dest, src| + expect(files[dest]).to eq(src), + "expected #{cimas_key} to map #{dest} <- #{src}" + end + end + end + end + + it "every relaton-data-* repo in the `data` group with a deploy.yml is covered by configs.yml" do + # The reverse direction: a data repo that Cimas pushes deploy.yml into but that + # has no configs.yml row would deploy the theme with no per-repo _config.yml. + # Excludes are the deliberate non-index repos (see data-pages-rollout hand-off). + known = configs.repos.map { |e| "relaton-data-#{e['repo']}" } + # ietf gets deploy.yml but is deliberately not a Pages index (no document + # index published); every other data-group repo is covered by configs.yml, + # including the already-live ids/oasis/w3c now folded in. + excluded = %w[relaton-data-ietf] + deploys_pages = + data_group.select do |name| + files = repositories.fetch(name, {}).fetch("files", nil) || {} + files.key?(".github/workflows/deploy.yml") + end + uncovered = deploys_pages - known - excluded + expect(uncovered).to be_empty, + "these data repos get deploy.yml but have no configs.yml row: " \ + "#{uncovered.join(', ')}" + end +end diff --git a/spec/data_index_config_spec.rb b/spec/data_index_config_spec.rb index 7e33f9b..301115b 100644 --- a/spec/data_index_config_spec.rb +++ b/spec/data_index_config_spec.rb @@ -48,10 +48,38 @@ def jekyll_index(repo) .to eq("https://raw.githubusercontent.com/relaton/relaton-data-adobe/main/") end - it "applies one uniform favicon to every repo" do - favicons = config.repos.map { |e| jekyll_index(e["repo"])["favicon"] }.uniq - expect(favicons.size).to eq(1) - expect(favicons.first).to match(%r{\Ahttps://.+favicon}) + it "applies the default favicon to repos without an override" do + default_favicon = config.defaults.fetch("favicon") + overridden = %w[ids oasis w3c] + config.repos.reject { |e| overridden.include?(e["repo"]) }.each do |e| + expect(jekyll_index(e["repo"])["favicon"]).to eq(default_favicon) + end + end + + it "honors a per-repo favicon override (w3c)" do + expect(jekyll_index("w3c")["favicon"]) + .to eq("https://www.w3.org/assets/logos/w3c/w3c-no-bars.svg") + end + + it "honors a per-repo description override (ids)" do + parsed = YAML.safe_load(config.render_repo("ids")) + expect(parsed["description"]) + .to eq("Bibliographic data information for Internet-Drafts in Relaton format") + end + + it "templates the description for repos without an override (iso)" do + parsed = YAML.safe_load(config.render_repo("iso")) + expect(parsed["description"]).to eq("Welcome to the ISO standards index site!") + end + + it "honors a per-repo pubid_require override (w3c -> relaton/w3c/pubid)" do + ji = jekyll_index("w3c") + expect(ji["pubid_class"]).to eq("Relaton::W3c::PubId") + expect(ji["pubid_require"]).to eq("relaton/w3c/pubid") + end + + it "defaults pubid_require to 'pubid' when not overridden (iso)" do + expect(jekyll_index("iso")["pubid_require"]).to eq("pubid") end it "never emits a pubid_class with a leading '::' (const_get rejects it)" do @@ -83,12 +111,13 @@ def jekyll_index(repo) end describe "configs.yml data" do - it "covers exactly the 25 target repos with no duplicates" do + it "covers exactly the 28 repos with no duplicates" do repos = config.repos.map { |e| e["repo"] } - expect(repos.size).to eq(25) - expect(repos.uniq.size).to eq(25) + expect(repos.size).to eq(28) + expect(repos.uniq.size).to eq(28) expect(repos).to include("iso", "ieee", "jis", "adobe", "easc", "gost", "jcgm", "oiml") - expect(repos).not_to include("sdo", "ietf", "misc", "ids", "oasis", "w3c") + expect(repos).to include("ids", "oasis", "w3c") # already-live, folded in + expect(repos).not_to include("sdo", "ietf", "misc") end it "gives every entry the required fields" do diff --git a/spec/generated_configs_spec.rb b/spec/generated_configs_spec.rb new file mode 100644 index 0000000..375f75f --- /dev/null +++ b/spec/generated_configs_spec.rb @@ -0,0 +1,30 @@ +# Drift guard for the committed snapshot in data-index/generated/. Those files +# are the exact bytes a maintainer copies into each relaton-data-* repo as its +# `_config.yml`, so they must always equal the generator's current output. If +# configs.yml changes without regenerating (`bin/gen-data-index-config --out +# data-index/generated`), this fails and points at the stale file. +require "data_index_config" + +RSpec.describe "data-index/generated snapshot" do + config = DataIndexConfig.load + generated_dir = File.expand_path("../data-index/generated", __dir__) + + config.repos.each do |entry| + repo = entry.fetch("repo") + + it "generated/#{repo}_config.yml matches the generator output" do + path = File.join(generated_dir, "#{repo}_config.yml") + expect(File.exist?(path)).to be(true), + "missing #{path} — run bin/gen-data-index-config --out data-index/generated" + expect(File.read(path)).to eq(config.render_repo(repo)), + "#{repo}_config.yml is stale — regenerate the snapshot" + end + end + + it "contains exactly one *_config.yml per target repo (no stale files)" do + present = Dir.glob(File.join(generated_dir, "*_config.yml")) + .map { |p| File.basename(p, "_config.yml") }.sort + expected = config.repos.map { |e| e["repo"] }.sort + expect(present).to eq(expected) + end +end