Skip to content

Commit 093fe69

Browse files
all changes
1 parent 38e84d2 commit 093fe69

File tree

5 files changed

+158
-17
lines changed

5 files changed

+158
-17
lines changed

.github/docker/Dockerfile.musl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
ARG PLATFORM=arm64
2+
ARG NODE_VERSION=16.20.1
3+
4+
FROM ${PLATFORM}/node:${NODE_VERSION}-alpine AS build
5+
6+
WORKDIR /zstd
7+
COPY . .
8+
9+
RUN apk --no-cache add make g++ libc-dev curl bash python3 py3-pip vim cmake
10+
RUN npm run install:libmongocrypt
11+
RUN npm run prebuild
12+
13+
ARG RUN_TEST
14+
RUN if [ -n "$RUN_TEST" ]; then npm test ; else echo "skipping tests" ; fi
15+
16+
FROM scratch
17+
18+
COPY --from=build /zstd/prebuilds/ /

.github/scripts/libmongocrypt.mjs

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import path from 'node:path';
99
import https from 'node:https';
1010
import stream from 'node:stream/promises';
1111
import url from 'node:url';
12+
import { getLibc, getLibmongocryptPackageName } from './utils.mjs';
1213

1314
const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
1415

@@ -161,22 +162,7 @@ export async function downloadLibMongoCrypt(nodeDepsRoot, { ref, fastDownload })
161162
await fs.rm(destination, { recursive: true, force: true });
162163
await fs.mkdir(destination);
163164

164-
const platformMatrix = {
165-
['darwin-arm64']: 'macos',
166-
['darwin-x64']: 'macos',
167-
['linux-ppc64']: 'rhel-71-ppc64el',
168-
['linux-s390x']: 'rhel72-zseries-test',
169-
['linux-arm64']: 'ubuntu1804-arm64',
170-
['linux-x64']: 'rhel-70-64-bit',
171-
['win32-x64']: 'windows-test'
172-
};
173-
174-
const detectedPlatform = `${process.platform}-${process.arch}`;
175-
const prebuild = platformMatrix[detectedPlatform];
176-
if (prebuild == null) throw new Error(`Unsupported: ${detectedPlatform}`);
177-
178-
console.error(`Platform: ${detectedPlatform} Prebuild: ${prebuild}`);
179-
165+
const prebuild = getLibmongocryptPackageName();
180166
const downloadDestination = `${prebuild}/nocrypto`;
181167
const unzipArgs = ['-xzv', '-C', `_libmongocrypt-${ref}`, downloadDestination];
182168
console.error(`+ tar ${unzipArgs.join(' ')}`);

.github/scripts/utils.mjs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { execSync } from "child_process";
2+
3+
4+
/**
5+
* @returns the libc (`musl` or `glibc`), if the platform is linux, otherwise null.
6+
*/
7+
export function getLibc() {
8+
if (process.platform !== 'linux') return null;
9+
10+
/**
11+
* executes `ldd --version`. on Alpine linux, `ldd` and `ldd --version` return exit code 1 and print the version
12+
* info to stderr, but on other platforms, `ldd --version` prints to stdout and returns exit code 0.
13+
*
14+
* So, this script works on both by return stderr if the command returns a non-zero exit code, otherwise stdout.
15+
*/
16+
function lddVersion() {
17+
try {
18+
return execSync('ldd --version', { encoding: 'utf-8' });
19+
} catch (error) {
20+
return error.stderr;
21+
}
22+
}
23+
24+
console.error({ ldd: lddVersion() });
25+
return lddVersion().includes('musl') ? 'musl' : 'glibc';
26+
}
27+
28+
/**
29+
* @returns the name of the package inside the libmognocrypt prebuild tarball for the current platform, arch and libc (if linux).
30+
*/
31+
export function getLibmongocryptPackageName() {
32+
const platformFactory = {
33+
'darwin': () => 'macos',
34+
'win32': () => 'windows-test',
35+
'linux': () => {
36+
const key = `${getLibc()}-${process.arch}`;
37+
return {
38+
['musl-x64']: 'alpine-amd64-earthly',
39+
['musl-arm64']: 'alpine-arm64-earthly',
40+
['glibc-ppc64']: 'rhel-71-ppc64el',
41+
['glibc-s390x']: 'rhel72-zseries-test',
42+
['glibc-arm64']: 'ubuntu1804-arm64',
43+
['glibc-x64']: 'rhel-70-64-bit',
44+
}[key]
45+
}
46+
}[process.platform] ?? (() => {
47+
throw new Error('unexpected platform.')
48+
});
49+
50+
return platformFactory();
51+
}
52+

