From c134bb72c83a5143f9bb43c77e91e5be53e16f5f Mon Sep 17 00:00:00 2001 From: Jacob Stephens Date: Fri, 25 Sep 2026 15:24:47 +0000 Subject: [PATCH 1/3] Run CI on ubuntu-24.04 and macos-26 Pin the format, lint and test job to ubuntu-24.04 and add a job that runs the test suite on a macos-26 Apple Silicon runner, the platforms 0.1.0 supports. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/ci.yml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e27cadf4b..99300a356 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,9 +5,10 @@ on: branches: [main] pull_request: +# The runner images are pinned to the platforms thirdshift supports. jobs: test: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v7 - uses: dtolnay/rust-toolchain@stable @@ -17,5 +18,13 @@ jobs: - run: cargo fmt --check - run: cargo clippy --all-targets -- -D warnings # The tests run the binary against real git and fake gh and claude - # (Python scripts in tests/fakes), all present on ubuntu-latest. + # (Python scripts in tests/fakes), all present on the runner image. + - run: cargo test + + test-macos: + runs-on: macos-26 + steps: + - uses: actions/checkout@v7 + - uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@v2 - run: cargo test From f4bea0cfc9c8d74661923e046331b7789151d960 Mon Sep 17 00:00:00 2001 From: Jacob Stephens Date: Fri, 25 Sep 2026 15:27:48 +0000 Subject: [PATCH 2/3] Resolve symlinks in the test scenario's temp root On macOS the temp directory is under /var, a symlink to /private/var, so paths git reports didn't match the ones the tests built. Co-Authored-By: Claude Opus 5.5 --- tests/support/mod.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/support/mod.rs b/tests/support/mod.rs index 684c1f6b8..778a51348 100644 --- a/tests/support/mod.rs +++ b/tests/support/mod.rs @@ -34,6 +34,9 @@ pub const REPO: &str = "widgets"; pub struct Scenario { root: TempDir, + /// `root`'s path with symlinks resolved, as git reports it: on macOS the + /// temp directory is under `/var`, a symlink to `/private/var`. + dir: PathBuf, } pub struct RunResult { @@ -57,7 +60,8 @@ impl Scenario { /// checked out, and an open issue #7. pub fn new() -> Self { let root = TempDir::new().unwrap(); - let scenario = Scenario { root }; + let dir = root.path().canonicalize().unwrap(); + let scenario = Scenario { root, dir }; for dir in ["home", "bin", "tmp", "work"] { fs::create_dir_all(scenario.path(dir)).unwrap(); } @@ -97,7 +101,7 @@ impl Scenario { } pub fn path(&self, relative: &str) -> PathBuf { - self.root.path().join(relative) + self.dir.join(relative) } pub fn launch_dir(&self) -> PathBuf { From 9b53d318df45d1f5ef20da130a2093b690692587 Mon Sep 17 00:00:00 2001 From: Jacob Stephens Date: Fri, 25 Sep 2026 15:31:44 +0000 Subject: [PATCH 3/3] Name the scenario's resolved temp root root It's what path() builds on; the TempDir is only kept to delete it. Co-Authored-By: Claude Opus 5.5 --- tests/support/mod.rs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/tests/support/mod.rs b/tests/support/mod.rs index 778a51348..3ceb21cc6 100644 --- a/tests/support/mod.rs +++ b/tests/support/mod.rs @@ -33,10 +33,11 @@ pub const OWNER: &str = "acme"; pub const REPO: &str = "widgets"; pub struct Scenario { - root: TempDir, - /// `root`'s path with symlinks resolved, as git reports it: on macOS the - /// temp directory is under `/var`, a symlink to `/private/var`. - dir: PathBuf, + /// Deletes the temp root when the scenario is dropped. + _temp_dir: TempDir, + /// The temp root's path with symlinks resolved, as git reports it: on + /// macOS the temp directory is under `/var`, a symlink to `/private/var`. + root: PathBuf, } pub struct RunResult { @@ -59,9 +60,12 @@ impl Scenario { /// An origin with one commit on `main`, a launch clone of it with `main` /// checked out, and an open issue #7. pub fn new() -> Self { - let root = TempDir::new().unwrap(); - let dir = root.path().canonicalize().unwrap(); - let scenario = Scenario { root, dir }; + let temp_dir = TempDir::new().unwrap(); + let root = temp_dir.path().canonicalize().unwrap(); + let scenario = Scenario { + _temp_dir: temp_dir, + root, + }; for dir in ["home", "bin", "tmp", "work"] { fs::create_dir_all(scenario.path(dir)).unwrap(); } @@ -101,7 +105,7 @@ impl Scenario { } pub fn path(&self, relative: &str) -> PathBuf { - self.dir.join(relative) + self.root.join(relative) } pub fn launch_dir(&self) -> PathBuf {