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
19 changes: 18 additions & 1 deletion .github/workflows/devcontainer-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,32 @@ jobs:
runner: ubuntu-latest
rust_target: x86_64-unknown-linux-gnu
pypi_wheel_builder: manylinux
pypi_manylinux_container: quay.io/pypa/manylinux2014_x86_64
- target: linux-x64-musl
runner: ubuntu-latest
rust_target: x86_64-unknown-linux-musl
pypi_wheel_builder: host
pypi_manylinux_container: ''
- target: linux-arm64
runner: ubuntu-24.04-arm
rust_target: aarch64-unknown-linux-gnu
pypi_wheel_builder: manylinux
pypi_manylinux_container: quay.io/pypa/manylinux2014_aarch64
- target: linux-arm64-musl
runner: ubuntu-24.04-arm
rust_target: aarch64-unknown-linux-musl
pypi_wheel_builder: host
pypi_manylinux_container: ''
- target: darwin-x64
runner: macos-15-intel
rust_target: x86_64-apple-darwin
pypi_wheel_builder: host
pypi_manylinux_container: ''
- target: darwin-arm64
runner: macos-15
rust_target: aarch64-apple-darwin
pypi_wheel_builder: host
pypi_manylinux_container: ''
runs-on: ${{ matrix.runner }}
env:
CARGO_TOML_PATH: cmd/devcontainer/Cargo.toml
Expand All @@ -84,7 +98,7 @@ jobs:
targets: ${{ matrix.rust_target }}

- name: Install musl linker
if: matrix.rust_target == 'x86_64-unknown-linux-musl'
if: endsWith(matrix.rust_target, '-unknown-linux-musl')
shell: bash
run: |
set -euo pipefail
Expand Down Expand Up @@ -136,6 +150,7 @@ jobs:
command: build
target: ${{ matrix.rust_target }}
manylinux: 2014
container: ${{ matrix.pypi_manylinux_container }}
args: --release --out dist/wheels --compatibility pypi

- name: Setup uv
Expand Down Expand Up @@ -314,5 +329,7 @@ jobs:
dist/npm/devcontainer-rs-devcontainer-darwin-arm64 \
dist/npm/devcontainer-rs-devcontainer-linux-x64-gnu \
dist/npm/devcontainer-rs-devcontainer-linux-x64-musl \
dist/npm/devcontainer-rs-devcontainer-linux-arm64-gnu \
dist/npm/devcontainer-rs-devcontainer-linux-arm64-musl \
dist/npm/devcontainer-rs \
dist/npm/devcontainer-rs-cli
20 changes: 20 additions & 0 deletions build/check-npm-publish-workflow.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,26 @@ assert.match(
/node build\/publish-npm-packages\.js /,
"npm publish job should use the repo-owned idempotent npm publish helper",
);
assert.match(
buildJob,
/rust_target:\s*aarch64-unknown-linux-gnu\b/,
"release build matrix should include Linux arm64 GNU artifacts",
);
assert.match(
buildJob,
/rust_target:\s*aarch64-unknown-linux-musl\b/,
"release build matrix should include Linux arm64 musl artifacts",
);
assert.match(
npmJob,
/dist\/npm\/devcontainer-rs-devcontainer-linux-arm64-gnu\b/,
"npm publish job should publish the Linux arm64 GNU native package",
);
assert.match(
npmJob,
/dist\/npm\/devcontainer-rs-devcontainer-linux-arm64-musl\b/,
"npm publish job should publish the Linux arm64 musl native package",
);
assert.doesNotMatch(
npmJob,
/\bnpm publish --access public\b/,
Expand Down
14 changes: 14 additions & 0 deletions build/test-npm-package-smoke.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,17 @@ test("npm package smoke selects the musl native package on linux x64 musl", () =
"@devcontainer-rs/devcontainer-linux-x64-musl",
);
});

test("npm package smoke selects the musl native package on linux arm64 musl", () => {
const target = detectHostTarget({
platform: "linux",
arch: "arm64",
libc: "musl",
});

assert.equal(target.target, "linux-arm64-musl");
assert.equal(
target.packageName,
"@devcontainer-rs/devcontainer-linux-arm64-musl",
);
});
28 changes: 28 additions & 0 deletions build/test-npm-wrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,32 @@ test("maps linux x64 musl to the musl native package", () => {
);
});

test("maps linux arm64 glibc to the arm64 gnu native package", () => {
const resolved = resolveBinaryPackage({
platform: "linux",
arch: "arm64",
libc: "gnu",
});
assert.equal(resolved.target, "linux-arm64-gnu");
assert.equal(
resolved.packageName,
"@devcontainer-rs/devcontainer-linux-arm64-gnu",
);
});

test("maps linux arm64 musl to the arm64 musl native package", () => {
const resolved = resolveBinaryPackage({
platform: "linux",
arch: "arm64",
libc: "musl",
});
assert.equal(resolved.target, "linux-arm64-musl");
assert.equal(
resolved.packageName,
"@devcontainer-rs/devcontainer-linux-arm64-musl",
);
});

