1717# SPEC_COMPILE_LIMIT=N process only the first N alphabetically-sorted specs
1818# SPEC_COMPILE_PARSE_ONLY=1 skip cargo check; only verify the generator
1919# parses+emits without errors. Faster.
20+ # SPEC_COMPILE_FORCE_CHECK=1 also cargo check the specs in
21+ # GENERATE_ONLY_SPECS (see below), which are
22+ # skipped by default because their generated
23+ # crate exceeds CI runner memory.
2024# SPEC_COMPILE_TARGET_DIR=path shared cargo target dir for the scratch
2125# workspace (default tmp/spec-compile-target).
2226# Dependency artifacts (reqwest, chrono, …)
7882echo " [spec-compile] running ${# SPECS[@]} spec(s)"
7983echo
8084
85+ # Specs whose generated crate is too large to `cargo check` inside a standard
86+ # CI runner. They are still generated (which catches the majority of generator
87+ # defects); only the compile step is skipped, and the summary reports them
88+ # separately so a green run is never mistaken for full verification.
89+ #
90+ # Set SPEC_COMPILE_FORCE_CHECK=1 to check them anyway on a machine with the
91+ # headroom. Measured peaks, `cargo check`, single rustc process:
92+ # microsoft-graph 2.4M lines generated ~14.3 GB RSS (16,153 operations)
93+ # A GitHub-hosted ubuntu-latest runner has 16 GB total, so it is killed with
94+ # SIGTERM partway through. Raising cargo parallelism does not help — the memory
95+ # is one rustc type-checking one crate.
96+ GENERATE_ONLY_SPECS=(" microsoft-graph" )
97+
98+ is_generate_only () {
99+ [ " ${SPEC_COMPILE_FORCE_CHECK:- } " = " 1" ] && return 1
100+ for entry in " ${GENERATE_ONLY_SPECS[@]} " ; do
101+ [ " $entry " = " $1 " ] && return 0
102+ done
103+ return 1
104+ }
105+
106+ generate_only_reason () {
107+ case " $1 " in
108+ microsoft-graph) echo " ~14.3 GB RSS, exceeds CI runner memory" ;;
109+ * ) echo " exceeds CI runner resources" ;;
110+ esac
111+ }
112+
81113# ---- Phase 1: generate a scratch crate per spec -------------------------
82114passed=()
83115failed_gen=()
84116failed_check=()
85117skipped=()
118+ generate_only=()
86119gen_ok=()
87120for entry in " ${SPECS[@]} " ; do
88121 IFS=' |' read -r name spec_path <<< " $entry"
@@ -163,6 +196,11 @@ elif [ ${#gen_ok[@]} -gt 0 ]; then
163196 echo
164197 echo " [spec-compile] cargo check (${# gen_ok[@]} isolated manifest(s))..."
165198 for name in " ${gen_ok[@]} " ; do
199+ if is_generate_only " $name " ; then
200+ printf " %-30s GEN-ONLY (cargo check skipped: %s)\n" " $name " " $( generate_only_reason " $name " ) "
201+ generate_only+=(" $name " )
202+ continue
203+ fi
166204 log=" $ROOT /$name /check.log"
167205 if ( cd " $ROOT /$name " && CARGO_TARGET_DIR=" $SCRATCH_TARGET " cargo check $OFFLINE ) > " $log " 2>&1 ; then
168206 printf " %-30s PASS\n" " $name "
@@ -177,12 +215,21 @@ elif [ ${#gen_ok[@]} -gt 0 ]; then
177215fi
178216
179217echo
180- echo " [spec-compile] summary: ${# passed[@]} passed, ${# failed_gen[@]} gen-failed, ${# failed_check[@]} check-failed, ${# skipped[@]} skipped"
218+ echo " [spec-compile] summary: ${# passed[@]} passed, ${# failed_gen[@]} gen-failed, ${# failed_check[@]} check-failed, ${# generate_only[@]} generate-only, ${ # skipped[@]} skipped"
181219[ ${# failed_gen[@]} -gt 0 ] && echo " gen-fail: ${failed_gen[*]} "
182220[ ${# failed_check[@]} -gt 0 ] && echo " check-fail: ${failed_check[*]} "
183221[ ${# skipped[@]} -gt 0 ] && echo " skipped: ${skipped[*]} "
222+ if [ ${# generate_only[@]} -gt 0 ]; then
223+ echo " generate-only (NOT compile-verified): ${generate_only[*]} "
224+ echo " ^ these generated cleanly but were never compiled. Run them locally"
225+ echo " on a machine with enough RAM: scripts/spec-compile.sh ${generate_only[*]} "
226+ fi
184227
185228if [ ${# failed_gen[@]} -gt 0 ] || [ ${# failed_check[@]} -gt 0 ]; then
186229 exit 1
187230fi
188- echo " [spec-compile] ✅ all specs compiled cleanly"
231+ if [ ${# generate_only[@]} -gt 0 ]; then
232+ echo " [spec-compile] ✅ ${# passed[@]} spec(s) compiled cleanly; ${# generate_only[@]} generated but not compiled"
233+ else
234+ echo " [spec-compile] ✅ all specs compiled cleanly"
235+ fi
0 commit comments