mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-10-08 03:10:26 +00:00
parent
dff39eb1f2
commit
e8990f7627
4 changed files with 609 additions and 200 deletions
648
run.json
648
run.json
File diff suppressed because one or more lines are too long
150
stages/007-simplify_gpt@1/diff.patch
Normal file
150
stages/007-simplify_gpt@1/diff.patch
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
diff --git a/lib/crates/fabro-config/src/legacy_sandbox_migration.rs b/lib/crates/fabro-config/src/legacy_sandbox_migration.rs
|
||||
index 4ed823128..b6b4c2515 100644
|
||||
--- a/lib/crates/fabro-config/src/legacy_sandbox_migration.rs
|
||||
+++ b/lib/crates/fabro-config/src/legacy_sandbox_migration.rs
|
||||
@@ -1,9 +1,11 @@
|
||||
#![expect(
|
||||
clippy::disallowed_methods,
|
||||
+ clippy::disallowed_types,
|
||||
reason = "temporary startup config migration uses synchronous file I/O before config is loaded"
|
||||
)]
|
||||
|
||||
use std::fmt;
|
||||
+use std::io::Write;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
|
||||
@@ -54,13 +56,7 @@ pub(crate) fn migrate_settings_path(
|
||||
.parse::<SettingsLayer>()
|
||||
.map_err(|err| Error::parse_file("Migrated settings file is invalid", path, err))?;
|
||||
|
||||
- let backup_path = next_backup_path(path);
|
||||
- std::fs::write(&backup_path, original_contents).map_err(|source| {
|
||||
- Error::other(format!(
|
||||
- "writing legacy sandbox migration backup {}: {source}",
|
||||
- backup_path.display()
|
||||
- ))
|
||||
- })?;
|
||||
+ let backup_path = write_next_backup(path, original_contents)?;
|
||||
std::fs::write(path, &next_contents).map_err(|source| {
|
||||
Error::other(format!(
|
||||
"writing migrated settings file {}: {source}",
|
||||
@@ -151,7 +147,14 @@ fn migrate_document(doc: &mut DocumentMut) -> std::result::Result<(), MigrationF
|
||||
}
|
||||
|
||||
let provider_str = sandbox.get("provider").and_then(Item::as_str);
|
||||
- let active_provider = provider_str.and_then(|s| EnvironmentProvider::from_str(s).ok());
|
||||
+ let active_provider = provider_str.and_then(|provider| {
|
||||
+ if let Ok(provider) = EnvironmentProvider::from_str(provider) {
|
||||
+ Some(provider)
|
||||
+ } else {
|
||||
+ unsupported.push("run.sandbox.provider".to_string());
|
||||
+ None
|
||||
+ }
|
||||
+ });
|
||||
if provider_str.is_none() {
|
||||
unsupported.push("run.sandbox.provider".to_string());
|
||||
}
|
||||
@@ -211,6 +214,8 @@ fn migrate_document(doc: &mut DocumentMut) -> std::result::Result<(), MigrationF
|
||||
}
|
||||
|
||||
if !unsupported.is_empty() {
|
||||
+ unsupported.sort();
|
||||
+ unsupported.dedup();
|
||||
return Err(MigrationFailure {
|
||||
unsupported_keys: unsupported,
|
||||
});
|
||||
@@ -418,19 +423,10 @@ fn remove_run_sandbox(doc: &mut DocumentMut) {
|
||||
}
|
||||
}
|
||||
|
||||
+#[cfg(test)]
|
||||
fn next_backup_path(path: &Path) -> PathBuf {
|
||||
- let file_name = path
|
||||
- .file_name()
|
||||
- .and_then(|name| name.to_str())
|
||||
- .expect("settings path always has a UTF-8 file name");
|
||||
- let base = path.with_file_name(format!("{file_name}.legacy-sandbox-migration.bak"));
|
||||
- if !base.exists() {
|
||||
- return base;
|
||||
- }
|
||||
-
|
||||
- for index in 1u32.. {
|
||||
- let candidate =
|
||||
- path.with_file_name(format!("{file_name}.legacy-sandbox-migration.{index}.bak"));
|
||||
+ for index in 0u32.. {
|
||||
+ let candidate = backup_path_for(path, index);
|
||||
if !candidate.exists() {
|
||||
return candidate;
|
||||
}
|
||||
@@ -438,6 +434,47 @@ fn next_backup_path(path: &Path) -> PathBuf {
|
||||
unreachable!("unbounded backup suffix search should return")
|
||||
}
|
||||
|
||||
+fn write_next_backup(path: &Path, contents: &str) -> Result<PathBuf> {
|
||||
+ for index in 0u32.. {
|
||||
+ let backup_path = backup_path_for(path, index);
|
||||
+ match std::fs::OpenOptions::new()
|
||||
+ .write(true)
|
||||
+ .create_new(true)
|
||||
+ .open(&backup_path)
|
||||
+ {
|
||||
+ Ok(mut file) => {
|
||||
+ file.write_all(contents.as_bytes()).map_err(|source| {
|
||||
+ Error::other(format!(
|
||||
+ "writing legacy sandbox migration backup {}: {source}",
|
||||
+ backup_path.display()
|
||||
+ ))
|
||||
+ })?;
|
||||
+ return Ok(backup_path);
|
||||
+ }
|
||||
+ Err(source) if source.kind() == std::io::ErrorKind::AlreadyExists => {}
|
||||
+ Err(source) => {
|
||||
+ return Err(Error::other(format!(
|
||||
+ "writing legacy sandbox migration backup {}: {source}",
|
||||
+ backup_path.display()
|
||||
+ )));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ unreachable!("unbounded backup suffix search should return")
|
||||
+}
|
||||
+
|
||||
+fn backup_path_for(path: &Path, index: u32) -> PathBuf {
|
||||
+ let file_name = path
|
||||
+ .file_name()
|
||||
+ .and_then(|name| name.to_str())
|
||||
+ .unwrap_or("settings.toml");
|
||||
+ if index == 0 {
|
||||
+ path.with_file_name(format!("{file_name}.legacy-sandbox-migration.bak"))
|
||||
+ } else {
|
||||
+ path.with_file_name(format!("{file_name}.legacy-sandbox-migration.{index}.bak"))
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use fabro_types::settings::InterpString;
|
||||
@@ -718,6 +755,22 @@ cpu_quota = 250000
|
||||
assert!(err.to_string().contains("run.sandbox.docker.cpu_quota"));
|
||||
}
|
||||
|
||||
+ #[test]
|
||||
+ fn unsupported_provider_value_is_reported_before_rewriting() {
|
||||
+ let err = migrate_contents(
|
||||
+ r#"
|
||||
+_version = 1
|
||||
+
|
||||
+[run.sandbox]
|
||||
+provider = "unknown"
|
||||
+"#,
|
||||
+ Path::new("settings.toml"),
|
||||
+ )
|
||||
+ .expect_err("unknown provider should fail migration");
|
||||
+
|
||||
+ assert!(err.to_string().contains("run.sandbox.provider"));
|
||||
+ }
|
||||
+
|
||||
#[test]
|
||||
fn explicit_skip_clone_false_is_accepted_as_default() {
|
||||
let migrated = migrate(
|
||||
6
stages/007-simplify_gpt@1/status.json
Normal file
6
stages/007-simplify_gpt@1/status.json
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"outcome": "succeeded",
|
||||
"notes": "Stage completed: simplify_gpt",
|
||||
"failure_reason": null,
|
||||
"timestamp": "2026-05-23T20:28:00.248895Z"
|
||||
}
|
||||
5
stages/008-verify@1/script_invocation.json
Normal file
5
stages/008-verify@1/script_invocation.json
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"script": "git fetch origin main 2>&1 && git merge --no-edit --no-stat origin/main 2>&1 && cargo +nightly-2026-04-14 fmt --all 2>&1 && cargo dev docs refresh 2>&1 && cargo +nightly-2026-04-14 fmt --check --all 2>&1 && ! rg -n 'AuthMode::Disabled|RunAuthMethod|RunSubjectProvenance|\\bActorRef\\b|\\bActorKind\\b|AuthenticatedSubject|AuthenticatedService|AuthorizeRunScoped|AuthorizeRunBlob|AuthorizeStageArtifact|AuthorizeCommandLog|auth_method\\s*==\\s*\"disabled\"' lib/crates apps lib/packages docs/public/api-reference/fabro-api.yaml 2>&1 && cargo +nightly-2026-04-14 clippy --workspace --all-targets -- -D warnings 2>&1 && cargo nextest run --workspace --status-level slow --profile ci 2>&1 && cargo dev docs check 2>&1 && bun install --frozen-lockfile 2>&1 && (cd apps/fabro-web && bun run typecheck) 2>&1 && (cd apps/fabro-web && bun run test) 2>&1 && (cd lib/packages/fabro-api-client && bun run typecheck) 2>&1 && cargo dev build -- -p fabro-cli --release 2>&1",
|
||||
"command": "exec 2>&1\ngit fetch origin main 2>&1 && git merge --no-edit --no-stat origin/main 2>&1 && cargo +nightly-2026-04-14 fmt --all 2>&1 && cargo dev docs refresh 2>&1 && cargo +nightly-2026-04-14 fmt --check --all 2>&1 && ! rg -n 'AuthMode::Disabled|RunAuthMethod|RunSubjectProvenance|\\bActorRef\\b|\\bActorKind\\b|AuthenticatedSubject|AuthenticatedService|AuthorizeRunScoped|AuthorizeRunBlob|AuthorizeStageArtifact|AuthorizeCommandLog|auth_method\\s*==\\s*\"disabled\"' lib/crates apps lib/packages docs/public/api-reference/fabro-api.yaml 2>&1 && cargo +nightly-2026-04-14 clippy --workspace --all-targets -- -D warnings 2>&1 && cargo nextest run --workspace --status-level slow --profile ci 2>&1 && cargo dev docs check 2>&1 && bun install --frozen-lockfile 2>&1 && (cd apps/fabro-web && bun run typecheck) 2>&1 && (cd apps/fabro-web && bun run test) 2>&1 && (cd lib/packages/fabro-api-client && bun run typecheck) 2>&1 && cargo dev build -- -p fabro-cli --release 2>&1",
|
||||
"language": "shell"
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue