Skip to content

chore: pin buildx, buildkit and qemu #68

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 14 commits into from
Closed
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
9 changes: 9 additions & 0 deletions .github/docker/AddLibmongocrypt.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
ARG ARCH
ARG NODE_VERSION
FROM ${ARCH}-alpine-base-node-${NODE_VERSION}:latest

WORKDIR /mongodb-client-encryption
COPY . .

RUN npm install --ignore-scripts
RUN npm run install:libmongocrypt -- --skip-bindings
16 changes: 7 additions & 9 deletions .github/docker/Dockerfile.glibc
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,11 @@ ENV PATH=$PATH:/nodejs/bin
WORKDIR /mongodb-client-encryption
COPY . .

RUN apt-get -qq update && apt-get -qq install -y python3 build-essential git && ldd --version
RUN apt-get -qq update && apt-get -qq install -y build-essential curl git && ldd --version

RUN npm run install:libmongocrypt

ARG RUN_TEST
RUN if [ -n "$RUN_TEST" ]; then npm test ; else echo "skipping tests" ; fi

FROM scratch

COPY --from=build /mongodb-client-encryption/prebuilds/ /
RUN bash install-pyenv.sh
RUN pyenv install 3.10 && pyenv global 3.10
RUN python --version
RUN git --version
RUN c++ --version
RUN g++ --version
11 changes: 11 additions & 0 deletions .github/docker/Dockerfile.musl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
ARG ARCH=arm64
ARG NODE_VERSION=16.20.1

FROM ${ARCH}/node:${NODE_VERSION}-alpine AS dependencies

RUN apk --no-cache add make g++ libc-dev curl bash python3 py3-pip cmake git

RUN python3 --version
RUN git --version
RUN c++ --version
RUN g++ --version
5 changes: 5 additions & 0 deletions .github/docker/Prebuilds.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ARG ARCH
ARG NODE_VERSION
FROM ${ARCH}-alpine-libmongocrypt-node-${NODE_VERSION}:latest

RUN npm run prebuild
63 changes: 45 additions & 18 deletions .github/scripts/utils.mjs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// @ts-check

import { execSync } from "child_process";
import path from "path";
import url from 'node:url';
import { spawn } from "node:child_process";
import { once } from "node:events";
import { execSync } from "child_process";

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

Expand Down Expand Up @@ -55,22 +55,25 @@ export function buildLibmongocryptDownloadUrl(ref, platform) {
}

export function getLibmongocryptPrebuildName() {
const platformMatrix = {
['darwin-arm64']: 'macos',
['darwin-x64']: 'macos',
['linux-ppc64']: 'rhel-71-ppc64el',
['linux-s390x']: 'rhel72-zseries-test',
['linux-arm64']: 'ubuntu1804-arm64',
['linux-x64']: 'rhel-70-64-bit',
['win32-x64']: 'windows-test'
};

const detectedPlatform = `${process.platform}-${process.arch}`;
const prebuild = platformMatrix[detectedPlatform];

if (prebuild == null) throw new Error(`Unsupported: ${detectedPlatform}`);

return prebuild;
const prebuildIdentifierFactory = {
'darwin': () => 'macos',
'win32': () => 'windows-test',
'linux': () => {
const key = `${getLibc()}-${process.arch}`;
return {
['musl-x64']: 'alpine-amd64-earthly',
['musl-arm64']: 'alpine-arm64-earthly',
['glibc-ppc64']: 'rhel-71-ppc64el',
['glibc-s390x']: 'rhel72-zseries-test',
['glibc-arm64']: 'ubuntu1804-arm64',
['glibc-x64']: 'rhel-70-64-bit',
}[key]
}
}[process.platform] ?? (() => {
throw new Error(`Unsupported platform`);
});

return prebuildIdentifierFactory();
}

/** `xtrace` style command runner, uses spawn so that stdio is inherited */
Expand All @@ -86,4 +89,28 @@ export async function run(command, args = [], options = {}) {
await once(proc, 'exit');

if (proc.exitCode != 0) throw new Error(`CRASH(${proc.exitCode}): ${commandDetails}`);
}
}

/**
* @returns the libc (`musl` or `glibc`), if the platform is linux, otherwise null.
*/
function getLibc() {
if (process.platform !== 'linux') return null;

/**
* executes `ldd --version`. on Alpine linux, `ldd` and `ldd --version` return exit code 1 and print the version
* info to stderr, but on other platforms, `ldd --version` prints to stdout and returns exit code 0.
*
* So, this script works on both by return stderr if the command returns a non-zero exit code, otherwise stdout.
*/
function lddVersion() {
try {
return execSync('ldd --version', { encoding: 'utf-8' });
} catch (error) {
return error.stderr;
}
}

console.error({ ldd: lddVersion() });
return lddVersion().includes('musl') ? 'musl' : 'glibc';
}
44 changes: 42 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
retention-days: 1
compression-level: 0

container_builds:
container_builds_glibc:
outputs:
artifact_id: ${{ steps.upload.outputs.artifact-id }}
runs-on: ubuntu-latest
Expand Down Expand Up @@ -64,8 +64,48 @@ jobs:
name: Upload prebuild
uses: actions/upload-artifact@v4
with:
name: build-linux-${{ matrix.linux_arch }}
name: build-linux-glibc-${{ matrix.linux_arch }}
path: prebuilds/
if-no-files-found: 'error'
retention-days: 1
compression-level: 0

container_tests_musl:
runs-on: ubuntu-latest
strategy:
matrix:
linux_arch: [amd64, arm64]
fail-fast: false
steps:
- uses: actions/checkout@v4

- name: Get Full Node.js Version
id: get_nodejs_version
shell: bash
run: |
echo "version=$(node --print 'process.version.slice(1)')" >> "$GITHUB_OUTPUT"

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Run Buildx
run: |
docker buildx create --name builder --bootstrap --use
docker --debug buildx build --progress=plain --no-cache \
--platform linux/${{ matrix.linux_arch }} \
--build-arg="PLATFORM=${{ matrix.linux_arch == 'arm64' && 'arm64v8' || matrix.linux_arch }}" \
--output type=local,dest=./prebuilds,platform-split=false \
-f ./.github/docker/Dockerfile.musl \
.
- id: upload
name: Upload prebuild
uses: actions/upload-artifact@v4
with:
name: build-linux-musl-${{ matrix.linux_arch }}
path: prebuilds/
if-no-files-found: "error"
retention-days: 1
compression-level: 0
Loading
Loading