.github/workflows/test.yml

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
shell: bash
3333
run: npm run test
3434

35-
container_tests:
35+
container_tests_glibc:
3636
runs-on: ubuntu-latest
3737
strategy:
3838
matrix:
@@ -71,3 +71,42 @@ jobs:
7171
--output type=local,dest=./prebuilds,platform-split=false \
7272
-f ./.github/docker/Dockerfile.glibc \
7373
.
74+
75+
76+
container_tests_musl:
77+
runs-on: ubuntu-latest
78+
strategy:
79+
matrix:
80+
linux_arch: [amd64, arm64]
81+
node: [16.20.1, 18.x, 20.x, 22.x]
82+
fail-fast: false
83+
steps:
84+
- uses: actions/checkout@v4
85+
86+
- uses: actions/setup-node@v4
87+
with:
88+
node-version: ${{ matrix.node }}
89+
90+
- name: Get Full Node.js Version
91+
id: get_nodejs_version
92+
shell: bash
93+
run: |
94+
echo "version=$(node --print 'process.version.slice(1)')" >> "$GITHUB_OUTPUT"
95+
96+
- name: Set up QEMU
97+
uses: docker/setup-qemu-action@v3
98+
99+
- name: Set up Docker Buildx
100+
uses: docker/setup-buildx-action@v3
101+
102+
- name: Run Buildx
103+
run: |
104+
docker buildx create --name builder --bootstrap --use
105+
docker --debug buildx build --progress=plain --no-cache \
106+
--platform linux/${{ matrix.linux_arch }} \
107+
--build-arg="PLATFORM=${{ matrix.linux_arch == 'arm64' && 'arm64v8' || matrix.linux_arch }}" \
108+
--build-arg="NODE_VERSION=${{ steps.get_nodejs_version.outputs.version }}" \
109+
--build-arg="RUN_TEST=true" \
110+
--output type=local,dest=./prebuilds,platform-split=false \
111+
-f ./.github/docker/Dockerfile.musl \
112+
.

etc/docker.sh

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#! /bin/bash
2+
3+
# script to aid in local testing of linux platforms
4+
# requires a running docker instance
5+
6+
# s390x, arm64, amd64 for ubuntu
7+
# amd64 or arm64v8 for alpine
8+
LINUX_ARCH=amd64
9+
10+
# 16.20.1+, default 16.20.1
11+
NODE_VERSION=20.0.0
12+
13+
SCRIPT_DIR=$(dirname ${BASH_SOURCE:-$0})
14+
PROJECT_DIR=$SCRIPT_DIR/..
15+
16+
build_and_test_musl() {
17+
docker buildx create --name builder --bootstrap --use
18+
19+
docker --debug buildx build --load --progress=plain --no-cache \
20+
--platform linux/$LINUX_ARCH --output=type=docker \
21+
--build-arg="PLATFORM=$LINUX_ARCH" \
22+
--build-arg="NODE_VERSION=$NODE_VERSION" \
23+
--build-arg="RUN_TEST=true" \
24+
-f ./.github/docker/Dockerfile.musl -t musl-zstd-base \
25+
.
26+
}
27+
28+
build_and_test_glibc() {
29+
docker buildx create --name builder --bootstrap --use
30+
31+
UBUNTU_VERSION=$(node --print 'Number(process.argv[1].split(`.`).at(0)) > 16 ? `noble` : `bionic`' $NODE_VERSION)
32+
NODE_ARCH=$(node -p 'process.argv[1] === `amd64` && `x64` || process.argv[1]' $LINUX_ARCH)
33+
echo $UBUNTU_VERSION
34+
docker buildx build --progress=plain --no-cache \
35+
--platform linux/$LINUX_ARCH \
36+
--build-arg="NODE_ARCH=$NODE_ARCH" \
37+
--build-arg="NODE_VERSION=$NODE_VERSION" \
38+
--build-arg="UBUNTU_VERSION=$UBUNTU_VERSION" \
39+
--build-arg="RUN_TEST=true" \
40+
--output type=local,dest=./prebuilds,platform-split=false \
41+
-f ./.github/docker/Dockerfile.glibc \
42+
$PROJECT_DIR
43+
}
44+
45+
build_and_test_musl
46+
# build_and_test_glibc

0 commit comments

Comments
 (0)