provisioning-catalog/scripts/check-pinned-versions.nu

51 lines
2.3 KiB
Text

#!/usr/bin/env nu
# scripts/check-pinned-versions.nu — L3 (versions-from-lock) check.
#
# For each covered component, verifies that nickel/version.ncl's declared
# `version.current` tag actually exists at `version.source` (a real registry
# query via skopeo) — ADR-056: accredited, not generated. Scoped narrowly to the
# components remediated so far (zot, forgejo); NOT a generic scan of every
# component with a rich version.ncl — that needs integration with the existing
# staleness-cache subsystem (core/nulib/domain/cache/) to avoid hammering
# registries on every check, deliberately deferred (see
# provisioning/.coder/2026-07-03_laws-catalogo-provisioning.plan.md §11).
#
# Exit 0: every covered component's pinned tag exists at its source. Exit 1: a
# tag was not found, or its version.ncl could not be read.
def main []: nothing -> nothing {
let covered = ["zot", "forgejo"]
let results = ($covered | each {|component|
let version_path = $"components/($component)/nickel/version.ncl"
let export_result = (do { ^nickel export $version_path --format json } | complete)
if ($export_result.exit_code != 0) {
{component: $component, ok: false, detail: $"failed to export ($version_path)"}
} else {
let data = ($export_result.stdout | from json)
let current = $data.version.current
let source = $data.version.source
let tags_result = (do { ^skopeo list-tags $"docker://($source)" } | complete)
if ($tags_result.exit_code != 0) {
{component: $component, ok: false, detail: $"skopeo list-tags failed for ($source)"}
} else {
let tags = ($tags_result.stdout | from json | get Tags)
if ($current in $tags) {
{component: $component, ok: true, detail: $"($current) found at ($source)"}
} else {
{component: $component, ok: false, detail: $"($current) NOT found at ($source)"}
}
}
}
})
$results | each {|r|
let mark = (if $r.ok { "OK" } else { "FAIL" })
print ("[" + $mark + "] " + $r.component + ": " + $r.detail)
}
let failed = ($results | where ok == false)
if ($failed | is-not-empty) {
exit 1
}
}