feat: release Dever 0.1.5 with direct workers and long transactions

This commit is contained in:
Codex committed 2026-10-11 11:17:33 +00:00
1 parent 89629c2197
commit a900d7e8db
153 files changed
+3676 -3708

No files matched your search

+112 -23
View File
@@ -17,8 +17,8 @@ mod daemon;
mod inputs;
#[path = "../../dever-tests/tests/support/process.rs"]
mod process;
#[path = "../../dever-tests/tests/support/sandbox.rs"]
mod sandbox;
#[path = "../../dever-tests/tests/support/process_runtime.rs"]
mod process_runtime;
use super::temp::TemporaryDirectory;
#[path = "ecosystem_acceptance.rs"]
@@ -147,11 +147,15 @@ fn author_inputs(author: &Path, workspace: &Path) -> Ed25519KeyPair {
),
);
}
let compiler = input(author, Path::new(env!("CARGO_BIN_EXE_dever")), "dever");
let compiler = input(
author,
&workspace.join("target/native-release-inputs/bin/dever"),
"dever",
);
let core_libraries = inputs::core_libraries()
.into_iter()
.map(|(name, source)| {
let mut value = input(author, &source, name);
let mut value = input(author, &source, &name);
value["path"] = json!(name);
value
})
@@ -171,11 +175,11 @@ fn author_inputs(author: &Path, workspace: &Path) -> Ed25519KeyPair {
.map(|name| links[*name].clone())
.collect::<Vec<_>>()
};
let sandbox = sandbox::assets(workspace).into_iter().map(|asset| {
let process_runtime = process_runtime::assets(workspace).into_iter().map(|asset| {
let relative = format!("inputs/{}", asset.path);
write(author, &relative, &asset.bytes);
fs::set_permissions(author.join(&relative), fs::Permissions::from_mode(if asset.executable { 0o755 } else { 0o644 })).unwrap();
json!({"source":relative, "path":asset.path.strip_prefix("sandbox/").unwrap(), "sha256":sha256_file(&author.join(&relative)).unwrap()})
json!({"source":relative, "path":asset.path.strip_prefix("process-runtime/").unwrap(), "sha256":sha256_file(&author.join(&relative)).unwrap()})
}).collect::<Vec<_>>();
write(
author,
@@ -193,7 +197,7 @@ fn author_inputs(author: &Path, workspace: &Path) -> Ed25519KeyPair {
"skill":[skill],
"start":ordered(&["crt1.o","crti.o","crtbeginT.o"]),
"libraries":ordered(&["libc.a","libm.a","libmvec.a","libgcc.a","libgcc_eh.a"]),
"end":ordered(&["crtend.o","crtn.o"]), "sandbox":sandbox
"end":ordered(&["crtend.o","crtn.o"]), "process_runtime":process_runtime
}))
.unwrap(),
);
@@ -211,10 +215,11 @@ fn isolated_os_command(root: &Path) -> Command {
}
fn isolated_os_namespace(root: &Path) -> Command {
let assets = Path::new(env!("CARGO_MANIFEST_DIR"))
.join("../../target/sandbox-inputs/assets")
.canonicalize()
.expect("prepare the explicit Linux isolation assets");
let isolator = PathBuf::from(
std::env::var_os("DEVER_TEST_ISOLATOR")
.expect("set an absolute test-only namespace isolator path"),
);
assert!(isolator.is_absolute());
let init = Path::new(env!("CARGO_MANIFEST_DIR"))
.join("../../target/debug/examples/native-acceptance-init")
.canonicalize()
@@ -222,10 +227,7 @@ fn isolated_os_namespace(root: &Path) -> Command {
let bytes = fs::read(&init).unwrap();
let executable = goblin::elf::Elf::parse(&bytes).unwrap();
assert!(executable.interpreter.is_none() && executable.libraries.is_empty());
// A plain chroot cannot create a nested user namespace. Use a real mount
// namespace root so the program can retain its normal Worker sandbox.
dever_sandbox::validate_bwrap(&fs::read(assets.join("bin/bwrap")).unwrap()).unwrap();
let mut command = Command::new(assets.join("bin/bwrap"));
let mut command = Command::new(isolator);
command
.env_clear()
.args([
@@ -301,6 +303,33 @@ fn application(root: &Path, profile: &str) {
"exercise() (okay: Bool) { dever.task.sleep(1)\n okay = true }\n"
};
write(root, "module/sample/value/app.dever", app);
if matches!(profile, "sqlite" | "both") {
write(
root,
"module/sample/value/api.dever",
"cmd exercise = app.exercise\nlong cmd stages = app.stages\n",
);
write(
root,
"module/sample/value/app.dever",
format!(
"{app}\nstages() (okay: Bool) {{ id = store()\n dever.task.sleep(1)\n okay = finish(id) }}\ntransaction store() (id: model.id) {{ saved = model.create({{ name = \"stage\" }})\n id = saved.id }}\ntransaction finish(id: model.id) (okay: Bool) {{ count = model.count()\n removed = model.delete(id)\n okay = count == 1 and removed == 1 }}\n"
),
);
}
}
#[test]
fn release_profile_projects_have_valid_source_contracts() {
for profile in PROFILES {
let project = TemporaryDirectory::new();
application(project.path(), profile);
command(
Command::new(env!("CARGO_BIN_EXE_dever"))
.arg("check")
.arg(project.path()),
);
}
}
fn assert_response(output: Output) {
@@ -489,7 +518,7 @@ fn signed_core_builds_without_host_compiler_libraries_or_tools() {
#[test]
#[ignore = "requires four optimized archives and component-fixture; starts only an owned daemon, SQLite and exec Worker fixtures"]
fn optimized_profiles_make_reproducible_signed_release_and_run_through_daemon() {
let workspace = Path::new(env!("CARGO_MANIFEST_DIR")).join("../..");
let workspace = inputs::workspace();
let profiles = archive_report(&workspace);
let author = TemporaryDirectory::new();
let key = author_inputs(author.path(), &workspace);
@@ -505,7 +534,7 @@ fn optimized_profiles_make_reproducible_signed_release_and_run_through_daemon()
let version = Version::parse(env!("CARGO_PKG_VERSION")).unwrap();
let release = layout.downloads().join(version.as_str());
command(
Command::new(workspace.join("target/debug/examples/native-release"))
Command::new(workspace.join("target/native-release-inputs/bin/native-release"))
.arg(author.path())
.arg("--output")
.arg(&release),
@@ -523,10 +552,13 @@ fn optimized_profiles_make_reproducible_signed_release_and_run_through_daemon()
fs::remove_dir_all(&release).unwrap();
drop(author);
let compiler = layout.versions().join(version.as_str()).join("dever-core");
let mut daemon = daemon::TestDaemon::start(&layout);
let mut daemon = daemon::TestDaemon::start_with_executable(
&layout,
&workspace.join("target/native-release-inputs/bin/deverd"),
);
let projects = TemporaryDirectory::new();
let mut binaries = serde_json::Map::new();
let mut programs: Vec<(PathBuf, PathBuf)> = Vec::new();
let mut programs = Vec::new();
for profile in PROFILES {
let project = projects.path().join(profile);
application(&project, profile);
@@ -538,6 +570,15 @@ fn optimized_profiles_make_reproducible_signed_release_and_run_through_daemon()
"{}",
]),
));
if matches!(profile, "sqlite" | "both") {
assert_response(command(
Command::new(&compiler).arg("run").arg(&project).args([
"--",
"sample.value.stages",
"{}",
]),
));
}
let executable = project.join("program");
command(
Command::new(&compiler)
@@ -547,7 +588,7 @@ fn optimized_profiles_make_reproducible_signed_release_and_run_through_daemon()
.arg(&executable),
);
binaries.insert(profile.into(), json!({"bytes":fs::metadata(&executable).unwrap().len(),"sha256":sha256_file(&executable).unwrap()}));
programs.push((project, executable));
programs.push((profile, project, executable));
}
assert_eq!(cache_status(&layout).unwrap().entries, 4);
let exec_project = TemporaryDirectory::new();
@@ -595,19 +636,25 @@ fn optimized_profiles_make_reproducible_signed_release_and_run_through_daemon()
"managed_run": true, "standalone_run": true,
"source_project_removed": true, "response": 7
});
for (project, executable) in programs {
for (profile, project, executable) in programs {
fs::remove_dir_all(project.join("module")).unwrap();
assert_response(command(
Command::new(executable).args(["sample.value.exercise", "{}"]),
Command::new(&executable).args(["sample.value.exercise", "{}"]),
));
if matches!(profile, "sqlite" | "both") {
assert_response(command(
Command::new(executable).args(["sample.value.stages", "{}"]),
));
}
}
let report = json!({
"format":"dever-native-release-acceptance-v1", "platform":"linux-x86_64",
"version":version.as_str(), "profiles":profiles,"programs":binaries,"exec":exec,
"manifest_sha256":format!("{:x}", sha2::Sha256::digest(&manifest)),
"checks":{"pack_determinism":true,"signed_install":true,"managed_profiles":4,"standalone_profiles":4,"sqlite_crud":true,"signed_exec_worker":true},
"checks":{"pack_determinism":true,"signed_install":true,"managed_profiles":4,"standalone_profiles":4,"sqlite_crud":true,"long_staged_transactions":true,"signed_exec_worker":true},
"postgres_server":"not_run", "cross_host_source_reproducibility":"not_run"
});
retain_candidate(&layout, &version, "native", &report);
use sha2::Digest;
write(
&workspace,
@@ -615,3 +662,45 @@ fn optimized_profiles_make_reproducible_signed_release_and_run_through_daemon()
serde_json::to_vec_pretty(&report).unwrap(),
);
}
fn retain_candidate(layout: &Layout, version: &Version, name: &str, report: &Value) {
let Some(destination) = std::env::var_os("DEVER_NATIVE_ACCEPTANCE_OUTPUT") else {
return;
};
let destination = PathBuf::from(destination);
assert!(destination.is_absolute());
fs::create_dir_all(&destination).unwrap();
let destination = destination.join(name);
fs::create_dir(&destination).unwrap();
let payload = destination.join("release");
let resources = dever_cli::toolchain::SignedResources::load(layout, version).unwrap();
let manifest = resources.manifest();
for artifact in manifest.artifacts.iter().chain(
manifest
.extensions
.iter()
.flat_map(|extension| &extension.artifacts),
) {
let output = payload.join(&artifact.path);
fs::create_dir_all(output.parent().unwrap()).unwrap();
fs::copy(resources.path(&artifact.path).unwrap(), &output).unwrap();
assert_eq!(sha256_file(&output).unwrap(), artifact.sha256);
}
for file in ["manifest.json", "manifest.sig"] {
fs::copy(
layout.versions().join(version.as_str()).join(file),
payload.join(file),
)
.unwrap();
}
fs::copy(
layout.state().join("trusted-release-key"),
destination.join("test-release.pub"),
)
.unwrap();
fs::write(
destination.join("verification.json"),
serde_json::to_vec_pretty(report).unwrap(),
)
.unwrap();
}