Update public bundle metadata contract
This commit is contained in:
parent
c4d8d94f49
commit
c4141e0dee
6 changed files with 204 additions and 5 deletions
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"kind": "disasmer-filtered-public-tree",
|
||||
"source_commit": "3313653a3d00fcd3fa5613e12cde2f76ae9a8ad0",
|
||||
"release_name": "dryrun-3313653a3d00",
|
||||
"source_commit": "b2b2e4a1b7c94ccc39c4d8cdfca6e98928fe2185",
|
||||
"release_name": "dryrun-b2b2e4a1b7c9",
|
||||
"filtered_out": [
|
||||
"private/**",
|
||||
"experiments/**",
|
||||
|
|
|
|||
|
|
@ -4316,8 +4316,11 @@ fn bundle_inspection(args: BundleInspectArgs, cwd: PathBuf) -> Result<BundleInsp
|
|||
let identity_inputs = BundleIdentityInputs {
|
||||
wasm_code: wasm_source_proxy_digest(&selected_inputs),
|
||||
task_abi: task_abi_digest(&model),
|
||||
entrypoints: model.entrypoints.keys().cloned().collect(),
|
||||
default_entrypoint: model.default_entrypoint.clone(),
|
||||
environments: model.environments.clone(),
|
||||
source_provider_manifest: source_provider_manifest.digest.clone(),
|
||||
source_transfer_policy: source_provider_manifest.transfer_policy.clone(),
|
||||
selected_inputs,
|
||||
};
|
||||
let pre_schedule_diagnostics = pre_schedule_diagnostics(
|
||||
|
|
@ -5951,12 +5954,18 @@ mod tests {
|
|||
fn bundle_inspect_discovers_environments_selected_inputs_and_source_providers() {
|
||||
let temp = tempfile::tempdir().unwrap();
|
||||
fs::create_dir_all(temp.path().join("envs/linux")).unwrap();
|
||||
fs::create_dir_all(temp.path().join("envs/docker")).unwrap();
|
||||
fs::create_dir_all(temp.path().join("src")).unwrap();
|
||||
fs::write(
|
||||
temp.path().join("envs/linux/Containerfile"),
|
||||
"FROM alpine\n",
|
||||
)
|
||||
.unwrap();
|
||||
fs::write(
|
||||
temp.path().join("envs/docker/Dockerfile"),
|
||||
"FROM debian:stable-slim\n",
|
||||
)
|
||||
.unwrap();
|
||||
fs::write(temp.path().join("Cargo.toml"), "[package]\nname='demo'\n").unwrap();
|
||||
fs::write(temp.path().join("src/main.rs"), "fn main() {}\n").unwrap();
|
||||
|
||||
|
|
@ -6003,7 +6012,62 @@ mod tests {
|
|||
.transfer_policy
|
||||
.default_full_repo_tarball
|
||||
);
|
||||
assert_eq!(inspection.metadata.environments[0].name, "linux");
|
||||
assert!(inspection
|
||||
.metadata
|
||||
.environments
|
||||
.iter()
|
||||
.any(|environment| environment.name == "linux"));
|
||||
assert!(inspection
|
||||
.metadata
|
||||
.environments
|
||||
.iter()
|
||||
.any(|environment| environment.name == "docker"));
|
||||
assert_eq!(
|
||||
inspection.metadata.source_metadata.source_provider_manifest,
|
||||
inspection.source_provider_manifest.digest
|
||||
);
|
||||
assert!(
|
||||
inspection
|
||||
.metadata
|
||||
.source_metadata
|
||||
.transfer_policy
|
||||
.local_source_bytes_remain_node_local
|
||||
);
|
||||
assert!(
|
||||
!inspection
|
||||
.metadata
|
||||
.source_metadata
|
||||
.transfer_policy
|
||||
.coordinator_receives_source_bytes_by_default
|
||||
);
|
||||
assert!(
|
||||
!inspection
|
||||
.metadata
|
||||
.source_metadata
|
||||
.transfer_policy
|
||||
.default_full_repo_tarball
|
||||
);
|
||||
assert!(inspection
|
||||
.metadata
|
||||
.task_metadata
|
||||
.entrypoints
|
||||
.contains(&"build".to_owned()));
|
||||
assert_eq!(
|
||||
inspection.metadata.task_metadata.default_entrypoint,
|
||||
"build"
|
||||
);
|
||||
assert_eq!(
|
||||
inspection.metadata.task_metadata.task_abi,
|
||||
task_abi_digest(&ProjectModel::discover_without_config(temp.path()).unwrap())
|
||||
);
|
||||
assert!(inspection
|
||||
.metadata
|
||||
.wasm_code
|
||||
.as_str()
|
||||
.starts_with("sha256:"));
|
||||
assert!(inspection.metadata.debug_metadata.available);
|
||||
assert!(inspection.metadata.debug_metadata.source_level_breakpoints);
|
||||
assert!(inspection.metadata.debug_metadata.variables_pane_supported);
|
||||
assert!(!inspection.metadata.embeds_full_container_images);
|
||||
assert!(inspection
|
||||
.metadata
|
||||
|
|
@ -7567,6 +7631,33 @@ mod tests {
|
|||
.as_str()
|
||||
.unwrap()
|
||||
.starts_with("sha256:"));
|
||||
assert!(report["bundle"]["metadata"]["wasm_code"]
|
||||
.as_str()
|
||||
.unwrap()
|
||||
.starts_with("sha256:"));
|
||||
assert_eq!(
|
||||
report["bundle"]["metadata"]["task_metadata"]["default_entrypoint"],
|
||||
"build"
|
||||
);
|
||||
assert!(report["bundle"]["metadata"]["task_metadata"]["entrypoints"]
|
||||
.as_array()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.any(|entrypoint| entrypoint == "release"));
|
||||
assert_eq!(
|
||||
report["bundle"]["metadata"]["source_metadata"]["transfer_policy"]
|
||||
["coordinator_receives_source_bytes_by_default"],
|
||||
false
|
||||
);
|
||||
assert_eq!(
|
||||
report["bundle"]["metadata"]["source_metadata"]["transfer_policy"]
|
||||
["default_full_repo_tarball"],
|
||||
false
|
||||
);
|
||||
assert_eq!(
|
||||
report["bundle"]["metadata"]["debug_metadata"]["dap_virtual_process"],
|
||||
true
|
||||
);
|
||||
assert_eq!(report["status"], "built");
|
||||
assert_eq!(report["scheduled_work"], false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{Digest, EnvironmentResource};
|
||||
use crate::{Digest, EnvironmentResource, SourceTransferPolicy};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct SelectedInput {
|
||||
|
|
@ -12,19 +12,49 @@ pub struct SelectedInput {
|
|||
pub struct BundleIdentityInputs {
|
||||
pub wasm_code: Digest,
|
||||
pub task_abi: Digest,
|
||||
pub entrypoints: Vec<String>,
|
||||
pub default_entrypoint: String,
|
||||
pub environments: Vec<EnvironmentResource>,
|
||||
pub source_provider_manifest: Digest,
|
||||
pub source_transfer_policy: SourceTransferPolicy,
|
||||
pub selected_inputs: Vec<SelectedInput>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct BundleMetadata {
|
||||
pub identity: Digest,
|
||||
pub wasm_code: Digest,
|
||||
pub task_metadata: BundleTaskMetadata,
|
||||
pub source_metadata: BundleSourceMetadata,
|
||||
pub debug_metadata: BundleDebugMetadata,
|
||||
pub environments: Vec<EnvironmentResource>,
|
||||
pub selected_inputs: Vec<SelectedInput>,
|
||||
pub embeds_full_container_images: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct BundleTaskMetadata {
|
||||
pub task_abi: Digest,
|
||||
pub entrypoints: Vec<String>,
|
||||
pub default_entrypoint: String,
|
||||
pub boundary: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct BundleSourceMetadata {
|
||||
pub source_provider_manifest: Digest,
|
||||
pub transfer_policy: SourceTransferPolicy,
|
||||
pub selected_inputs: Vec<SelectedInput>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct BundleDebugMetadata {
|
||||
pub available: bool,
|
||||
pub source_level_breakpoints: bool,
|
||||
pub dap_virtual_process: bool,
|
||||
pub variables_pane_supported: bool,
|
||||
}
|
||||
|
||||
impl BundleIdentityInputs {
|
||||
pub fn identity(&self) -> Digest {
|
||||
let mut parts = vec![
|
||||
|
|
@ -32,8 +62,16 @@ impl BundleIdentityInputs {
|
|||
self.wasm_code.as_str().as_bytes().to_vec(),
|
||||
self.task_abi.as_str().as_bytes().to_vec(),
|
||||
self.source_provider_manifest.as_str().as_bytes().to_vec(),
|
||||
self.default_entrypoint.as_bytes().to_vec(),
|
||||
format!("{:?}", self.source_transfer_policy).into_bytes(),
|
||||
];
|
||||
|
||||
let mut entrypoints = self.entrypoints.clone();
|
||||
entrypoints.sort();
|
||||
for entrypoint in entrypoints {
|
||||
parts.push(entrypoint.into_bytes());
|
||||
}
|
||||
|
||||
let mut environments = self.environments.clone();
|
||||
environments.sort_by(|left, right| left.name.cmp(&right.name));
|
||||
for environment in environments {
|
||||
|
|
@ -53,8 +91,29 @@ impl BundleIdentityInputs {
|
|||
}
|
||||
|
||||
pub fn inspectable_metadata(&self) -> BundleMetadata {
|
||||
let mut entrypoints = self.entrypoints.clone();
|
||||
entrypoints.sort();
|
||||
|
||||
BundleMetadata {
|
||||
identity: self.identity(),
|
||||
wasm_code: self.wasm_code.clone(),
|
||||
task_metadata: BundleTaskMetadata {
|
||||
task_abi: self.task_abi.clone(),
|
||||
entrypoints,
|
||||
default_entrypoint: self.default_entrypoint.clone(),
|
||||
boundary: "disasmer_task_exports".to_owned(),
|
||||
},
|
||||
source_metadata: BundleSourceMetadata {
|
||||
source_provider_manifest: self.source_provider_manifest.clone(),
|
||||
transfer_policy: self.source_transfer_policy.clone(),
|
||||
selected_inputs: self.selected_inputs.clone(),
|
||||
},
|
||||
debug_metadata: BundleDebugMetadata {
|
||||
available: true,
|
||||
source_level_breakpoints: true,
|
||||
dap_virtual_process: true,
|
||||
variables_pane_supported: true,
|
||||
},
|
||||
environments: self.environments.clone(),
|
||||
selected_inputs: self.selected_inputs.clone(),
|
||||
embeds_full_container_images: false,
|
||||
|
|
@ -86,8 +145,11 @@ mod tests {
|
|||
let base = BundleIdentityInputs {
|
||||
wasm_code: Digest::sha256("wasm"),
|
||||
task_abi: Digest::sha256("abi"),
|
||||
entrypoints: vec!["build".to_owned()],
|
||||
default_entrypoint: "build".to_owned(),
|
||||
environments: vec![env("recipe-a")],
|
||||
source_provider_manifest: Digest::sha256("source"),
|
||||
source_transfer_policy: SourceTransferPolicy::local_first_snapshot_chunks(),
|
||||
selected_inputs: vec![],
|
||||
};
|
||||
let mut changed = base.clone();
|
||||
|
|
@ -101,8 +163,11 @@ mod tests {
|
|||
let inputs = BundleIdentityInputs {
|
||||
wasm_code: Digest::sha256("wasm"),
|
||||
task_abi: Digest::sha256("abi"),
|
||||
entrypoints: vec!["build".to_owned(), "test".to_owned()],
|
||||
default_entrypoint: "build".to_owned(),
|
||||
environments: vec![env("recipe")],
|
||||
source_provider_manifest: Digest::sha256("source"),
|
||||
source_transfer_policy: SourceTransferPolicy::local_first_snapshot_chunks(),
|
||||
selected_inputs: vec![SelectedInput {
|
||||
path: "inputs/config.json".to_owned(),
|
||||
digest: Digest::sha256("config"),
|
||||
|
|
@ -111,6 +176,19 @@ mod tests {
|
|||
|
||||
let metadata = inputs.inspectable_metadata();
|
||||
|
||||
assert!(metadata.wasm_code.as_str().starts_with("sha256:"));
|
||||
assert_eq!(metadata.task_metadata.default_entrypoint, "build");
|
||||
assert!(metadata
|
||||
.task_metadata
|
||||
.entrypoints
|
||||
.contains(&"test".to_owned()));
|
||||
assert!(metadata.debug_metadata.dap_virtual_process);
|
||||
assert!(
|
||||
metadata
|
||||
.source_metadata
|
||||
.transfer_policy
|
||||
.local_source_bytes_remain_node_local
|
||||
);
|
||||
assert_eq!(metadata.environments.len(), 1);
|
||||
assert!(!metadata.embeds_full_container_images);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,10 @@ pub use auth::{
|
|||
CliLoginFlow, CredentialKind, EnrollmentError, EnrollmentGrant, IdentityKind, NodeCredential,
|
||||
PublicKeyIdentity, Scope,
|
||||
};
|
||||
pub use bundle::{BundleIdentityInputs, BundleMetadata, SelectedInput};
|
||||
pub use bundle::{
|
||||
BundleDebugMetadata, BundleIdentityInputs, BundleMetadata, BundleSourceMetadata,
|
||||
BundleTaskMetadata, SelectedInput,
|
||||
};
|
||||
pub use capability::{Capability, CapabilityReportError, EnvironmentBackend, NodeCapabilities, Os};
|
||||
pub use checkpoint::{
|
||||
CheckpointBoundary, CompatibilityFailure, RestartDecision, RestartPolicy, RestartRequest,
|
||||
|
|
|
|||
|
|
@ -376,6 +376,21 @@ expect(
|
|||
"CLI exposes environment pre-schedule diagnostics",
|
||||
/environment_diagnostics_for_inputs[\s\S]*diagnose_environment_references[\s\S]*missing_environment/
|
||||
);
|
||||
expect(
|
||||
cli,
|
||||
"CLI bundle metadata exposes MVP build facets",
|
||||
/BundleIdentityInputs[\s\S]*entrypoints[\s\S]*default_entrypoint[\s\S]*source_transfer_policy[\s\S]*wasm_source_proxy_digest[\s\S]*task_abi_digest/
|
||||
);
|
||||
expect(
|
||||
cli,
|
||||
"CLI bundle coverage verifies Dockerfile and debug metadata",
|
||||
/fn bundle_inspect_discovers_environments_selected_inputs_and_source_providers\(\)[\s\S]*envs\/docker\/Dockerfile[\s\S]*task_metadata[\s\S]*source_metadata[\s\S]*debug_metadata/
|
||||
);
|
||||
expect(
|
||||
cli,
|
||||
"CLI build coverage verifies inspectable metadata",
|
||||
/fn build_command_reuses_bundle_inspection_without_full_repo_upload\(\)[\s\S]*wasm_code[\s\S]*task_metadata[\s\S]*source_metadata[\s\S]*debug_metadata/
|
||||
);
|
||||
expect(
|
||||
cli,
|
||||
"CLI blocks build before scheduling unsafe inputs",
|
||||
|
|
|
|||
|
|
@ -89,5 +89,17 @@ assertHuman("bundle inspect", inspectHuman, [
|
|||
const inspectJson = json(["bundle", "inspect", "--project", project, "--json"]);
|
||||
assert.strictEqual(inspectJson.project, project);
|
||||
assert.match(inspectJson.metadata.identity, /^sha256:/);
|
||||
assert.match(inspectJson.metadata.wasm_code, /^sha256:/);
|
||||
assert.strictEqual(inspectJson.metadata.task_metadata.default_entrypoint, "build");
|
||||
assert(inspectJson.metadata.task_metadata.entrypoints.includes("release"));
|
||||
assert.strictEqual(
|
||||
inspectJson.metadata.source_metadata.transfer_policy.coordinator_receives_source_bytes_by_default,
|
||||
false
|
||||
);
|
||||
assert.strictEqual(
|
||||
inspectJson.metadata.source_metadata.transfer_policy.default_full_repo_tarball,
|
||||
false
|
||||
);
|
||||
assert.strictEqual(inspectJson.metadata.debug_metadata.dap_virtual_process, true);
|
||||
|
||||
console.log("CLI output mode smoke passed");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue