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: 8 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,8 @@ jobs:
coverage:
needs: failfast
runs-on: macos-15
env:
CARGO_INCREMENTAL: "0"
steps:
- uses: actions/checkout@v7
with:
Expand All @@ -237,6 +239,12 @@ jobs:
llvm-cov: "true"
rust-components: llvm-tools-preview
browser-fixture: "true"
- name: Reserve disk headroom for real-runtime coverage
run: |
mbx settings set gc.min_free_size 20GiB
./scripts/clean-mbx-cache.sh
df -h .
du -sh target .temp || true
- name: Build untracked runtime and toolchain assets from this checkout
run: bun run build
- name: Enforce 90 percent Rust line coverage
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
-- Retained versions bind the previous system Worker manifest in their immutable
-- descriptor. Reject before changing authority rather than rehashing deployments.
CREATE TABLE migration_v15_worker_identity_guard (
invalid INTEGER NOT NULL CHECK (invalid = 0)
);
INSERT INTO migration_v15_worker_identity_guard (invalid)
SELECT 1 FROM worker_versions WHERE deleted_at_ms IS NULL LIMIT 1;
DROP TABLE migration_v15_worker_identity_guard;

-- Extend the current builtin authority without changing published migrations.
CREATE TABLE version_builtin_bindings_next (
version_id TEXT NOT NULL REFERENCES worker_versions(id),
Expand Down
64 changes: 64 additions & 0 deletions crates/storage/src/migrations_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1197,3 +1197,67 @@ fn local_extension_migration_rejects_old_service_descriptors_atomically() {
})
.unwrap();
}

#[test]
fn browser_migration_rejects_retained_worker_identity_without_mutation() {
use std::os::unix::fs::PermissionsExt;

for retained in [false, true] {
let directory = tempfile::tempdir().unwrap();
let path = directory.path().join("control.sqlite");
let mut connection = Connection::open(&path).unwrap();
connection
.pragma_update(None, "foreign_keys", "ON")
.unwrap();
schema_migrations::migrate_to_for_test(&mut connection, DatabaseKind::Control, 14);
if retained {
connection
.execute_batch(
"INSERT INTO instance_identity(instance_id, created_at_ms)
VALUES('00000000-0000-7000-8000-000000000001', 1);
INSERT INTO workers(id, name, do_storage_id, route_generation,
created_at_ms, updated_at_ms, ownership)
VALUES('00000000-0000-7000-8000-000000000002', 'worker',
'00000000-0000-7000-8000-000000000003', 0, 1, 1, 'tenant');
INSERT INTO worker_versions(id, worker_id, version_number, content_kind,
state, artifact_sha256, artifact_size, artifact_schema_version,
main_module, worker_code_sha256, loader_schema_version,
compatibility_date, compatibility_flags_json, created_at_ms)
VALUES('00000000-0000-7000-8000-000000000004',
'00000000-0000-7000-8000-000000000002', 1, 'worker', 'staging',
zeroblob(32), 1, 1, 'index.js', zeroblob(32), 1,
'2026-09-08', X'5B5D', 1);",
)
.unwrap();
}
drop(connection);
std::fs::set_permissions(&path, std::fs::Permissions::from_mode(0o600)).unwrap();
let before = std::fs::read(&path).unwrap();
let result =
ControlDb::preflight_migrations(&path, 100, &DeterministicClock::new(UNIX_EPOCH));
if retained {
assert_eq!(result.unwrap_err().code(), ErrorCode::MigrationFailed);
} else {
result.unwrap();
}
assert_eq!(std::fs::read(&path).unwrap(), before);
let db = ControlDb::open(&path, 100).unwrap();
if retained {
assert_eq!(
apply(&db, &DeterministicClock::new(UNIX_EPOCH))
.unwrap_err()
.code(),
ErrorCode::MigrationFailed
);
assert_eq!(inspect_schema(&db).unwrap(), 14);
assert!(!db.table_exists("browser_sessions").unwrap());
assert!(
!db.table_exists("migration_v15_worker_identity_guard")
.unwrap()
);
} else {
apply(&db, &DeterministicClock::new(UNIX_EPOCH)).unwrap();
assert!(db.table_exists("browser_sessions").unwrap());
}
}
}
2 changes: 1 addition & 1 deletion test/conformance/baseline.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"schemaVersion": 1,
"sourceDigest": "4fb387d2955ec52d91a8d0aeb7e6210b644d3b94d1334e2067d6352bda6d35cc",
"sourceDigest": "8a1f41ba31595329dbfac52424dcbcdfba1b0715ebd44f27ac0c81a97acdedb0",
"sourceDigestScope": "git-visible production, test, toolchain, manifest, and maintained reference inputs; excludes generated Python caches, test/conformance/baseline.json, and non-reference docs",
"workerdLockSha256": "d685331dc96e294b10a1b2365065ab6934d920c037d071b020552c7fc4f0d37f",
"workerd": {
Expand Down