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