Skip to content

Commit 3da2b87

Browse files
committed
fix(native): build Linux binaries against GLIBC 2.28 for RHEL 8 compatibility
Build linux-x64 and linux-arm64 inside a custom RHEL 8 UBI container (GCC Toolset 13) so that better_sqlite3.node is compiled against GLIBC 2.28 rather than the host runner's GLIBC 2.39, making the binaries compatible with RHEL 8 / AlmaLinux 8 / Rocky Linux 8. - ci/Dockerfile.build: new RHEL 8 UBI + GCC 13 builder image, cached in GHCR by Dockerfile SHA via the new sync-builder CI job - build-native.yml: linux jobs now run inside the builder container; linux-arm64 switches from self-hosted to ubuntu-24.04-arm - packages/cli/bin/build-native: pass --no-native-build when targeting the current platform (rely on yarn install's compiled addon instead of pkg fetching a pre-built one); derive output name from package.json so the script works for both appmap and scanner - packages/scanner/bin/build-native: replace duplicate script with a symlink to the cli version
1 parent 463ffb6 commit 3da2b87

4 files changed

Lines changed: 147 additions & 31 deletions

File tree

.github/workflows/build-native.yml

Lines changed: 89 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,22 +47,86 @@ jobs:
4747
exit 1
4848
fi
4949
50-
linux-x64:
50+
sync-builder:
5151
needs: setup
5252
runs-on: ubuntu-latest
53+
permissions:
54+
contents: read
55+
packages: write
56+
outputs:
57+
image_tag: ${{ steps.calc_sha.outputs.sha }}
58+
steps:
59+
- name: Checkout
60+
uses: actions/checkout@v6
61+
62+
- name: Calculate Dockerfile SHA
63+
id: calc_sha
64+
run: echo "sha=$(sha256sum ci/Dockerfile.build | cut -d' ' -f1)" >> $GITHUB_OUTPUT
65+
66+
- name: Login to GHCR
67+
uses: docker/login-action@v3
68+
with:
69+
registry: ghcr.io
70+
username: ${{ github.actor }}
71+
password: ${{ secrets.GITHUB_TOKEN }}
72+
73+
- name: Check if image exists
74+
id: check
75+
continue-on-error: true
76+
run: docker manifest inspect ghcr.io/${{ github.repository }}/rhel8-builder:${{ steps.calc_sha.outputs.sha }}
77+
78+
- uses: docker/setup-qemu-action@v3
79+
if: steps.check.outcome == 'failure'
80+
- uses: docker/setup-buildx-action@v3
81+
if: steps.check.outcome == 'failure'
82+
- name: Build and Push
83+
if: steps.check.outcome == 'failure'
84+
uses: docker/build-push-action@v6
85+
with:
86+
context: .
87+
file: ./ci/Dockerfile.build
88+
push: true
89+
platforms: linux/amd64,linux/arm64
90+
tags: ghcr.io/${{ github.repository }}/rhel8-builder:${{ steps.calc_sha.outputs.sha }}
91+
cache-from: type=gha
92+
cache-to: type=gha,mode=max
93+
94+
linux-x64:
95+
needs: [setup, sync-builder]
96+
runs-on: ubuntu-latest
97+
permissions:
98+
packages: read
5399
timeout-minutes: 30
100+
container:
101+
image: ghcr.io/${{ github.repository }}/rhel8-builder:${{ needs.sync-builder.outputs.image_tag }}
102+
credentials:
103+
username: ${{ github.actor }}
104+
password: ${{ secrets.GITHUB_TOKEN }}
54105
env:
55106
PUPPETEER_SKIP_DOWNLOAD: 1
56107

57108
steps:
58109
- name: Checkout
59110
uses: actions/checkout@v6
60111

112+
- name: Prepare yarn
113+
run: corepack prepare --activate
114+
115+
- name: Cache node_modules
116+
uses: actions/cache@v4
117+
with:
118+
path: node_modules
119+
key: ${{ runner.os }}-${{ runner.arch }}-builder-${{ needs.sync-builder.outputs.image_tag }}-yarn-${{ hashFiles('yarn.lock') }}
120+
61121
- name: Setup Node
62-
uses: ./.github/actions/setup-node
122+
uses: actions/setup-node@v4
123+
with:
124+
node-version: 18
125+
cache: yarn
63126

64127
- name: Build
65128
run: |
129+
yarn install --immutable
66130
yarn build
67131
cd ${{ needs.setup.outputs.package_dir }}
68132
yarn build-native linux x64
@@ -74,21 +138,41 @@ jobs:
74138
path: ${{ needs.setup.outputs.package_dir }}/release/${{ needs.setup.outputs.package_name }}-linux-x64
75139

76140
linux-arm64:
77-
needs: setup
78-
runs-on: linux-arm64
141+
needs: [setup, sync-builder]
142+
runs-on: ubuntu-24.04-arm
143+
permissions:
144+
packages: read
79145
timeout-minutes: 30
146+
container:
147+
image: ghcr.io/${{ github.repository }}/rhel8-builder:${{ needs.sync-builder.outputs.image_tag }}
148+
credentials:
149+
username: ${{ github.actor }}
150+
password: ${{ secrets.GITHUB_TOKEN }}
80151
env:
81152
PUPPETEER_SKIP_DOWNLOAD: 1
82153

