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

The self-hosted runner is 0.1.3: on Windows its tar calls keep drive paths local (--force-local), so packing a job's artifacts and unpacking actions and caches no longer fail with GNU tar reading C: as a host, which is what stopped the desktop release's Windows job.

syntaqxcommitted Parentd0fd07eBrowse files
4 files+28−60/4 viewed
+1−1
10961096
10971097 [[package]]
10981098 name = "g1t-runner"
1099−version = "0.1.2"
1099+version = "0.1.3"
11001100 dependencies = [
11011101 "anyhow",
11021102 "base64 0.22.1",
+1−1
11 [package]
22 name = "g1t-runner"
3−version = "0.1.2"
3+version = "0.1.3"
44 edition.workspace = true
55 license.workspace = true
66 description = "The program inside a g1t sandbox: runs an agent, checks, a catch-up merge, a review or a GitHub Actions job, and reports back. Also the self-hosted runner, g1t-runner register/run, on your own machines."
+21−3
315315 let fetched = self.fetch_to(artifact, &file).and_then(|format| {
316316 if format == "tgz" {
317317 std::fs::create_dir_all(into).map_err(|e| e.to_string())?;
318− let script = format!("tar -xzf {} -C {}", quote(&file.display().to_string()), quote(&into.display().to_string()));
318+ let script = format!("tar{} -xzf {} -C {}", tar_local(), quote(&file.display().to_string()), quote(&into.display().to_string()));
319319 if self.shell(&script) { Ok(()) } else { Err("it could not be unpacked".into()) }
320320 } else {
321321 zip::extract(&file, into).map(|_| ()).map_err(|e| format!("it could not be unpacked: {e}"))
558558 let lookup_only = with.get("lookup-only").is_some_and(|v| v == "true");
559559 let size = std::fs::metadata(&archive).map(|m| m.len()).unwrap_or(0);
560560 // tar finds out from the archive whether it is zstd or gzip.
561− if !lookup_only && !self.shell(&format!("tar -xPf {}", quote(&archive.display().to_string()))) {
561+ if !lookup_only && !self.shell(&format!("tar{} -xPf {}", tar_local(), quote(&archive.display().to_string()))) {
562562 self.log.line("##[warning]The cache was found but could not be unpacked.");
563563 }
564564 let _ = std::fs::remove_file(&archive);
896896 for f in \"${{found[@]}}\"; do if [ -e \"$f\" ]; then files+=(\"$f\"); fi; done; \
897897 if [ ${{#files[@]}} -eq 0 ]; then exit 3; fi; \
898898 if command -v zstd >/dev/null; then compress='zstd -T0 -3'; else compress=gzip; fi; \
899− tar -cPf {} -I \"$compress\" {} -- \"${{files[@]}}\"",
899+ tar{} -cPf {} -I \"$compress\" {} -- \"${{files[@]}}\"",
900900 includes.join(" "),
901+ tar_local(),
901902 quote(archive),
902903 excludes.join(" ")
903904 )
904905 }
905906
907+/// GNU tar on Windows reads `C:...` as a host and a file; `--force-local`
908+/// makes every path a local one. Elsewhere the flag is left off, since
909+/// bsdtar (macOS) doesn't know it.
910+pub(crate) fn tar_local() -> &'static str {
911+ if cfg!(windows) {
912+ " --force-local"
913+ } else {
914+ ""
915+ }
916+}
917+
906918 fn urlencode(text: &str) -> String {
907919 let mut out = String::new();
908920 for byte in text.bytes() {
940952 }
941953
942954 #[test]
955+ fn packing_keeps_windows_paths_local() {
956+ let script = pack_script(&["C:/w/target".into()], "C:/t/c.tar");
957+ assert_eq!(script.contains("--force-local"), cfg!(windows), "{script}");
958+ }
959+
960+ #[test]
943961 fn packing_expands_globs_and_leaves_exclusions_out() {
944962 let script = pack_script(&["/w/target/*/release".into(), "!/w/target/**/incremental".into()], "/t/c.tar");
945963 assert!(script.contains("found=( /w/target/*/release )"), "{script}");
+5−1
300300 let _ = std::fs::create_dir_all(&dir);
301301 let mut command = Command::new("tar");
302302 command.arg("-xzf").arg(&archive).arg("-C").arg(&dir).arg("--strip-components=1");
303+ if cfg!(windows) {
304+ // GNU tar on Windows reads `C:...` as a host and a file.
305+ command.arg("--force-local");
306+ }
303307 let mut commands = Commands::default();
304308 matches!(process::run(command, Duration::from_secs(300).min(self.remaining_time()), &mut self.log, &mut commands), Ok(Ended::Exited(0)))
305309 }
334338 }
335339 let _ = std::fs::create_dir_all(&dir);
336340 let url = format!("https://codeload.github.com/{owner}/{repo}/tar.gz/{}", sha.unwrap_or(git_ref));
337− let script = format!("set -o pipefail; curl -fsSL --retry 3 '{url}' | tar -xz -C '{}' --strip-components=1", dir.display());
341+ let script = format!("set -o pipefail; curl -fsSL --retry 3 '{url}' | tar{} -xz -C '{}' --strip-components=1", super::blobs::tar_local(), dir.display());
338342 let mut command = Command::new("bash");
339343 command.args(["-c", &script]);
340344 let mut commands = Commands::default();