Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

g1t.sh

Commit

A pushed annotated tag starts its push: tags workflows, for real this time (#55): pushing cli-v0.3.7 to flagon-io/g1t, with 4e63b3f7 live, published git.push for refs/tags/cli-v0.3.7 at a41bb238, the tag object, and no CLI release started. Artifacts logs nothing for an annotated tag's ref, so pushed_to took its "cannot read back, taken as pushed" path and announced the hash the push named; Actions then read .g1t/workflows at a tag object, found none, and started nothing. 4e63b3f7's tests had a store that reads an annotated tag back as its commit, which Artifacts does not. record_push now reads the store's ref advertisement once when a push has tags (refs.rs all, as releases and refs_of do): a tag is pushed when the advertisement has it at the hash pushed, and is announced at its peeled line (refs/tags/v1^{}), the commit, or at that hash for a lightweight tag; not there or left elsewhere is refused. An advertisement that cannot be read leaves each tag to the log check as before, with an error logged. Deploy: repos. Checked: cargo test -p g1t-repos (368, new: an annotated tag the store cannot log is announced at its peeled commit; lightweight, moved elsewhere and missing tags); cargo check -p g1t-repos --target wasm32-unknown-unknown.

G1t-Session:
ses_01m4zbw69vethr4vmwsmcpwe3n
syntaqxcommitted Parent960f565Browse files
2 files+57−100/2 viewed
+10−1
25762576 pushed.len()
25772577 );
25782578 }
2579+ // Where the store has the pushed tags, and an annotated tag's commit,
2580+ // from its ref advertisement: Artifacts logs nothing for an annotated
2581+ // tag's ref. Unread, each tag is checked by its log as before.
2582+ let advertised = if announced.iter().any(|pushed| pushed.branch().is_none()) {
2583+ let refs = async { refs::all(&stored.access(Scope::Read).await?).await }.await;
2584+ refs.inspect_err(|error| worker::console_error!("tags pushed to {} not read back: {error}", repo.name)).ok()
2585+ } else {
2586+ None
2587+ };
25792588 for pushed in announced {
25802589 // The store can refuse one ref and accept another, so each
25812590 // branch and tag is checked against where it actually is, and
25822591 // an annotated tag is announced at its commit (pushed.rs).
2583− let at = pushed::pushed_to(&stored, pushed).await?;
2592+ let at = pushed::pushed_to(&stored, pushed, advertised.as_deref()).await?;
25842593 let moved = at.is_some();
25852594 // How many commits a branch push brought (push_commits.rs), for
25862595 // the event and the person's contribution calendar. A log the
+47−9
4242 /// whose commit differs is taken as pushed unless what the push named is a
4343 /// commit itself, and is announced at that commit, as `git.push` says its
4444 /// `after` is. A tag the store cannot read back is taken as pushed.
45−pub(crate) async fn pushed_to<R: GitRepo>(git: &R, pushed: &crate::git_http::Pushed) -> Result<Option<String>> {
45+///
46+/// Artifacts does not read an annotated tag's ref back at all, so the push
47+/// of `cli-v0.3.7` was announced at its tag object (a41bb238) and Actions
48+/// found no workflows there. With the store's ref advertisement
49+/// (`advertised`, refs.rs `all`), a tag is where the advertisement has it
50+/// and is announced at its peeled line (`refs/tags/v1^{}`), the commit.
51+pub(crate) async fn pushed_to<R: GitRepo>(
52+ git: &R,
53+ pushed: &crate::git_http::Pushed,
54+ advertised: Option<&[(String, String)]>,
55+) -> Result<Option<String>> {
4656 if let Some(branch) = pushed.branch() {
4757 let head = git.log(branch, 1).await?;
4858 return Ok(head.first().filter(|commit| commit.hash == pushed.after).map(|_| pushed.after.clone()));
4959 }
60+ if let Some(refs) = advertised {
61+ let at = |name: &str| refs.iter().find(|(advertised, _)| advertised == name).map(|(_, hash)| hash.clone());
62+ return Ok(match at(&pushed.git_ref) {
63+ Some(hash) if hash == pushed.after => Some(at(&format!("{}^{{}}", pushed.git_ref)).unwrap_or(hash)),
64+ // Not there, or left elsewhere: the store refused it.
65+ _ => None,
66+ });
67+ }
5068 let Ok(head) = git.log(&pushed.git_ref, 1).await else {
5169 return Ok(Some(pushed.after.clone()));
5270 };
327345 // store reads the tag back as the commit it leads to, main's head.
328346 let git = with_refs(&[("main", "m2"), ("refs/tags/cli-v0.3.6", "m2")]);
329347 let tag = push("refs/tags/cli-v0.3.6", None, "accae3e8");
330− assert_eq!(run(pushed_to(&git, &tag)).unwrap().as_deref(), Some("m2"));
348+ assert_eq!(run(pushed_to(&git, &tag, None)).unwrap().as_deref(), Some("m2"));
331349 // Moved by a new tag object.
332350 let moved = push("refs/tags/cli-v0.3.6", Some("accae3e8"), "b0b0b0b0");
333− assert_eq!(run(pushed_to(&git, &moved)).unwrap().as_deref(), Some("m2"));
351+ assert_eq!(run(pushed_to(&git, &moved, None)).unwrap().as_deref(), Some("m2"));
352+ }
353+
354+ fn advertised(refs: &[(&str, &str)]) -> Vec<(String, String)> {
355+ refs.iter().map(|&(name, hash)| (name.to_owned(), hash.to_owned())).collect()
356+ }
357+
358+ #[test]
359+ fn an_annotated_tag_the_store_cannot_log_is_announced_at_its_peeled_commit() {
360+ // `git push g1t cli-v0.3.7`: Artifacts logs nothing for the tag's
361+ // ref, and its advertisement has the tag object and the peeled commit.
362+ let git = with_refs(&[("main", "m2")]);
363+ let refs = advertised(&[("refs/heads/main", "m2"), ("refs/tags/cli-v0.3.7", "a41bb238"), ("refs/tags/cli-v0.3.7^{}", "m1")]);
364+ let tag = push("refs/tags/cli-v0.3.7", None, "a41bb238");
365+ assert_eq!(run(pushed_to(&git, &tag, Some(&refs))).unwrap().as_deref(), Some("m1"));
366+ // A lightweight tag has no peeled line: it is its commit.
367+ let refs = advertised(&[("refs/tags/v1", "f2")]);
368+ assert_eq!(run(pushed_to(&git, &push("refs/tags/v1", None, "f2"), Some(&refs))).unwrap().as_deref(), Some("f2"));
369+ // Left elsewhere, or not there at all: refused.
370+ assert_eq!(run(pushed_to(&git, &push("refs/tags/v1", Some("f2"), "m1"), Some(&refs))).unwrap(), None);
371+ assert_eq!(run(pushed_to(&git, &push("refs/tags/v2", None, "m1"), Some(&refs))).unwrap(), None);
334372 }
335373
336374 #[test]
337375 fn a_lightweight_tag_is_announced_where_the_store_has_it() {
338376 let git = with_refs(&[("refs/tags/v1", "f2")]);
339− assert_eq!(run(pushed_to(&git, &push("refs/tags/v1", None, "f2"))).unwrap().as_deref(), Some("f2"));
377+ assert_eq!(run(pushed_to(&git, &push("refs/tags/v1", None, "f2"), None)).unwrap().as_deref(), Some("f2"));
340378 // The push named a commit the store did not move the tag to.
341− assert_eq!(run(pushed_to(&git, &push("refs/tags/v1", Some("f2"), "m1"))).unwrap(), None);
379+ assert_eq!(run(pushed_to(&git, &push("refs/tags/v1", Some("f2"), "m1"), None)).unwrap(), None);
342380 // A tag the store cannot read back is taken as pushed.
343− assert_eq!(run(pushed_to(&git, &push("refs/tags/v2", None, "m1"))).unwrap().as_deref(), Some("m1"));
381+ assert_eq!(run(pushed_to(&git, &push("refs/tags/v2", None, "m1"), None)).unwrap().as_deref(), Some("m1"));
344382 }
345383
346384 #[test]
347385 fn a_branch_is_announced_only_at_the_commit_pushed() {
348386 let git = with_refs(&[("main", "m2")]);
349− assert_eq!(run(pushed_to(&git, &push("refs/heads/main", Some("m1"), "m2"))).unwrap().as_deref(), Some("m2"));
350− assert_eq!(run(pushed_to(&git, &push("refs/heads/main", Some("m2"), "f2"))).unwrap(), None);
351− assert_eq!(run(pushed_to(&git, &push("refs/heads/gone", None, "f2"))).unwrap(), None);
387+ assert_eq!(run(pushed_to(&git, &push("refs/heads/main", Some("m1"), "m2"), None)).unwrap().as_deref(), Some("m2"));
388+ assert_eq!(run(pushed_to(&git, &push("refs/heads/main", Some("m2"), "f2"), None)).unwrap(), None);
389+ assert_eq!(run(pushed_to(&git, &push("refs/heads/gone", None, "f2"), None)).unwrap(), None);
352390 }
353391 }

Comments

Sign in to comment.