83154
steps:
84155
- name: Checkout
85156
uses: actions/checkout@v6
86157

158+
- name: Prepare yarn
159+
run: corepack prepare --activate
160+
161+
- name: Cache node_modules
162+
uses: actions/cache@v4
163+
with:
164+
path: node_modules
165+
key: ${{ runner.os }}-${{ runner.arch }}-builder-${{ needs.sync-builder.outputs.image_tag }}-yarn-${{ hashFiles('yarn.lock') }}
166+
87167
- name: Setup Node
88-
uses: ./.github/actions/setup-node
168+
uses: actions/setup-node@v4
169+
with:
170+
node-version: 18
171+
cache: yarn
89172

90173
- name: Build
91174
run: |
175+
yarn install --immutable
92176
yarn build
93177
cd ${{ needs.setup.outputs.package_dir }}
94178
yarn build-native linux arm64

ci/Dockerfile.build

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
FROM registry.access.redhat.com/ubi8/nodejs-18:1-140
2+
3+
# Use OCI labels so the GHCR page looks professional and links to your repo
4+
LABEL org.opencontainers.image.title="RHEL 8 Builder" \
5+
org.opencontainers.image.description="Node 18 + GCC 13 for RHEL 8 native builds" \
6+
org.opencontainers.image.source="https://github.com/getappmap/appmap-js"
7+
8+
USER root
9+
10+
# 1. Install GCC Toolset 13 (provides modern g++ on RHEL 8)
11+
# 2. Clean cache to keep image small
12+
RUN dnf install -y gcc-toolset-13-gcc-c++ && \
13+
dnf clean all
14+
15+
# 3. Enable Corepack for Yarn/PNPM support
16+
RUN corepack enable
17+
18+
# 4. Set PATH so 'gcc' and 'g++' point to the Toolset version automatically
19+
ENV PATH=/opt/rh/gcc-toolset-13/root/usr/bin:$PATH
20+
21+
# Standard UBI user
22+
USER 1001
23+
WORKDIR /opt/app-root/src

packages/cli/bin/build-native

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,48 @@
11
#!/bin/bash
2-
set -ex
2+
set -e
33

44
# Optionally pass a desired OS as the first argument, followed by an optional architecture.
55
# e.g. ./build-native macos arm64
66
#
77
# Otherwise every target will be built.
8-
# Note that if a desired OS is provided, the output will simply be named 'appmap' or 'appmap.exe'.
9-
# OS and ARCH are only used to name the output when multiple targets are being built at once.
108
OS="${1}"
9+
ARCH="${2:-x64}"
1110
ARGS="--config package.json --compress GZip"
11+
PKG_NAME=$(node -p "require('./package.json').name.split('/').pop()")
12+
13+
# check if OS is set and OS/ARCH is the same as the current system.
14+
is_native() {
15+
[ -z "${OS}" ] && return 1
16+
# Check if the current system matches the specified OS and ARCH.
17+
case "$(uname -s)" in
18+
Linux*) current_os="linux" ;;
19+
Darwin*) current_os="macos" ;;
20+
CYGWIN*) current_os="windows" ;;
21+
MINGW*) current_os="windows" ;;
22+
*) current_os="unknown" ;;
23+
esac
24+
current_arch="$(uname -m)"
25+
case "${current_arch}" in
26+
x86_64) current_arch="x64" ;;
27+
arm64) current_arch="arm64" ;;
28+
aarch64) current_arch="arm64" ;;
29+
*) current_arch="unknown" ;;
30+
esac
31+
[ "${OS}" = "${current_os}" ] && [ "${ARCH}" = "${current_arch}" ]
32+
}
33+
34+
# Do not rebuild native binary addons if the architecture and system match.
35+
# These should be built by yarn install beforehand.
36+
# Having pkg try to rebuild them risks downloading pre-built versions that do not work
37+
# correctly on the target machine.
38+
if is_native; then
39+
echo "Building native binary for current system ${OS} ${ARCH} - skipping native build step."
40+
ARGS="${ARGS} --no-native-build"
41+
fi
1242

1343
if [ -n "${OS}" ]; then
14-
ARCH="${2:-x64}"
1544
echo "Building native binaries for ${OS} ${ARCH}..."
16-
ARGS="${ARGS} -o release/appmap-${OS}-${ARCH} -t node18-${OS}-${ARCH}"
45+
ARGS="${ARGS} -o release/${PKG_NAME}-${OS}-${ARCH} -t node18-${OS}-${ARCH}"
1746
else
1847
echo "Building native binaries for each target..."
1948
fi

packages/scanner/bin/build-native

Lines changed: 0 additions & 21 deletions
This file was deleted.

packages/scanner/bin/build-native

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../cli/bin/build-native

0 commit comments

Comments
 (0)