Skip to content

Commit 586edff

Browse files
committed
feat: generate prebuilt binaries workflows
1 parent f0aba5f commit 586edff

File tree

3 files changed

+632
-48
lines changed

3 files changed

+632
-48
lines changed

.github/workflows/ci.yml

Lines changed: 0 additions & 48 deletions
This file was deleted.
Lines changed: 348 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,348 @@
1+
name: prebuilt-binaries-cross
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
version:
7+
description: "Override the semver used for the release tag (defaults to package.json or published release tag)"
8+
required: false
9+
type: string
10+
publish:
11+
description: "Upload generated binaries to a GitHub release"
12+
required: false
13+
default: true
14+
type: boolean
15+
release:
16+
types: [published]
17+
18+
permissions:
19+
contents: write
20+
actions: read
21+
22+
env:
23+
PREBUILT_DIR: prebuilt-artifacts
24+
25+
jobs:
26+
metadata:
27+
name: Resolve Version
28+
runs-on: ubuntu-latest
29+
outputs:
30+
version: ${{ steps.versions.outputs.version }}
31+
tag: ${{ steps.versions.outputs.tag }}
32+
should_publish: ${{ steps.versions.outputs.should_publish }}
33+
steps:
34+
- uses: actions/checkout@v4
35+
- id: versions
36+
env:
37+
EVENT_NAME: ${{ github.event_name }}
38+
INPUT_VERSION: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.version || '' }}
39+
PUBLISH_INPUT: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.publish || 'true' }}
40+
RELEASE_TAG: ${{ github.event_name == 'release' && github.event.release.tag_name || '' }}
41+
run: |
42+
set -euo pipefail
43+
VERSION="${INPUT_VERSION}"
44+
TAG=""
45+
46+
if [ -z "$VERSION" ]; then
47+
if [ "$EVENT_NAME" = "release" ]; then
48+
TAG="$RELEASE_TAG"
49+
if [ -z "$TAG" ]; then
50+
TAG="$GITHUB_REF_NAME"
51+
fi
52+
TAG="${TAG#refs/tags/}"
53+
if [[ "$TAG" != v* ]]; then
54+
TAG="v${TAG}"
55+
fi
56+
VERSION="${TAG#v}"
57+
else
58+
VERSION=$(node -p "require('./package.json').version")
59+
TAG="v${VERSION}"
60+
fi
61+
else
62+
if [[ "$VERSION" == v* ]]; then
63+
TAG="$VERSION"
64+
VERSION="${VERSION#v}"
65+
else
66+
TAG="v${VERSION}"
67+
fi
68+
fi
69+
70+
if [ -z "$VERSION" ]; then
71+
echo "Unable to determine version" >&2
72+
exit 1
73+
fi
74+
75+
SHOULD_PUBLISH="false"
76+
if [ "$EVENT_NAME" = "release" ]; then
77+
SHOULD_PUBLISH="true"
78+
else
79+
case "${PUBLISH_INPUT,,}" in
80+
true|1|yes)
81+
SHOULD_PUBLISH="true"
82+
;;
83+
esac
84+
fi
85+
86+
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
87+
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
88+
echo "should_publish=${SHOULD_PUBLISH}" >> "$GITHUB_OUTPUT"
89+
90+
linux-cross:
91+
name: Linux cross (${{ matrix.slug }})
92+
needs: metadata
93+
runs-on: ubuntu-22.04
94+
strategy:
95+
fail-fast: false
96+
matrix:
97+
include:
98+
- slug: x64
99+
npm_arch: x64
100+
deb_arch: amd64
101+
cc: gcc
102+
cxx: g++
103+
ar: ar
104+
ranlib: ranlib
105+
toolchain_packages: ""
106+
- slug: arm64
107+
npm_arch: arm64
108+
deb_arch: arm64
109+
cc: aarch64-linux-gnu-gcc
110+
cxx: aarch64-linux-gnu-g++
111+
ar: aarch64-linux-gnu-ar
112+
ranlib: aarch64-linux-gnu-ranlib
113+
toolchain_packages: crossbuild-essential-arm64
114+
- slug: armhf
115+
npm_arch: arm
116+
deb_arch: armhf
117+
cc: arm-linux-gnueabihf-gcc
118+
cxx: arm-linux-gnueabihf-g++
119+
ar: arm-linux-gnueabihf-ar
120+
ranlib: arm-linux-gnueabihf-ranlib
121+
toolchain_packages: crossbuild-essential-armhf
122+
- slug: riscv64
123+
npm_arch: riscv64
124+
deb_arch: riscv64
125+
cc: riscv64-linux-gnu-gcc
126+
cxx: riscv64-linux-gnu-g++
127+
ar: riscv64-linux-gnu-ar
128+
ranlib: riscv64-linux-gnu-ranlib
129+
toolchain_packages: "gcc-riscv64-linux-gnu g++-riscv64-linux-gnu"
130+
- slug: loong64
131+
npm_arch: loong64
132+
deb_arch: loongarch64
133+
cc: loongarch64-linux-gnu-gcc
134+
cxx: loongarch64-linux-gnu-g++
135+
ar: loongarch64-linux-gnu-ar
136+
ranlib: loongarch64-linux-gnu-ranlib
137+
toolchain_packages: "gcc-loongarch64-linux-gnu g++-loongarch64-linux-gnu"
138+
- slug: ppc64le
139+
npm_arch: ppc64
140+
deb_arch: ppc64el
141+
cc: powerpc64le-linux-gnu-gcc
142+
cxx: powerpc64le-linux-gnu-g++
143+
ar: powerpc64le-linux-gnu-ar
144+
ranlib: powerpc64le-linux-gnu-ranlib
145+
toolchain_packages: crossbuild-essential-ppc64el
146+
- slug: s390x
147+
npm_arch: s390x
148+
deb_arch: s390x
149+
cc: s390x-linux-gnu-gcc
150+
cxx: s390x-linux-gnu-g++
151+
ar: s390x-linux-gnu-ar
152+
ranlib: s390x-linux-gnu-ranlib
153+
toolchain_packages: crossbuild-essential-s390x
154+
env:
155+
TARGET_PLATFORM: linux
156+
PACKAGE_VERSION: ${{ needs.metadata.outputs.version }}
157+
steps:
158+
- uses: actions/checkout@v4
159+
- uses: actions/setup-node@v4
160+
with:
161+
node-version-file: '.nvmrc'
162+
- name: Install cross toolchains and headers
163+
run: |
164+
set -euo pipefail
165+
if [ "${{ matrix.deb_arch }}" != "amd64" ]; then
166+
dpkg --add-architecture ${{ matrix.deb_arch }}
167+
fi
168+
apt-get update
169+
PKGS="build-essential python3 pkg-config ninja-build libx11-dev:${{ matrix.deb_arch }} libxkbfile-dev:${{ matrix.deb_arch }} libkrb5-dev:${{ matrix.deb_arch }}"
170+
if [ -n "${{ matrix.toolchain_packages }}" ]; then
171+
PKGS="$PKGS ${{ matrix.toolchain_packages }}"
172+
fi
173+
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends $PKGS
174+
- name: Install npm dependencies
175+
run: npm install --no-fund --no-audit --ignore-scripts
176+
- name: Build native module (cross)
177+
env:
178+
npm_config_build_from_source: true
179+
npm_config_arch: ${{ matrix.npm_arch }}
180+
npm_config_target_arch: ${{ matrix.npm_arch }}
181+
CC: ${{ matrix.cc }}
182+
CXX: ${{ matrix.cxx }}
183+
AR: ${{ matrix.ar }}
184+
RANLIB: ${{ matrix.ranlib }}
185+
run: |
186+
set -euo pipefail
187+
export PKG_CONFIG_PATH=/usr/lib/${{ matrix.deb_arch }}-linux-gnu/pkgconfig:/usr/lib/${{ matrix.deb_arch }}/pkgconfig:/usr/lib/pkgconfig:$PKG_CONFIG_PATH
188+
export PKG_CONFIG_LIBDIR=/usr/lib/${{ matrix.deb_arch }}-linux-gnu/pkgconfig:/usr/share/pkgconfig
189+
npx node-gyp rebuild --arch=${{ matrix.npm_arch }}
190+
- name: Package artifact
191+
run: |
192+
set -euo pipefail
193+
mkdir -p "${PREBUILT_DIR}/${TARGET_PLATFORM}-${{ matrix.slug }}"
194+
cp build/Release/keymapping.node "${PREBUILT_DIR}/${TARGET_PLATFORM}-${{ matrix.slug }}/keymapping.node"
195+
tar -czf "${PREBUILT_DIR}/native-keymap-${PACKAGE_VERSION}-${TARGET_PLATFORM}-${{ matrix.slug }}.tar.gz" -C "${PREBUILT_DIR}/${TARGET_PLATFORM}-${{ matrix.slug }}" keymapping.node
196+
(cd "${PREBUILT_DIR}" && sha256sum "native-keymap-${PACKAGE_VERSION}-${TARGET_PLATFORM}-${{ matrix.slug }}.tar.gz" > "native-keymap-${PACKAGE_VERSION}-${TARGET_PLATFORM}-${{ matrix.slug }}.tar.gz.sha256")
197+
- uses: actions/upload-artifact@v4
198+
with:
199+
name: native-keymap-${{ env.TARGET_PLATFORM }}-${{ matrix.slug }}
200+
path: |
201+
${{ env.PREBUILT_DIR }}/native-keymap-${{ env.PACKAGE_VERSION }}-${{ env.TARGET_PLATFORM }}-${{ matrix.slug }}.tar.gz
202+
${{ env.PREBUILT_DIR }}/native-keymap-${{ env.PACKAGE_VERSION }}-${{ env.TARGET_PLATFORM }}-${{ matrix.slug }}.tar.gz.sha256
203+
204+
macos-cross:
205+
name: macOS cross (${{ matrix.label }})
206+
needs: metadata
207+
runs-on: macos-13
208+
strategy:
209+
fail-fast: false
210+
matrix:
211+
include:
212+
- label: x64
213+
npm_arch: x64
214+
clang_arch: x86_64
215+
deployment_target: "10.13"
216+
- label: arm64
217+
npm_arch: arm64
218+
clang_arch: arm64
219+
deployment_target: "11.0"
220+
env:
221+
TARGET_PLATFORM: darwin
222+
PACKAGE_VERSION: ${{ needs.metadata.outputs.version }}
223+
steps:
224+
- uses: actions/checkout@v4
225+
- uses: actions/setup-node@v4
226+
with:
227+
node-version-file: '.nvmrc'
228+
- name: Install npm dependencies
229+
run: npm install --no-fund --no-audit --ignore-scripts
230+
- name: Build native module (cross)
231+
env:
232+
npm_config_build_from_source: true
233+
npm_config_arch: ${{ matrix.npm_arch }}
234+
npm_config_target_arch: ${{ matrix.npm_arch }}
235+
CFLAGS: "-arch ${{ matrix.clang_arch }} -mmacosx-version-min=${{ matrix.deployment_target }}"
236+
CXXFLAGS: "-arch ${{ matrix.clang_arch }} -mmacosx-version-min=${{ matrix.deployment_target }}"
237+
LDFLAGS: "-arch ${{ matrix.clang_arch }} -mmacosx-version-min=${{ matrix.deployment_target }}"
238+
run: |
239+
set -euo pipefail
240+
export SDKROOT=$(xcrun --sdk macosx --show-sdk-path)
241+
npx node-gyp rebuild --arch=${{ matrix.npm_arch }}
242+
- name: Package artifact
243+
run: |
244+
set -euo pipefail
245+
mkdir -p "${PREBUILT_DIR}/${TARGET_PLATFORM}-${{ matrix.label }}"
246+
cp build/Release/keymapping.node "${PREBUILT_DIR}/${TARGET_PLATFORM}-${{ matrix.label }}/keymapping.node"
247+
tar -czf "${PREBUILT_DIR}/native-keymap-${PACKAGE_VERSION}-${TARGET_PLATFORM}-${{ matrix.label }}.tar.gz" -C "${PREBUILT_DIR}/${TARGET_PLATFORM}-${{ matrix.label }}" keymapping.node
248+
(cd "${PREBUILT_DIR}" && shasum -a 256 "native-keymap-${PACKAGE_VERSION}-${TARGET_PLATFORM}-${{ matrix.label }}.tar.gz" > "native-keymap-${PACKAGE_VERSION}-${TARGET_PLATFORM}-${{ matrix.label }}.tar.gz.sha256")
249+
- uses: actions/upload-artifact@v4
250+
with:
251+
name: native-keymap-${{ env.TARGET_PLATFORM }}-${{ matrix.label }}
252+
path: |
253+
${{ env.PREBUILT_DIR }}/native-keymap-${{ env.PACKAGE_VERSION }}-${{ env.TARGET_PLATFORM }}-${{ matrix.label }}.tar.gz
254+
${{ env.PREBUILT_DIR }}/native-keymap-${{ env.PACKAGE_VERSION }}-${{ env.TARGET_PLATFORM }}-${{ matrix.label }}.tar.gz.sha256
255+
256+
windows-cross:
257+
name: Windows cross (${{ matrix.arch }})
258+
needs: metadata
259+
runs-on: windows-2022
260+
strategy:
261+
fail-fast: false
262+
matrix:
263+
include:
264+
- arch: x64
265+
vs_arch: x64
266+
- arch: arm64
267+
vs_arch: amd64_arm64
268+
env:
269+
TARGET_PLATFORM: win32
270+
PACKAGE_VERSION: ${{ needs.metadata.outputs.version }}
271+
defaults:
272+
run:
273+
shell: bash
274+
steps:
275+
- uses: actions/checkout@v4
276+
- uses: actions/setup-node@v4
277+
with:
278+
node-version-file: '.nvmrc'
279+
- name: Install npm dependencies
280+
run: npm install --no-fund --no-audit --ignore-scripts
281+
- name: Setup MSVC toolchain
282+
uses: ilammy/msvc-dev-cmd@v1
283+
with:
284+
arch: ${{ matrix.vs_arch }}
285+
- name: Build native module (cross)
286+
env:
287+
npm_config_build_from_source: true
288+
npm_config_arch: ${{ matrix.arch }}
289+
npm_config_target_arch: ${{ matrix.arch }}
290+
run: npx node-gyp rebuild --arch=${{ matrix.arch }}
291+
- name: Package artifact
292+
run: |
293+
set -euo pipefail
294+
mkdir -p "${PREBUILT_DIR}/${TARGET_PLATFORM}-${{ matrix.arch }}"
295+
cp build/Release/keymapping.node "${PREBUILT_DIR}/${TARGET_PLATFORM}-${{ matrix.arch }}/keymapping.node"
296+
tar -czf "${PREBUILT_DIR}/native-keymap-${PACKAGE_VERSION}-${TARGET_PLATFORM}-${{ matrix.arch }}.tar.gz" -C "${PREBUILT_DIR}/${TARGET_PLATFORM}-${{ matrix.arch }}" keymapping.node
297+
- name: Generate checksums
298+
shell: pwsh
299+
run: |
300+
$target = "${env:PREBUILT_DIR}\native-keymap-${env:PACKAGE_VERSION}-${env:TARGET_PLATFORM}-${{ matrix.arch }}.tar.gz"
301+
$hash = (Get-FileHash -Path $target -Algorithm SHA256).Hash
302+
Set-Content -Path "$target.sha256" -Value "$hash $(Split-Path -Leaf $target)"
303+
- uses: actions/upload-artifact@v4
304+
with:
305+
name: native-keymap-${{ env.TARGET_PLATFORM }}-${{ matrix.arch }}
306+
path: |
307+
${{ env.PREBUILT_DIR }}/native-keymap-${{ env.PACKAGE_VERSION }}-${{ env.TARGET_PLATFORM }}-${{ matrix.arch }}.tar.gz
308+
${{ env.PREBUILT_DIR }}/native-keymap-${{ env.PACKAGE_VERSION }}-${{ env.TARGET_PLATFORM }}-${{ matrix.arch }}.tar.gz.sha256
309+
310+
publish:
311+
name: Publish Release
312+
needs:
313+
- metadata
314+
- linux-cross
315+
- macos-cross
316+
- windows-cross
317+
if: needs.metadata.outputs.should_publish == 'true'
318+
runs-on: ubuntu-latest
319+
steps:
320+
- name: Checkout repository
321+
uses: actions/checkout@v4
322+
- name: Setup Node.js for npm publish
323+
uses: actions/setup-node@v4
324+
with:
325+
node-version-file: '.nvmrc'
326+
registry-url: https://registry.npmjs.org
327+
- name: Download artifacts
328+
uses: actions/download-artifact@v4
329+
with:
330+
path: collected-artifacts
331+
- name: Flatten artifact structure
332+
run: |
333+
set -euo pipefail
334+
mkdir -p release
335+
find collected-artifacts -type f -name '*.tar.gz*' -exec cp {} release/ \;
336+
- name: Publish package to npm
337+
if: secrets.NPM_TOKEN != ''
338+
env:
339+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
340+
run: npm publish --access public
341+
- name: Publish release assets
342+
uses: softprops/action-gh-release@v2
343+
with:
344+
tag_name: ${{ needs.metadata.outputs.tag }}
345+
name: native-keymap ${{ needs.metadata.outputs.tag }}
346+
files: release/*
347+
draft: false
348+
prerelease: false

0 commit comments

Comments
 (0)