Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Cache cargo registry + target
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: |
~/.cargo/registry
Expand All @@ -38,9 +38,9 @@ jobs:
needs: build
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Cache cargo registry + target
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: |
~/.cargo/registry
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
Expand All @@ -41,7 +41,7 @@ jobs:
run: cp rust/target/${{ matrix.target }}/release/s5d ${{ matrix.binary }}

- name: Upload artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: ${{ matrix.binary }}
path: ${{ matrix.binary }}
Expand All @@ -51,10 +51,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@v7

- name: Create release
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@v3
with:
prerelease: ${{ contains(github.ref_name, '-') }}
files: |
Expand Down
Binary file removed bin/s5d
Binary file not shown.
Binary file modified bin/s5d-darwin-arm64
Binary file not shown.
6 changes: 5 additions & 1 deletion rust/src/bin/s5d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ mod cmd_provision;
mod cmd_skill;

#[derive(Parser)]
#[command(name = "s5d", about = "S5D — control plane for agentic repo changes")]
#[command(
name = "s5d",
version,
about = "S5D — control plane for agentic repo changes"
)]
struct Cli {
#[command(subcommand)]
command: S5dCommand,
Expand Down
40 changes: 30 additions & 10 deletions rust/src/bin/s5d/cmd_provision.rs
Original file line number Diff line number Diff line change
Expand Up @@ -487,17 +487,37 @@ fn install_binary_from_repo(
repo_root: &std::path::Path,
destination: &std::path::Path,
) -> anyhow::Result<()> {
let source = if let Some(prebuilt) = prebuilt_binary(repo_root) {
prebuilt
} else {
let status = std::process::Command::new("cargo")
.args(["build", "--release"])
.current_dir(repo_root.join("rust"))
.status()?;
if !status.success() {
anyhow::bail!("cargo build --release failed");
// Build from the checked-out source first: it always matches the repo
// revision. The tracked prebuilt is refreshed only at release time and
// has shipped stale binaries silently (alpha.7 → alpha.8 both lagged) —
// it is a fallback ONLY for hosts without a Rust toolchain. A failed
// build on a host that HAS cargo is an error, not a fallback: silently
// installing a lagging prebuilt over broken source recreates the very
// divergence this path exists to prevent. The explicit --target-dir
// pins the output location regardless of CARGO_TARGET_DIR/config.
let cargo_build = std::process::Command::new("cargo")
.args(["build", "--release", "--target-dir", "target"])
.current_dir(repo_root.join("rust"))
.status();
let source = match cargo_build {
Ok(status) if status.success() => repo_root.join("rust/target/release/s5d"),
Ok(status) => anyhow::bail!(
"cargo build --release failed ({status}) — fix the build; refusing to install a prebuilt over broken source"
),
Err(e) => {
let reason = format!("cargo unavailable ({e})");
match prebuilt_binary(repo_root) {
Some(prebuilt) => {
eprintln!(
" warn: {} — installing tracked prebuilt {} (may lag the repo revision)",
reason,
prebuilt.display()
);
prebuilt
}
None => anyhow::bail!("{} and no tracked prebuilt for this platform", reason),
}
}
repo_root.join("rust/target/release/s5d")
};

if let Some(parent) = destination.parent() {
Expand Down