Route both pipeline compile callers through Ci::compile
Ci::pipeline and trigger_ref each called source() then
pipeline::compile(&source, CI_FNL) directly, so the two paths could
drift on validation invariants. Add Ci::compile as the single chokepoint
and have both callers go through it.
Assisted-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
diff --git a/src/ci/mod.rs b/src/ci/mod.rs
index 9fe2d73..f96b851 100644
--- a/src/ci/mod.rs
+++ b/src/ci/mod.rs
@@ -68,9 +68,15 @@ impl Ci {
let Some(source) = self.source(&commit.sha)? else {
return Ok(None);
};
- let name = CI_FNL.to_string();
- let pipeline = pipeline::compile(&source, &name)?;
- Ok(Some(pipeline))
+ Ok(Some(self.compile(&source)?))
+ }
+
+ /// Compile `.quire/ci.fnl` source into a validated [`Pipeline`].
+ ///
+ /// Single chokepoint for compile + structural validation, used by
+ /// [`Ci::pipeline`] and `trigger_ref` so the two paths can't drift.
+ fn compile(&self, source: &str) -> error::Result<Pipeline> {
+ pipeline::compile(source, CI_FNL)
}
/// Read the contents of `.quire/ci.fnl` at a given commit SHA.
@@ -168,7 +174,7 @@ fn trigger_ref(
"created CI run"
);
- let pipeline = match pipeline::compile(&source, CI_FNL) {
+ let pipeline = match ci.compile(&source) {
Ok(p) => p,
Err(e) => {
run.transition(RunState::Active)?;