1#!/usr/bin/env bash2# supergraph-check.sh — check the subgraph against the user's published3# supergraph with `rover subgraph check`.4#5# supergraph-check.sh [workspace-dir]6#7# The graphos target's evidence layer, supergraph_check. `evidence` runs it8# after the core layers; by hand it does the same and prints the same lines.9# The compose layer composes the subgraph alone. This one sends the rendered10# schema to GraphOS, which composes it with the variant's other subgraphs11# and runs the variant's configured checks (operations against recorded12# traffic, and lint, custom, proposal or downstream checks when the graph has13# them). Nothing is published: a check changes no variant.14#
77# Every line this script prints, with the key (should anything echo it)
78# replaced.
79say() {
80 local line="$*"
81 if [ -n "${APOLLO_KEY:-}" ]; then line="${line//"$APOLLO_KEY"/<redacted>}"; fi
82 printf '%s\n' "$line"
83}
84
85# The graph to check against, and the mode that chose it: an explicit
86# GRAPHOS_FACTORY_GRAPH_REF first, else APOLLO_GRAPH_REF when the user
87# switched automatic checks on. Nothing else reads either variable.
88case "${GRAPHOS_FACTORY_SUPERGRAPH_CHECK:-}" in
89 ""|auto) ;;
90 *)
91 echo "supergraph_check: GRAPHOS_FACTORY_SUPERGRAPH_CHECK is set to something other than auto, its only value — not checked against your supergraph (not_run)"
92 echo "supergraph_check: unset it, or set it to auto to check against \$APOLLO_GRAPH_REF on every run"
93 exit 3
94 ;;
95esac
96GRAPH_REF="" MODE="" FROM=""
97if [ -n "${GRAPHOS_FACTORY_GRAPH_REF:-}" ]; then
103 echo "supergraph_check: no graph to check against — set GRAPHOS_FACTORY_GRAPH_REF=<graph>@<variant> for this run (the agent asks you first), or GRAPHOS_FACTORY_SUPERGRAPH_CHECK=auto to check against \$APOLLO_GRAPH_REF on every run (not_run)"
104 echo "supergraph_check: a check sends the rendered schema to GraphOS and publishes nothing; APOLLO_GRAPH_REF alone does not start one"
105 exit 3
106fi
107# <graph>@<variant>, never a leading `-`, which rover would read as a flag.
108if ! [[ "$GRAPH_REF" =~ ^[A-Za-z0-9][A-Za-z0-9_-]*@[A-Za-z0-9_.-]+$ ]]; then
109 say "supergraph_check: $FROM is not <graph>@<variant> (a letter or digit first, then letters, digits, _ and - in the graph id; also . in the variant) — not checked against your supergraph (not_run)"
110 exit 3
111fi
112if [ -z "${APOLLO_KEY:-}" ]; then
113 echo "supergraph_check: APOLLO_KEY is not set — not checked against your supergraph (not_run)"
114 echo "supergraph_check: export your GraphOS API key as APOLLO_KEY in the environment the agent's commands inherit (your shell profile, or the shell you start it from)"
115 echo "supergraph_check: the key is yours: it stays in your environment, is never written to the workspace and is never printed"
116 exit 3
117fi
118
119command -v rover >/dev/null 2>&1 || { echo "supergraph_check: rover is not installed" >&2; exit 127; }
120command -v jq >/dev/null 2>&1 || { echo "supergraph_check: jq is not installed" >&2; exit 127; }
121
122# The core's scripts: $GRAPHOS_FACTORY_CORE_SCRIPTS first (what `evidence`
123# hands this script: the core the rest of the run used), else the copy
124# inside this skill (an installed skill carries one), else the one at the
128for c in "${GRAPHOS_FACTORY_CORE_SCRIPTS:-}" "$HERE/../graphos-factory-core/scripts" "$HERE/../../../graphos-factory-core/scripts"; do
129 if [ -n "$c" ] && [ -f "$c/resolve-bin.sh" ]; then CORE="$(cd "$c" && pwd)"; break; fi
130done
131if [ -z "$CORE" ]; then
132 echo "supergraph_check: GRAPHOS_FACTORY_CORE_SCRIPTS names no core scripts, and there are none beside $HERE or at the checkout root: the core scripts are not installed" >&2
133 exit 127
134fi
135# The product binary, refused (exit 78) when older than the pin.
153 say "supergraph_check: FAIL — the schema did not render: $(head -1 "$OUT/render.err")"
154 exit 1
155fi
156eval "$rendered"
157if grep -Eq 'baseURL:[[:space:]]*"[A-Za-z][A-Za-z0-9+.-]*://[^/"]*@' "$RENDERED_SCHEMA"; then
158 echo "supergraph_check: the base URL carries userinfo, so the schema was not sent to GraphOS — not checked against your supergraph (not_run)"
159 echo "supergraph_check: GraphOS keeps the schemas it checks; send the credential through AUTH_EXPR, not the URL"
160 exit 3
161fi
162if grep -Eiq 'baseURL:[[:space:]]*"[^"]*[?&]([^"=&]*(token|key|secret|passw|pwd|auth|sig|cred|jwt|bearer|session)[^"=&]*|([^"=&]*[^A-Za-z"=&])?pw([^A-Za-z"=&][^"=&]*)?)=' "$RENDERED_SCHEMA"; then
163 echo "supergraph_check: the base URL carries a query parameter named like a credential, so the schema was not sent to GraphOS — not checked against your supergraph (not_run)"
164 echo "supergraph_check: GraphOS keeps the schemas it checks; send the credential through AUTH_EXPR, not the URL"
165 exit 3
166fi
167
168ROVER_VERSION="$(rover --version 2>/dev/null | sed -n 's/^Rover \([0-9][^ ]*\).*/\1/p' | head -1)"
217 say "supergraph_check: FAIL — composes with $GRAPH_REF, but checks did not pass: ${failed:-$(jq -r '.error.message // "rover reported a failure"' "$JSON")}"
222 } | head -20 | while IFS= read -r l; do say "$l"; done
223 [ -z "$url" ] || say "supergraph_check: details: $url"
224 exit 1
225fi
226
227# An error with no check behind it: the graph ref, the key or the network.
228say "supergraph_check: rover subgraph check did not run the check: $(jq -r '.error.message // "no result"' "$JSON")${code:+ ($code)} — not checked against your supergraph (not_run)"