Fixing the internalModuleReadJSON boot crash let Node 20 actually run the integration suite for the first time - it used to crash at Node's own startup before any test code ran. That exposed a real, previously latent failure: "resolves modules from the real fs" can't find a genuinely non-bundled package via the real-fs fallback. Passes on Windows + Node 22.23.1, so it's specific to Linux and/or Node 20 specifically - not yet isolated which. Pulling Node 20 out of the matrix until that's root-caused (see project notes).
227 lines
8.3 KiB
YAML
227 lines
8.3 KiB
YAML
name: Build and test asset
|
||
|
||
on:
|
||
schedule:
|
||
- cron: '0 10 * * 1' # every Monday at 10:00 UTC
|
||
workflow_dispatch:
|
||
inputs:
|
||
versions:
|
||
description: 'Node.js version(s) as JSON array'
|
||
required: true
|
||
default: '[ "lts/*", "22", "24" ]'
|
||
publish:
|
||
description: 'Attach built assets to the release for the current package.json version'
|
||
type: boolean
|
||
default: false
|
||
pull_request:
|
||
branches: [ master ]
|
||
push:
|
||
tags: [ '*' ]
|
||
|
||
permissions:
|
||
contents: write
|
||
|
||
jobs:
|
||
build:
|
||
runs-on: ${{ matrix.os }}
|
||
strategy:
|
||
fail-fast: false
|
||
matrix:
|
||
os: [ windows-latest, macos-latest, ubuntu-latest ]
|
||
# Use the input versions if provided, otherwise fall back to default
|
||
version: ${{ fromJSON(inputs.versions || '[ "lts/*", "22", "24" ]') }}
|
||
env:
|
||
NEXE_ASSET: ${{ github.workspace }}/nexe-asset
|
||
NEXE_TMP_CACHE_PATH: ${{ github.workspace }}/nexe-tmp
|
||
NEXE_TMP: ${{ github.workspace }}/nexe-tmp/standard
|
||
CCACHE_COMPRESS: '1'
|
||
ErrorView: NormalView
|
||
steps:
|
||
# Checkout repository
|
||
- uses: actions/checkout@v4
|
||
|
||
# Set up Node.js (using matrix version)
|
||
- uses: actions/setup-node@v4
|
||
with:
|
||
node-version: ${{ matrix.version }}
|
||
|
||
# Record the exact Node.js version for later use (cross‑platform)
|
||
- name: Record exact Node.js version
|
||
shell: bash
|
||
run: echo "NODEJS_VERSION=$(node -p process.versions.node)" >> $GITHUB_ENV
|
||
|
||
# Install Node dependencies
|
||
- run: npm ci
|
||
|
||
# Python may be needed for native addons
|
||
- uses: actions/setup-python@v5
|
||
with:
|
||
python-version: '3.9'
|
||
|
||
# Windows: install NASM (required for some native modules)
|
||
- if: startsWith(matrix.os, 'windows')
|
||
run: choco install nasm
|
||
|
||
# Windows: current runner images (windows-2025-vs2026, also served for
|
||
# the windows-2025 label) only ship Visual Studio 2026, but Node's
|
||
# vcbuild.bat searches for VS 2022 — install the 2022 Build Tools with
|
||
# the VC workload (Node's documented setup path). The Clang components
|
||
# are needed for Node 24+ (vcbuild requires ClangCL); without them it
|
||
# falls back to VS 2026's Clang 22, which is too new and turns the
|
||
# uint32_t*/unsigned long* mismatch in deps/histogram into a hard error.
|
||
- if: startsWith(matrix.os, 'windows')
|
||
run: choco install visualstudio2022-workload-vctools -y --no-progress --package-parameters "--add Microsoft.VisualStudio.Component.VC.Llvm.Clang --add Microsoft.VisualStudio.Component.VC.Llvm.ClangToolset"
|
||
timeout-minutes: 30
|
||
|
||
# Ubuntu: update package lists (kept for safety, can be removed if not needed)
|
||
- if: matrix.os == 'ubuntu-latest'
|
||
run: sudo apt-get update
|
||
|
||
# Linux/macOS: enable compiler caching with ccache
|
||
- if: ${{ !startsWith(matrix.os, 'windows') }}
|
||
uses: hendrikmuhs/ccache-action@v1.2
|
||
with:
|
||
create-symlink: true
|
||
key: ${{ github.job }}-${{ matrix.os }}-${{ matrix.version }}
|
||
|
||
# Windows: adjust asset name and suffix
|
||
- if: startsWith(matrix.os, 'windows')
|
||
shell: bash
|
||
run: |
|
||
echo "NEXE_ASSET=${NEXE_ASSET}.exe" >> $GITHUB_ENV
|
||
echo "EXECUTABLE_SUFFIX=.exe" >> $GITHUB_ENV
|
||
# Force vcbuild to use VS 2022: Node 24's vcbuild prefers VS 2026,
|
||
# whose Clang 22 fails on deps/histogram (uint32_t*/unsigned long*
|
||
# mismatch is a hard error there). vs2022 is accepted by Node 22
|
||
# and 24 alike.
|
||
echo "NEXE_VCBUILD=nosign,release,vs2022" >> $GITHUB_ENV
|
||
|
||
# Main build & test (asset + integration)
|
||
- name: Build and test asset
|
||
run: node tasks/asset-build && node tasks/asset-test-build && npm run test:integration:run
|
||
|
||
# Rename the built asset to include target platform info
|
||
- name: Update release artifact name
|
||
shell: bash
|
||
run: |
|
||
nexe_target="$(node -p 'require("./lib/target").getTarget().toString()')"
|
||
echo "NEXE_TARGET=${nexe_target}" >> $GITHUB_ENV
|
||
artefact_name="nexe-asset-${nexe_target}"
|
||
mv "${NEXE_ASSET}" "${artefact_name}"
|
||
echo "NEXE_ASSET=${artefact_name}" >> $GITHUB_ENV
|
||
echo "RELEASE_TAG=v$(node -p 'require("./package.json").version')" >> $GITHUB_ENV
|
||
|
||
# Upload main asset
|
||
- name: Upload asset artifact
|
||
uses: actions/upload-artifact@v4
|
||
with:
|
||
name: ${{ env.NEXE_ASSET }}
|
||
path: ${{ env.NEXE_ASSET }}
|
||
if-no-files-found: error
|
||
|
||
# Upload integration test binary
|
||
- name: Upload integration test artifact
|
||
uses: actions/upload-artifact@v4
|
||
with:
|
||
name: integration-tests-${{ env.NEXE_TARGET }}${{ env.EXECUTABLE_SUFFIX }}
|
||
path: integration-tests${{ env.EXECUTABLE_SUFFIX }}
|
||
if-no-files-found: error
|
||
|
||
# Attach the asset to the release: on tag push, or on manual dispatch
|
||
# with publish=true (attaches to the release for package.json's version)
|
||
- if: startsWith(github.ref, 'refs/tags/')
|
||
uses: softprops/action-gh-release@v2
|
||
with:
|
||
fail_on_unmatched_files: true
|
||
prerelease: true
|
||
files: ${{ env.NEXE_ASSET }}
|
||
|
||
- if: github.event_name == 'workflow_dispatch' && inputs.publish
|
||
uses: softprops/action-gh-release@v2
|
||
with:
|
||
tag_name: ${{ env.RELEASE_TAG }}
|
||
fail_on_unmatched_files: true
|
||
prerelease: true
|
||
files: ${{ env.NEXE_ASSET }}
|
||
|
||
# Alpine (musl) static builds run natively in a musl container. The old
|
||
# node-musl cross toolchain (last release 2023) ships a GCC too old for
|
||
# Node 22+/V8 (needs GCC 12.2+); Alpine's native GCC is current.
|
||
build-musl:
|
||
runs-on: ubuntu-latest
|
||
container: node:${{ matrix.version }}-alpine
|
||
strategy:
|
||
fail-fast: false
|
||
matrix:
|
||
version: [ 'lts', '22', '24' ]
|
||
env:
|
||
NEXE_ASSET: ${{ github.workspace }}/nexe-asset
|
||
NEXE_TMP: ${{ github.workspace }}/nexe-tmp/musl
|
||
MUSL_BUILD: 'yes'
|
||
PYTHON: python3
|
||
CCACHE_COMPRESS: '1'
|
||
CCACHE_DIR: /root/.cache/ccache
|
||
steps:
|
||
# git/tar/zstd so checkout and cache actions work in the container
|
||
- name: Install build dependencies
|
||
run: apk add --no-cache build-base linux-headers python3 py3-setuptools git bash tar zstd ccache
|
||
|
||
- uses: actions/checkout@v4
|
||
|
||
- name: Record exact Node.js version
|
||
run: echo "NODEJS_VERSION=$(node -p process.versions.node)" >> $GITHUB_ENV
|
||
|
||
- run: npm ci
|
||
|
||
- name: ccache cache
|
||
uses: actions/cache@v4
|
||
with:
|
||
path: /root/.cache/ccache
|
||
key: ccache-musl-${{ matrix.version }}-${{ github.run_id }}
|
||
restore-keys: ccache-musl-${{ matrix.version }}-
|
||
|
||
- name: Build and test asset
|
||
shell: bash
|
||
run: |
|
||
export CC="ccache gcc" CXX="ccache g++"
|
||
node tasks/asset-build && node tasks/asset-test-build && npm run test:integration:run
|
||
|
||
- name: Update release artifact name
|
||
shell: bash
|
||
run: |
|
||
nexe_target="$(node -p 'require("./lib/target").getTarget({ platform: "static" }).toString()')"
|
||
echo "NEXE_TARGET=${nexe_target}" >> $GITHUB_ENV
|
||
artefact_name="nexe-asset-${nexe_target}"
|
||
mv "${NEXE_ASSET}" "${artefact_name}"
|
||
echo "NEXE_ASSET=${artefact_name}" >> $GITHUB_ENV
|
||
echo "RELEASE_TAG=v$(node -p 'require("./package.json").version')" >> $GITHUB_ENV
|
||
|
||
- name: Upload asset artifact
|
||
uses: actions/upload-artifact@v4
|
||
with:
|
||
name: ${{ env.NEXE_ASSET }}
|
||
path: ${{ env.NEXE_ASSET }}
|
||
if-no-files-found: error
|
||
|
||
- name: Upload integration test artifact
|
||
uses: actions/upload-artifact@v4
|
||
with:
|
||
name: integration-tests-${{ env.NEXE_TARGET }}
|
||
path: integration-tests
|
||
if-no-files-found: error
|
||
|
||
- if: startsWith(github.ref, 'refs/tags/')
|
||
uses: softprops/action-gh-release@v2
|
||
with:
|
||
fail_on_unmatched_files: true
|
||
prerelease: true
|
||
files: ${{ env.NEXE_ASSET }}
|
||
|
||
- if: github.event_name == 'workflow_dispatch' && inputs.publish
|
||
uses: softprops/action-gh-release@v2
|
||
with:
|
||
tag_name: ${{ env.RELEASE_TAG }}
|
||
fail_on_unmatched_files: true
|
||
prerelease: true
|
||
files: ${{ env.NEXE_ASSET }}
|