const fs = require('fs');
const { spawn } = require('node:child_process');
const GENERIC_BUCKETS = 3;
const SINGLE_CRATE_BUCKETS = ["wasmtime", "wasmtime-cli", "wasmtime-wasi"];
const ubuntu = 'ubuntu-24.04';
const windows = 'windows-2025';
const macos = 'macos-15';
const FAST_MATRIX = [
{
"name": "Test Linux x86_64",
"os": ubuntu,
"filter": "linux-x64",
"isa": "x64",
},
];
const FULL_MATRIX = [
...FAST_MATRIX,
{
"name": "Test MSRV",
"os": ubuntu,
"filter": "linux-x64",
"isa": "x64",
"rust": "msrv",
},
{
"name": "Test MPK",
"os": ubuntu,
"filter": "linux-x64",
"isa": "x64"
},
{
"name": "Test ASAN",
"os": ubuntu,
"filter": "asan",
"rust": "wasmtime-ci-pinned-nightly",
"target": "x86_64-unknown-linux-gnu",
},
{
"name": "Test Intel SDE",
"os": ubuntu,
"filter": "sde",
"isa": "x64",
"sde": true,
"crates": "cranelift-tools",
},
{
"name": "Test macOS x86_64",
"os": macos,
"filter": "macos-x64",
"target": "x86_64-apple-darwin",
},
{
"name": "Test macOS arm64",
"os": macos,
"filter": "macos-arm64",
"target": "aarch64-apple-darwin",
},
{
"name": "Test MSVC x86_64",
"os": windows,
"filter": "windows-x64",
},
{
"name": "Test MinGW x86_64",
"os": windows,
"target": "x86_64-pc-windows-gnu",
"filter": "mingw-x64"
},
{
"name": "Test Linux arm64",
"os": ubuntu + '-arm',
"target": "aarch64-unknown-linux-gnu",
"filter": "linux-arm64",
"isa": "aarch64",
},
{
"name": "Test Linux s390x",
"os": ubuntu,
"target": "s390x-unknown-linux-gnu",
"filter": "linux-s390x",
"isa": "s390x",
"gcc_package": "gcc-s390x-linux-gnu",
"gcc": "s390x-linux-gnu-gcc",
"qemu": "qemu-s390x -L /usr/s390x-linux-gnu",
"qemu_target": "s390x-linux-user",
},
{
"name": "Test Linux riscv64",
"os": ubuntu,
"target": "riscv64gc-unknown-linux-gnu",
"gcc_package": "gcc-riscv64-linux-gnu",
"gcc": "riscv64-linux-gnu-gcc",
"qemu": "qemu-riscv64 -cpu rv64,v=true,vlen=256,vext_spec=v1.0,zfa=true,zfh=true,zba=true,zbb=true,zbc=true,zbs=true,zbkb=true,zcb=true,zicond=true,zvfh=true -L /usr/riscv64-linux-gnu",
"qemu_target": "riscv64-linux-user",
"filter": "linux-riscv64",
"isa": "riscv64",
},
{
"name": "Tests Linux i686",
"os": ubuntu,
"target": "i686-unknown-linux-gnu",
"gcc_package": "gcc-i686-linux-gnu",
"gcc": "i686-linux-gnu-gcc",
},
{
"name": "Tests Linux armv7",
"os": ubuntu,
"target": "armv7-unknown-linux-gnueabihf",
"gcc_package": "gcc-arm-linux-gnueabihf",
"gcc": "arm-linux-gnueabihf-gcc",
"qemu": "qemu-arm -L /usr/arm-linux-gnueabihf -E LD_LIBRARY_PATH=/usr/arm-linux-gnueabihf/lib",
"qemu_target": "arm-linux-user",
},
];
async function getWorkspaceMembers() {
const child = spawn("cargo", ["metadata"], { encoding: "utf8" });
let data = "";
child.stdout.on("data", chunk => data += chunk);
await new Promise((resolve, reject) => {
child.on("close", resolve);
child.on("error", reject);
});
const metadata = JSON.parse(data);
const id_to_name = {};
for (const pkg of metadata.packages) {
id_to_name[pkg.id] = pkg.name;
}
return metadata.workspace_members.map(m => id_to_name[m]);
}
async function shard(configs) {
const members = await getWorkspaceMembers();
const buckets = Array.from({ length: GENERIC_BUCKETS }, _ => new Set());
let i = 0;
for (const crate of members) {
if (SINGLE_CRATE_BUCKETS.indexOf(crate) != -1) continue;
buckets[i].add(crate);
i = (i + 1) % GENERIC_BUCKETS;
}
for (crate of SINGLE_CRATE_BUCKETS) {
buckets.push(new Set([crate]));
}
const sharded = [];
for (const config of configs) {
if (config.crates) {
sharded.push(Object.assign(
{},
config,
{
bucket: members
.map(c => c === config.crates ? `--package ${c}` : `--exclude ${c}`)
.join(" ")
}
));
continue;
}
let nbucket = 1;
for (const bucket of buckets) {
let bucket_name = `${nbucket}/${buckets.length}`;
if (bucket.size === 1)
bucket_name = Array.from(bucket)[0];
sharded.push(Object.assign(
{},
config,
{
name: `${config.name} (${bucket_name})`,
bucket: members
.map(c => bucket.has(c) ? `--package ${c}` : `--exclude ${c}`)
.join(" "),
}
));
nbucket += 1;
}
}
return sharded;
}
async function main() {
const commits = fs.readFileSync(process.argv[2]).toString();
const names = fs.readFileSync(process.argv[3]).toString();
for (let config of FULL_MATRIX) {
if (config.rust === undefined) {
config.rust = 'default';
}
}
if (process.argv[4] == 'true') {
console.log(JSON.stringify(await shard(FULL_MATRIX), undefined, 2));
return;
}
const filtered = FULL_MATRIX.filter(config => {
if (config.isa && names.includes(`cranelift/codegen/src/isa/${config.isa}`)) {
return true;
}
if (names.includes(`cranelift/filetests/filetests/runtests`)) {
if (config.isa !== undefined)
return true;
}
if (config.filter && commits.includes(`prtest:${config.filter}`)) {
return true;
}
return false;
});
if (filtered.length > 0) {
console.log(JSON.stringify(await shard(filtered), undefined, 2));
return;
}
console.log(JSON.stringify(await shard(FAST_MATRIX), undefined, 2));
}
main()