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
15 changes: 9 additions & 6 deletions crates/tower-duckdb/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1188,12 +1188,15 @@ mod tests {
false
}

/// MinIO pinned to an immutable release tag rather than `latest`.
/// Coollabs builds official MinIO sources; upstream's prebuilt images are unavailable.
/// https://github.com/coollabsio/minio
///
/// A floating tag lets a new upstream image change this test's behaviour, or
/// break it into a skip, without anyone choosing that. A security regression
/// test should only change when someone means it. Bump deliberately and re-run.
const MINIO_IMAGE_TAG: &str = "RELEASE.2025-09-07T16-13-09Z";
/// Pin the multi-platform image digest so a rebuilt tag cannot change this security test.
/// Bump deliberately and re-run the object-store test on Linux.
const MINIO_IMAGE_TAG: &str = concat!(
"RELEASE.2025-10-15T17-29-55Z@",
"sha256:69b55a1c1c5dc285ce04db96689f5b2102317fc77a50680a1874ca6efd1c87f9"
);

/// Whether a container runtime that can run this image is reachable.
///
Expand Down Expand Up @@ -1241,7 +1244,7 @@ mod tests {
}

let bucket = "warehouse";
let image = GenericImage::new("quay.io/minio/minio", MINIO_IMAGE_TAG)
let image = GenericImage::new("ghcr.io/coollabsio/minio", MINIO_IMAGE_TAG)
.with_wait_for(WaitFor::seconds(1))
.with_exposed_port(9000.tcp())
.with_entrypoint("sh")
Expand Down
6 changes: 5 additions & 1 deletion crates/tower-package/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ pub struct Manifest {

pub schedule: Option<String>,

#[serde(default, skip_serializing_if = "Option::is_none")]
pub run_size: Option<String>,

#[serde(default)]
pub import_paths: Vec<String>,

Expand Down Expand Up @@ -108,7 +111,7 @@ pub struct PackageInputs {
// module_files have archive_name already rooted under "modules/".
pub module_files: Vec<Entry>,

// towerfile_bytes is the sole source of invoke, parameters, and import_paths.
// towerfile_bytes is the sole source of invoke, parameters, run_size, and import_paths.
pub towerfile_bytes: Vec<u8>,
}

Expand Down Expand Up @@ -154,6 +157,7 @@ pub fn build_package(inputs: PackageInputs) -> Result<BuiltPackage, Error> {
invoke: towerfile.app.script,
parameters: towerfile.parameters,
schedule: None,
run_size: towerfile.app.run_size,
import_paths,
app_dir_name: "app".to_string(),
modules_dir_name: "modules".to_string(),
Expand Down
9 changes: 5 additions & 4 deletions crates/tower-package/src/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@ use crate::core::{
use crate::error::Error;
use crate::towerfile::Towerfile;

// PackageSpec describes how to build a package. Everything core needs (invoke, parameters,
// import_paths as manifest entries) is derived from the Towerfile on disk, so this struct only
// carries what the file resolver needs: where the Towerfile lives, what's considered the project
// root, which globs match app files, and which import paths to walk.
// PackageSpec describes how to build a package. Manifest fields are derived from the Towerfile
// on disk, so this struct only carries what the file resolver needs: where the Towerfile lives,
// what's considered the project root, which globs match app files, and which import paths to walk.
#[derive(Debug)]
pub struct PackageSpec {
pub towerfile_path: PathBuf,
Expand Down Expand Up @@ -85,6 +84,7 @@ impl Package {
invoke: "".to_string(),
parameters: vec![],
schedule: None,
run_size: None,
import_paths: vec![],
app_dir_name: "app".to_string(),
modules_dir_name: "modules".to_string(),
Expand Down Expand Up @@ -573,6 +573,7 @@ mod test {
invoke: invoke.to_string(),
parameters: vec![],
schedule: None,
run_size: None,
import_paths: vec![],
app_dir_name: "app".to_string(),
modules_dir_name: "modules".to_string(),
Expand Down
27 changes: 13 additions & 14 deletions crates/tower-package/tests/package_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ async fn it_creates_package() {
"files {:?} was missing MANIFEST",
files
);

let manifest = &files["MANIFEST"];
let json: serde_json::Value = serde_json::from_str(manifest).unwrap();
assert!(json.get("run_size").is_none());
assert_eq!(Manifest::from_json(manifest).unwrap().run_size, None);
}

#[tokio::test]
Expand Down Expand Up @@ -607,9 +612,8 @@ where
}

#[tokio::test]
async fn it_ships_run_size_in_the_packaged_towerfile() {
// The server reads run_size out of the Towerfile stored on the app version,
// not out of the MANIFEST, so the raw file has to survive packaging verbatim.
async fn it_preserves_run_size_in_the_manifest_and_towerfile() {
// The deploy handler reads run_size from MANIFEST when creating the app version.
let tmp_dir = TmpDir::new("example")
.await
.expect("Failed to create temp dir");
Expand All @@ -631,18 +635,13 @@ async fn it_ships_run_size_in_the_packaged_towerfile() {
let packaged = files
.get("Towerfile")
.expect("package was missing the Towerfile entry");
assert!(
packaged.contains(r#"run_size = "basic.large""#),
"packaged Towerfile lost run_size: {:?}",
packaged
);
assert_eq!(packaged, towerfile);

// run_size deliberately stays out of the MANIFEST: the runner doesn't act on
// it, and a second copy could disagree with the Towerfile above.
let manifest = files.get("MANIFEST").expect("package was missing MANIFEST");
assert!(
!manifest.contains("run_size"),
"MANIFEST should not carry run_size: {:?}",
manifest
let json: serde_json::Value = serde_json::from_str(manifest).unwrap();
assert_eq!(json["run_size"], "basic.large");
assert_eq!(
Manifest::from_json(manifest).unwrap().run_size.as_deref(),
Some("basic.large")
);
}
Loading