mirror of
https://github.com/hanzoai/ci.git
synced 2026-10-20 15:28:05 +00:00
Hanzo CI/CD / test (linux-amd64) (push) Successful in 3m47s
Hanzo CI/CD / test (linux-arm64) (push) Successful in 8m51s
Hanzo CI/CD / cicd (push) Successful in 1m37s
CI/CD / gate (push) Successful in 12m40s
A static export inlines its ingest key at build just as an image bakes one, but only images[] were read, so a site had no way to take a pk- key from KMS and fell back to committing a literal. Claude-Session: https://claude.ai/code/session_01TUxvfuta1Z44KVNYuAz71F
47 lines
2.5 KiB
Bash
Executable File
47 lines
2.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# publishable — refuse a `build_secrets` name that does not declare itself public.
|
|
#
|
|
# Usage: publishable <hanzo.yml> (reads images[], site and sites[] build_secrets, rc=1 on refusal)
|
|
#
|
|
# WHY A NAME AND NOT A VALUE. A build_secret is handed to buildx as
|
|
# `--build-arg NAME=value`, and a build-arg is IN THE PUBLISHED IMAGE: `docker
|
|
# history` prints it to anyone who can pull. So the only value that may sit
|
|
# here is one that is public on purpose — a Vite/Next static export has no
|
|
# server to read an env from, so its ingest key must be inlined at build, and
|
|
# inlining it is what publishing it means.
|
|
#
|
|
# The value cannot be the test. At the moment ci reads hanzo.yml the value does
|
|
# not exist yet (KMS has not been called), and guessing secrecy from a string's
|
|
# shape is a heuristic that is wrong in both directions. The name is what a
|
|
# reviewer reads, it is in git, and it is decided by the person who knows the
|
|
# answer. So the name carries the assertion.
|
|
#
|
|
# The fleet had already started saying it this way — hanzoai/docs renamed
|
|
# EVENT_INGEST_KEY -> PUBLISHABLE_KEY, and hanzoai/world's four are VITE_*,
|
|
# which a bundler inlines by construction. This turns that convention into the
|
|
# mechanism. Before it, the ONE repo whose value is genuinely publishable
|
|
# (hanzoai/ui, a `pk-…` key) asserted the prefix inside its own Dockerfile, so
|
|
# the check existed once, for one image, and any repo adding a real credential
|
|
# got no check at all.
|
|
set -uo pipefail
|
|
|
|
f=${1:-hanzo.yml}
|
|
[ -r "$f" ] || exit 0 # no config, nothing declared, nothing to refuse
|
|
|
|
names=$(yq -r '[(.images // [])[] | (.build_secrets // [])[]] + (.site.build_secrets // []) + [(.sites // [])[] | (.build_secrets // [])[]] | unique | .[]' "$f" 2>/dev/null) || exit 0
|
|
[ -n "$names" ] || exit 0
|
|
|
|
rc=0
|
|
for n in $names; do
|
|
case "$n" in
|
|
# Prefixes a bundler already treats as client-side, plus an explicit
|
|
# self-declaration for everything else. Anything outside this set has not
|
|
# claimed to be public, so it is not baked.
|
|
PUBLISHABLE_*|PUBLIC_*|NEXT_PUBLIC_*|EXPO_PUBLIC_*|NUXT_PUBLIC_*|VITE_*|REACT_APP_*|*_PUBLISHABLE|*_PUBLIC) ;;
|
|
*)
|
|
echo "::error::build_secret '$n' does not declare itself publishable, and a build_secret is baked into the image as a --build-arg where \`docker history\` reveals it. Rename it (PUBLISHABLE_*, PUBLIC_*, NEXT_PUBLIC_*, VITE_*, REACT_APP_*) if the value is public on purpose; if it is a real credential it cannot be a build_secret at all." >&2
|
|
rc=1 ;;
|
|
esac
|
|
done
|
|
exit $rc
|