WIP: Remove prebuild dependency

This commit is contained in:
Lovell Fuller 2025-06-13 12:41:45 +01:00
parent 5374b036f3
commit f093898e5d
6 changed files with 158 additions and 91 deletions

View File

@ -4,15 +4,12 @@ on:
- pull_request - pull_request
permissions: {} permissions: {}
jobs: jobs:
github-runner: build-native:
permissions: permissions:
contents: write contents: read
name: ${{ matrix.platform }} - Node.js ${{ matrix.nodejs_version_major }} ${{ matrix.prebuild && '- prebuild' }} name: ${{ matrix.platform }} - Node.js ${{ matrix.nodejs_version_major }} ${{ matrix.prebuild && '- prebuild' }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
container: container: ${{ matrix.container }}
image: ${{ matrix.container }}
volumes:
- /:/host
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@ -62,15 +59,6 @@ jobs:
nodejs_version: "^20.3.0" nodejs_version: "^20.3.0"
nodejs_version_major: 20 nodejs_version_major: 20
platform: linux-arm64 platform: linux-arm64
- os: ubuntu-24.04-arm
container: node:18-alpine3.17
nodejs_version_major: 18
platform: linuxmusl-arm64
prebuild: true
- os: ubuntu-24.04-arm
container: node:20-alpine3.18
nodejs_version_major: 20
platform: linuxmusl-arm64
- os: macos-13 - os: macos-13
nodejs_arch: x64 nodejs_arch: x64
nodejs_version: "^18.17.0" nodejs_version: "^18.17.0"
@ -147,16 +135,6 @@ jobs:
nodejs_version_major: 22 nodejs_version_major: 22
platform: win32-arm64 platform: win32-arm64
steps: steps:
- name: Allow Linux musl containers on ARM64 runners # https://github.com/actions/runner/issues/801#issuecomment-2394425757
if: matrix.platform == 'linuxmusl-arm64'
shell: sh
run: |
apk add nodejs
sed -i "s:ID=alpine:ID=NotpineForGHA:" /etc/os-release
cd /host/home/runner/runners/*/externals/
rm -rf node20/*
mkdir node20/bin
ln -s /usr/bin/node node20/bin/node
- name: Dependencies (Rocky Linux glibc) - name: Dependencies (Rocky Linux glibc)
if: contains(matrix.container, 'rockylinux') if: contains(matrix.container, 'rockylinux')
run: | run: |
@ -182,24 +160,65 @@ jobs:
run: npm install --build-from-source run: npm install --build-from-source
- name: Test - name: Test
run: npm test run: npm test
- name: Test packaging - name: Populate npm package
run: | if: matrix.prebuild
npm run package-from-local-build run: npm run package-from-local-build
npm pkg set "optionalDependencies.@img/sharp-${{ matrix.platform }}=file:./npm/${{ matrix.platform }}" - uses: actions/upload-artifact@v4
npm run clean if: matrix.prebuild
npm install --ignore-scripts with:
npm test name: ${{ matrix.platform }}
- name: Prebuild path: npm/${{ matrix.platform }}
if: matrix.prebuild && startsWith(github.ref, 'refs/tags/') retention-days: 1
env: if-no-files-found: error
prebuild_upload: ${{ secrets.GITHUB_TOKEN }} build-linuxmusl-arm-64:
run: |
node -e "require('fs').cpSync('package.json', 'src/package.json')"
cd src
npx prebuild
github-runner-qemu:
permissions: permissions:
contents: write contents: read
name: linuxmusl-arm64 - Node.js ${{ matrix.nodejs_version_major }} ${{ matrix.prebuild && '- prebuild' }}
runs-on: ubuntu-24.04-arm
container:
image: ${{ matrix.container }}
volumes:
- /:/host
strategy:
fail-fast: false
matrix:
include:
- container: node:18-alpine3.17
nodejs_version_major: 18
prebuild: true
- container: node:20-alpine3.18
nodejs_version_major: 20
steps:
- name: Allow Linux musl containers on ARM64 runners # https://github.com/actions/runner/issues/801#issuecomment-2394425757
shell: sh
run: |
apk add nodejs
sed -i "s:ID=alpine:ID=NotpineForGHA:" /etc/os-release
cd /host/home/runner/runners/*/externals/
rm -rf node20/*
mkdir node20/bin
ln -s /usr/bin/node node20/bin/node
- name: Dependencies
run: apk add build-base git python3 font-noto --update-cache
- name: Checkout
uses: actions/checkout@v4
- name: Install
run: npm install --build-from-source
- name: Test
run: npm test
- name: Populate npm package
if: matrix.prebuild
run: npm run package-from-local-build
- uses: actions/upload-artifact@v4
if: matrix.prebuild
with:
name: linuxmusl-arm64
path: npm/linuxmusl-arm64
retention-days: 1
if-no-files-found: error
build-qemu:
permissions:
contents: read
name: ${{ matrix.platform }} - Node.js ${{ matrix.nodejs_version_major }} - prebuild name: ${{ matrix.platform }} - Node.js ${{ matrix.nodejs_version_major }} - prebuild
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
strategy: strategy:
@ -233,8 +252,6 @@ jobs:
with: with:
arch: ${{ matrix.run_on_arch }} arch: ${{ matrix.run_on_arch }}
distro: ${{ matrix.distro }} distro: ${{ matrix.distro }}
env: |
prebuild_upload: "${{ startsWith(github.ref, 'refs/tags/') && secrets.GITHUB_TOKEN || '' }}"
run: | run: |
apt-get update apt-get update
apt-get install -y curl g++ git libatomic1 make python3 xz-utils apt-get install -y curl g++ git libatomic1 make python3 xz-utils
@ -244,14 +261,15 @@ jobs:
npm install --build-from-source npm install --build-from-source
npx mocha --no-config --spec=test/unit/io.js --timeout=30000 npx mocha --no-config --spec=test/unit/io.js --timeout=30000
npm run package-from-local-build npm run package-from-local-build
npm pkg set "optionalDependencies.@img/sharp-${{ matrix.platform }}=file:./npm/${{ matrix.platform }}" - uses: actions/upload-artifact@v4
npm run clean with:
npm install --ignore-scripts name: ${{ matrix.platform }}
npx mocha --no-config --spec=test/unit/io.js --timeout=30000 path: npm/${{ matrix.platform }}
[[ -n $prebuild_upload ]] && cd src && ln -s ../package.json && npx prebuild || true retention-days: 1
github-runner-emscripten: if-no-files-found: error
build-emscripten:
permissions: permissions:
contents: write contents: read
name: wasm32 - prebuild name: wasm32 - prebuild
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
container: "emscripten/emsdk:4.0.10" container: "emscripten/emsdk:4.0.10"
@ -275,17 +293,36 @@ jobs:
test "$EMSCRIPTEN_VERSION_LIBVIPS" = "$EMSCRIPTEN_VERSION_SHARP" test "$EMSCRIPTEN_VERSION_LIBVIPS" = "$EMSCRIPTEN_VERSION_SHARP"
- name: Test - name: Test
run: emmake npm test run: emmake npm test
- name: Test packaging - name: Populate npm package
run: | run: emmake npm run package-from-local-build
emmake npm run package-from-local-build - uses: actions/upload-artifact@v4
npm pkg set "optionalDependencies.@img/sharp-wasm32=file:./npm/wasm32" with:
npm run clean name: wasm32
rm -rf node_modules/@img/sharp-linux-x64 path: npm/wasm32
npm install --cpu=wasm32 retention-days: 1
npm test if-no-files-found: error
- name: Prebuild release:
if: startsWith(github.ref, 'refs/tags/') permissions:
env: contents: write
npm_config_nodedir: emscripten name: Create release
prebuild_upload: ${{ secrets.GITHUB_TOKEN }} runs-on: ubuntu-24.04
run: cd src && ln -s ../package.json && emmake npx prebuild --platform=emscripten --arch=wasm32 --strip=0 needs:
- build-native
- build-linuxmusl-arm-64
- build-qemu
- build-emscripten
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
path: npm
- name: Create npm workspace tarball
run: tar -vcaf npm-workspace.tar.xz -C npm .
- name: Create GitHub release for tag
if: startsWith(github.ref, 'refs/tags/v')
uses: ncipollo/release-action@v1
with:
artifacts: npm-workspace.tar.xz
artifactContentType: application/x-xz
prerelease: ${{ contains(github.ref, '-rc') }}
makeLatest: ${{ !contains(github.ref, '-rc') }}

View File

@ -1,6 +0,0 @@
{
"runtime": "napi",
"include-regex": "(sharp-.+\\.node|libvips-.+\\.dll)",
"prerelease": true,
"strip": true
}

View File

@ -123,7 +123,7 @@ const yarnLocator = () => {
/* istanbul ignore next */ /* istanbul ignore next */
const spawnRebuild = () => const spawnRebuild = () =>
spawnSync(`node-gyp rebuild --directory=src ${isEmscripten() ? '--nodedir=emscripten' : ''}`, { spawnSync(`node-gyp rebuild --verbose --directory=src ${isEmscripten() ? '--nodedir=emscripten' : ''}`, {
...spawnSyncOptions, ...spawnSyncOptions,
stdio: 'inherit' stdio: 'inherit'
}).status; }).status;

View File

@ -3,24 +3,62 @@
'use strict'; 'use strict';
// Populate contents of a single npm/sharpen-sharp-<build-platform> package // Populate the npm package for the current platform with the local build
// with the local/CI build directory for local/CI prebuild testing
const fs = require('node:fs'); const { copyFileSync, cpSync, readFileSync, writeFileSync, appendFileSync } = require('node:fs');
const path = require('node:path'); const { basename, join } = require('node:path');
const { buildPlatformArch } = require('../lib/libvips'); const { buildPlatformArch } = require('../lib/libvips');
const platform = buildPlatformArch();
const dest = path.join(__dirname, platform);
// Use same config as prebuild to copy binary files const licensing = `
const release = path.join(__dirname, '..', 'src', 'build', 'Release'); ## Licensing
const prebuildrc = JSON.parse(fs.readFileSync(path.join(__dirname, '..', '.prebuildrc'), 'utf8'));
const include = new RegExp(prebuildrc['include-regex'], 'i'); Copyright 2013 Lovell Fuller and others.
fs.cpSync(release, path.join(dest, 'lib'), {
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
[https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0)
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
`;
const platform = buildPlatformArch();
const destDir = join(__dirname, platform);
console.log(`Populating npm package for platform: ${platform}`);
// Copy binaries
const releaseDir = join(__dirname, '..', 'src', 'build', 'Release');
const libDir = join(destDir, 'lib');
cpSync(releaseDir, libDir, {
recursive: true, recursive: true,
filter: (file) => { filter: (file) => {
const name = path.basename(file); const name = basename(file);
return name === 'Release' || include.test(name); return name === 'Release' ||
(name.startsWith('sharp-') && name.endsWith('.node')) ||
(name.startsWith('libvips-') && name.endsWith('.dll'));
} }
}); });
// Generate README
const { name, description } = require(`./${platform}/package.json`);
writeFileSync(join(destDir, 'README.md'), `# \`${name}\`\n\n${description}.\n${licensing}`);
// Copy Apache-2.0 LICENSE
copyFileSync(join(__dirname, '..', 'LICENSE'), join(destDir, 'LICENSE'));
// Copy files for packages without an explicit sharp-libvips dependency (Windows, wasm)
if (platform.startsWith('win') || platform.startsWith('wasm')) {
const libvipsPlatform = platform === 'wasm32' ? 'dev-wasm32' : platform;
const sharpLibvipsDir = join(require(`@img/sharp-libvips-${libvipsPlatform}/lib`), '..');
// Copy versions.json
copyFileSync(join(sharpLibvipsDir, 'versions.json'), join(destDir, 'versions.json'));
// Append third party licensing to README
const readme = readFileSync(join(sharpLibvipsDir, 'README.md'), { encoding: 'utf-8' });
const thirdParty = readme.substring(readme.indexOf('\nThis software contains'));
appendFileSync(join(destDir, 'README.md'), thirdParty);
}

View File

@ -155,6 +155,7 @@
"@img/sharp-libvips-linuxmusl-x64": "1.2.0-rc.2", "@img/sharp-libvips-linuxmusl-x64": "1.2.0-rc.2",
"@img/sharp-linux-arm": "0.34.2", "@img/sharp-linux-arm": "0.34.2",
"@img/sharp-linux-arm64": "0.34.2", "@img/sharp-linux-arm64": "0.34.2",
"@img/sharp-linux-ppc64": "0.34.2",
"@img/sharp-linux-s390x": "0.34.2", "@img/sharp-linux-s390x": "0.34.2",
"@img/sharp-linux-x64": "0.34.2", "@img/sharp-linux-x64": "0.34.2",
"@img/sharp-linuxmusl-arm64": "0.34.2", "@img/sharp-linuxmusl-arm64": "0.34.2",
@ -181,8 +182,8 @@
"license-checker": "^25.0.1", "license-checker": "^25.0.1",
"mocha": "^11.6.0", "mocha": "^11.6.0",
"node-addon-api": "^8.3.1", "node-addon-api": "^8.3.1",
"node-gyp": "^11.2.0",
"nyc": "^17.1.0", "nyc": "^17.1.0",
"prebuild": "^13.0.1",
"semistandard": "^17.0.0", "semistandard": "^17.0.0",
"tar-fs": "^3.0.9", "tar-fs": "^3.0.9",
"tsd": "^0.32.0" "tsd": "^0.32.0"
@ -197,11 +198,6 @@
"funding": { "funding": {
"url": "https://opencollective.com/libvips" "url": "https://opencollective.com/libvips"
}, },
"binary": {
"napi_versions": [
9
]
},
"semistandard": { "semistandard": {
"env": [ "env": [
"mocha" "mocha"

View File

@ -163,6 +163,8 @@
}, },
'xcode_settings': { 'xcode_settings': {
'OTHER_LDFLAGS': [ 'OTHER_LDFLAGS': [
'-Wl,-s',
'-Wl,-dead_strip',
# Ensure runtime linking is relative to sharp.node # Ensure runtime linking is relative to sharp.node
'-Wl,-rpath,\'@loader_path/../../sharp-libvips-<(platform_and_arch)/lib\'', '-Wl,-rpath,\'@loader_path/../../sharp-libvips-<(platform_and_arch)/lib\'',
'-Wl,-rpath,\'@loader_path/../../../sharp-libvips-<(platform_and_arch)/<(sharp_libvips_version)/lib\'', '-Wl,-rpath,\'@loader_path/../../../sharp-libvips-<(platform_and_arch)/<(sharp_libvips_version)/lib\'',