diff --git a/src/main.rs b/src/main.rs index 46bca76..85bdf33 100644 --- a/src/main.rs +++ b/src/main.rs @@ -283,7 +283,19 @@ fn process_event( event: &Event, ) -> Result<(), String> { let event_path = dirs.queue.join(format!("{name}.event")); - let checkout_oid = checkout_oid(repo, event)?; + let checkout_oid = match checkout_oid(repo, event)? { + Some(checkout_oid) => Some(checkout_oid), + None if event.kind == EventKind::Delete => None, + None => { + eprintln!( + "sip: event {} new object {} does not resolve to a commit", + event_path.display(), + event.new + ); + move_event(&event_path, &dirs.failed, name)?; + return Ok(()); + } + }; let workflow = resolve_workflow(repo, protected_workflow_ref, checkout_oid.as_deref())?; let workflow_execution_id = format!("wf-{name}"); let manifest = render_manifest( @@ -354,7 +366,11 @@ fn checkout_oid(repo: &Path, event: &Event) -> Result, String> { } git_output( repo, - ["rev-parse", format!("{}^{{commit}}", event.new).as_str()], + [ + "rev-parse", + "--verify", + format!("{}^{{commit}}", event.new).as_str(), + ], ) } diff --git a/tests/integration.rc b/tests/integration.rc index 3537a0e..d30c5d1 100755 --- a/tests/integration.rc +++ b/tests/integration.rc @@ -333,6 +333,48 @@ fn test_malformed_event_is_failed { fail inconsistent event kind should move to failed queue } +fn test_non_delete_events_require_commit_checkout { + tmp=`{setup_pair} + src=$tmp^/src + remote=$tmp^/remote.git + + printf 'one\n' >$src^/README.md + git -C $src add README.md + git -C $src commit -m one >/dev/null || fail could not commit checkout validation fixture + commit=`{git -C $src rev-parse HEAD} + git -C $remote fetch $src HEAD:refs/heads/main >/dev/null >[2]/dev/null || fail could not install main fixture ref + + blob=`{printf 'blob\n' | git -C $remote hash-object -w --stdin} + missing=1111111111111111111111111111111111111111 + annotated=`{git -C $src tag -a annotated -m annotated && git -C $src rev-parse annotated} + git -C $remote fetch $src refs/tags/annotated:refs/tags/annotated >/dev/null >[2]/dev/null || fail could not install annotated tag fixture ref + + mkdir -p $remote^/sip/queue + printf '1\t0000000000000000000000000000000000000000\t%s\trefs/heads/missing\tactor\t1\tcreate\n' $missing >$remote^/sip/queue/missing.event + printf '1\t0000000000000000000000000000000000000000\t%s\trefs/heads/blob\tactor\t2\tcreate\n' $blob >$remote^/sip/queue/blob.event + printf '1\t0000000000000000000000000000000000000000\t%s\trefs/tags/light\tactor\t3\tcreate\n' $commit >$remote^/sip/queue/light.event + printf '1\t0000000000000000000000000000000000000000\t%s\trefs/tags/annotated\tactor\t4\tcreate\n' $annotated >$remote^/sip/queue/annotated.event + + $root^/bin/sip-worker.rc $remote >/dev/null || fail worker failed for checkout validation test + + if(! test -f $remote^/sip/failed/missing.event) + fail missing new object should move to failed queue + if(! test -f $remote^/sip/failed/blob.event) + fail blob new object should move to failed queue + if(! test -f $remote^/sip/done/light.event) + fail lightweight tag commit should move to done queue + if(! test -f $remote^/sip/done/annotated.event) + fail annotated tag should move to done queue + + run_count=`{git -C $remote for-each-ref '--format=%(refname)' refs/ci/runs | awk 'END { print NR }'} + assert_eq $run_count 2 'worker should create runs only for peelable tag events' + + git -C $remote cat-file -p refs/ci/runs/light >$tmp^/light.manifest + git -C $remote cat-file -p refs/ci/runs/annotated >$tmp^/annotated.manifest + assert_contains $tmp^/light.manifest checkout_oid=$commit 'lightweight tag checkout oid is commit' + assert_contains $tmp^/annotated.manifest checkout_oid=$commit 'annotated tag checkout oid peels to commit' +} + test_branch_tag_and_protected_refs test_no_workflow_repository test_protected_workflow_policy @@ -340,5 +382,6 @@ test_basic_wasm_workflow_declares_jobs test_unsafe_host_shell_executor_records_logs test_stale_events_do_not_overwrite_status test_malformed_event_is_failed +test_non_delete_events_require_commit_checkout echo ok - integration tests passed