test("detects musl when ldd reports on stderr and exits non-zero", () => {
const detected = detectLibc({
platform: "linux",
Expand Down Expand Up @@ -118,6 +144,8 @@ test("runtime config optional dependency set matches supported targets", () => {
assert.deepEqual(packageNames.sort(), [
"@devcontainer-rs/devcontainer-darwin-arm64",
"@devcontainer-rs/devcontainer-darwin-x64",
"@devcontainer-rs/devcontainer-linux-arm64-gnu",
"@devcontainer-rs/devcontainer-linux-arm64-musl",
"@devcontainer-rs/devcontainer-linux-x64-gnu",
"@devcontainer-rs/devcontainer-linux-x64-musl",
]);
Expand Down
2 changes: 2 additions & 0 deletions dist-workspace.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ installers = []
targets = [
"x86_64-unknown-linux-gnu",
"x86_64-unknown-linux-musl",
"aarch64-unknown-linux-gnu",
"aarch64-unknown-linux-musl",
"x86_64-apple-darwin",
"aarch64-apple-darwin",
]
Expand Down
8 changes: 5 additions & 3 deletions docs/standalone/distribution.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

- GitHub Releases is the active distribution channel.
- `dist-workspace.toml` is the release artifact baseline for cargo-dist.
- `.github/workflows/devcontainer-release.yml` builds release archives for Linux x64 (glibc), Linux x64 (musl), macOS x64, and macOS arm64 with cargo-dist.
- `.github/workflows/devcontainer-release.yml` builds release archives for Linux x64 (glibc), Linux x64 (musl), Linux arm64 (glibc), Linux arm64 (musl), macOS x64, and macOS arm64 with cargo-dist.
- Each release artifact currently includes a compressed archive and a SHA-256 checksum file.
- npm publishes two wrapper entrypoints:
- `devcontainer-rs` for `npx devcontainer-rs`
Expand Down Expand Up @@ -40,6 +40,8 @@ The initial PyPI wheel set matches the standalone release targets:

- Linux x64 glibc (`manylinux2014_x86_64`)
- Linux x64 musl (`musllinux_1_2_x86_64`)
- Linux arm64 glibc (`manylinux2014_aarch64`)
- Linux arm64 musl (`musllinux_1_2_aarch64`)
- macOS x64
- macOS arm64

Expand All @@ -58,8 +60,8 @@ Homebrew maps the backing repository `jooh/homebrew-tap` to the tap shorthand `j

## Local build flow

- `scripts/standalone/build.sh <target>` builds the Rust release binary and places it under `dist/standalone/`.
- `scripts/standalone/build-linux-x64-musl.sh` builds the Linux x64 musl artifact for older-glibc distro compatibility.
- `scripts/standalone/build.sh <target>` builds the Rust release binary and places it under `dist/standalone/`. Supported Linux targets are `linux-x64`, `linux-x64-musl`, `linux-arm64`, and `linux-arm64-musl`.
- `scripts/standalone/build-linux-x64-musl.sh` and `scripts/standalone/build-linux-arm64-musl.sh` build musl artifacts for older-glibc distro compatibility.
- `scripts/standalone/smoke.sh <binary>` runs the repo-owned smoke commands against a built artifact.
- `~/.cargo/bin/dist build --artifacts=local --target <triple> --allow-dirty` builds the cargo-dist archive into `target/distrib/`.
- `node build/prepare-npm-packages.js --artifacts-dir target/distrib --output-dir dist/npm` stages the publishable npm wrapper/native packages from dist outputs.
Expand Down
7 changes: 4 additions & 3 deletions npm/launcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,13 @@ function resolveBinaryPackage(system = {}) {
if (platform === "darwin" && arch === "arm64") {
return runtimeConfig.supportedTargets["darwin-arm64"];
}
if (platform === "linux" && arch === "x64") {
if (platform === "linux" && (arch === "x64" || arch === "arm64")) {
const targetArch = arch === "x64" ? "x64" : "arm64";
const libc = detectLibc(system);
if (libc === "musl") {
return runtimeConfig.supportedTargets["linux-x64-musl"];
return runtimeConfig.supportedTargets[`linux-${targetArch}-musl`];
}
return runtimeConfig.supportedTargets["linux-x64-gnu"];
return runtimeConfig.supportedTargets[`linux-${targetArch}-gnu`];
}

throw new Error(
Expand Down
20 changes: 20 additions & 0 deletions npm/runtime-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,26 @@ const supportedTargets = {
cpu: "x64",
libc: "musl",
},
"linux-arm64-gnu": {
target: "linux-arm64-gnu",
triple: "aarch64-unknown-linux-gnu",
archiveSuffix: "linux-arm64-gnu",
packageName: "@devcontainer-rs/devcontainer-linux-arm64-gnu",
packageSlug: "devcontainer-rs-devcontainer-linux-arm64-gnu",
os: "linux",
cpu: "arm64",
libc: "glibc",
},
"linux-arm64-musl": {
target: "linux-arm64-musl",
triple: "aarch64-unknown-linux-musl",
archiveSuffix: "linux-arm64-musl",
packageName: "@devcontainer-rs/devcontainer-linux-arm64-musl",
packageSlug: "devcontainer-rs-devcontainer-linux-arm64-musl",
os: "linux",
cpu: "arm64",
libc: "musl",
},
};

const wrapperPackages = {
Expand Down
4 changes: 4 additions & 0 deletions scripts/standalone/build-linux-arm64-musl.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env bash
set -euo pipefail

"$(dirname "$0")/build.sh" linux-arm64-musl
8 changes: 7 additions & 1 deletion scripts/standalone/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ set -euo pipefail

if [[ $# -ne 1 ]]; then
echo "usage: $0 <target>" >&2
echo "example targets: linux-x64, linux-x64-musl, darwin-x64, darwin-arm64" >&2
echo "example targets: linux-x64, linux-x64-musl, linux-arm64, linux-arm64-musl, darwin-x64, darwin-arm64" >&2
exit 2
fi

Expand All @@ -18,6 +18,12 @@ case "$target" in
linux-x64-musl)
rust_target="x86_64-unknown-linux-musl"
;;
linux-arm64)
rust_target="aarch64-unknown-linux-gnu"
;;
linux-arm64-musl)
rust_target="aarch64-unknown-linux-musl"
;;
darwin-x64|darwin-arm64)
;;
*)
Expand Down
2 changes: 1 addition & 1 deletion tap
Loading