From 4780ec7190dbbeba37f4c28f3fca6544659d3526 Mon Sep 17 00:00:00 2001 From: Zach Bjornson Date: Sun, 26 Apr 2020 12:57:30 -0600 Subject: [PATCH] prebuild with gha --- .github/workflows/prebuild.yaml | 161 ++++++++++++++++++++++++++++ package.json | 2 +- prebuild/Linux/binding.gyp | 53 +++++++++ prebuild/Linux/bundle.sh | 5 + prebuild/Linux/preinstall.sh | 8 ++ prebuild/Windows/binding.gyp | 79 ++++++++++++++ prebuild/Windows/bundle.sh | 19 ++++ prebuild/Windows/exec_with_msys.bat | 8 ++ prebuild/Windows/node_version.sh | 2 + prebuild/Windows/preinstall.sh | 44 ++++++++ prebuild/install.sh | 60 +++++++++++ prebuild/macOS/.gitignore | 1 + prebuild/macOS/binding.gyp | 51 +++++++++ prebuild/macOS/bundle.sh | 4 + prebuild/macOS/preinstall.sh | 4 + prebuild/tarball.sh | 17 +++ 16 files changed, 517 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/prebuild.yaml create mode 100644 prebuild/Linux/binding.gyp create mode 100644 prebuild/Linux/bundle.sh create mode 100644 prebuild/Linux/preinstall.sh create mode 100644 prebuild/Windows/binding.gyp create mode 100644 prebuild/Windows/bundle.sh create mode 100644 prebuild/Windows/exec_with_msys.bat create mode 100644 prebuild/Windows/node_version.sh create mode 100644 prebuild/Windows/preinstall.sh create mode 100644 prebuild/install.sh create mode 100644 prebuild/macOS/.gitignore create mode 100644 prebuild/macOS/binding.gyp create mode 100644 prebuild/macOS/bundle.sh create mode 100644 prebuild/macOS/preinstall.sh create mode 100644 prebuild/tarball.sh diff --git a/.github/workflows/prebuild.yaml b/.github/workflows/prebuild.yaml new file mode 100644 index 000000000..b78002c8b --- /dev/null +++ b/.github/workflows/prebuild.yaml @@ -0,0 +1,161 @@ +name: Make Prebuilds +on: [push] +# TODO: +# on: +# release: +# types: +# - created + +# When a new Node.js version is released, publish a new node-canvas release that +# adds that version to CI and the build? Could do on.push.branches: "master" +# with paths: ".github/workflows/prebuild.yaml", but how do we get the right +# $GITHUB_REF? + +env: + CANVAS_VERSION_TO_BUILD: "2.6.1" # no "v" prefix. TODO switch to $GITHUB_REF if we switch to `on: release` + CANVAS_PREBUILT_VERSION: "0.0.1" + +jobs: + Linux: + strategy: + matrix: + node: [10, 12, 14] + name: Node.js ${{ matrix.node }} on Linux + runs-on: ubuntu-latest + container: + image: chearon/canvas-prebuilt:7 + steps: + - uses: actions/checkout@v2 + + - uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node }} + + - name: Build + env: + OS: ${{ runner.os }} + run: | + npm install -g node-gyp + npm install --ignore-scripts + . prebuild/$OS/preinstall.sh + cp prebuild/$OS/binding.gyp binding.gyp + node-gyp rebuild -j 2 + . prebuild/$OS/bundle.sh + + - name: Test binary + run: node -e "require('.')" + + - name: Make bundle + id: make_bundle + run: | + ASSET_NAME=$(. prebuild/tarball.sh $CANVAS_PREBUILT_VERSION) + echo "::set-output name=asset_name::${ASSET_NAME}" + ls -l + + - name: Upload + uses: actions/github-script@0.9.0 + with: + script: | + const fs = require("fs"); + const assetName = "${{ steps.make_bundle.outputs.asset_name }}"; + const tagName = `v${process.env.CANVAS_PREBUILT_VERSION}`; + + const releases = await github.repos.listReleases({ + owner: process.env.GITHUB_REPOSITORY.split("/")[0], + repo: process.env.GITHUB_REPOSITORY.split("/")[1] + }); + const release = releases.data.find(r => r.tag_name === tagName); + + for (const asset of release.assets) { + if (asset.name === assetName) { + await github.repos.deleteReleaseAsset({ + owner: process.env.GITHUB_REPOSITORY.split("/")[0], + repo: process.env.GITHUB_REPOSITORY.split("/")[1], + asset_id: asset.id + }); + break; + } + } + + // (This is equivalent to actions/upload-release-asset. We're + // already in a script, so might as well do it here.) + const r = await github.repos.uploadReleaseAsset({ + url: release.upload_url, + headers: { + "content-type": "application/x-gzip", + "content-length": `${fs.statSync(assetName).size}` + }, + name: assetName, + data: fs.readFileSync(assetName) + }); + + macOS: + strategy: + matrix: + node: [10, 12, 14] + name: Node.js ${{ matrix.node }} on macOS + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + + - uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node }} + + - name: Build + env: + OS: ${{ runner.os }} + run: | + npm install -g node-gyp + npm install --ignore-scripts + . prebuild/$OS/preinstall.sh + cp prebuild/$OS/binding.gyp binding.gyp + node-gyp rebuild -j 2 + . prebuild/$OS/bundle.sh + + - name: Test binary + run: node -e "require('.')" + + - name: Make bundle + id: make_bundle + run: | + ASSET_NAME=$(. prebuild/tarball.sh $CANVAS_PREBUILT_VERSION) + echo "::set-output name=asset_name::${ASSET_NAME}" + ls -l + + - name: Upload + uses: actions/github-script@0.9.0 + with: + script: | + const fs = require("fs"); + const assetName = "${{ steps.make_bundle.outputs.asset_name }}"; + const tagName = `v${process.env.CANVAS_PREBUILT_VERSION}`; + + const releases = await github.repos.listReleases({ + owner: process.env.GITHUB_REPOSITORY.split("/")[0], + repo: process.env.GITHUB_REPOSITORY.split("/")[1] + }); + const release = releases.data.find(r => r.tag_name === tagName); + + for (const asset of release.assets) { + if (asset.name === assetName) { + await github.repos.deleteReleaseAsset({ + owner: process.env.GITHUB_REPOSITORY.split("/")[0], + repo: process.env.GITHUB_REPOSITORY.split("/")[1], + asset_id: asset.id + }); + break; + } + } + + // (This is equivalent to actions/upload-release-asset. We're + // already in a script, so might as well do it here.) + const r = await github.repos.uploadReleaseAsset({ + url: release.upload_url, + headers: { + "content-type": "application/x-gzip", + "content-length": `${fs.statSync(assetName).size}` + }, + name: assetName, + data: fs.readFileSync(assetName) + }); diff --git a/package.json b/package.json index fe619b0ea..0261c7f3e 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "binary": { "module_name": "canvas", "module_path": "build/Release", - "host": "https://github.com/node-gfx/node-canvas-prebuilt/releases/download/", + "host": "https://github.com/Automattic/node-canvas/releases/download/", "remote_path": "v{version}", "package_name": "{module_name}-v{version}-{node_abi}-{platform}-{libc}-{arch}.tar.gz" }, diff --git a/prebuild/Linux/binding.gyp b/prebuild/Linux/binding.gyp new file mode 100644 index 000000000..1a967667d --- /dev/null +++ b/prebuild/Linux/binding.gyp @@ -0,0 +1,53 @@ +{ + 'targets': [ + { + 'target_name': 'canvas', + 'sources': [ + 'src/backend/Backend.cc', + 'src/backend/ImageBackend.cc', + 'src/backend/PdfBackend.cc', + 'src/backend/SvgBackend.cc', + 'src/bmp/BMPParser.cc', + 'src/Backends.cc', + 'src/Canvas.cc', + 'src/CanvasGradient.cc', + 'src/CanvasPattern.cc', + 'src/CanvasRenderingContext2d.cc', + 'src/closure.cc', + 'src/color.cc', + 'src/Image.cc', + 'src/ImageData.cc', + 'src/init.cc', + 'src/register_font.cc' + ], + 'defines': [ + 'HAVE_GIF', + 'HAVE_JPEG', + 'HAVE_RSVG' + ], + 'libraries': [ + ' /dev/null 2>&1 || { + echo "could not find lib$lib.dll, have to skip "; + continue; + } + + dlltool -d lib$lib.def -l /mingw64/lib/lib$lib.lib > /dev/null 2>&1 || { + echo "could not create dll for lib$lib.dll"; + continue; + } + + echo "created lib$lib.lib from lib$lib.dll"; + + rm lib$lib.def +done + +# dependency walker will help us figure out which DLLs +# canvas.node directly and indirectly uses + +wget -nc http://www.dependencywalker.com/depends22_x64.zip +unzip -u depends22_x64.zip + diff --git a/prebuild/install.sh b/prebuild/install.sh new file mode 100644 index 000000000..8ecaeb130 --- /dev/null +++ b/prebuild/install.sh @@ -0,0 +1,60 @@ +OS=$1; + +if [ "$CANVAS_VERSION_TO_BUILD" = "" ]; then + echo "Can't do anything since you didn't specify which version we're building!"; + echo "Specify the environment variable in AppVeyor/Travis" + echo "Make sure that building pushes is disabled, and that you are executing builds manually." + exit 0; +fi; + +rm -rf node-canvas +git clone --branch v$CANVAS_VERSION_TO_BUILD --depth 1 https://github.com/Automattic/node-canvas.git || { + echo "could not find node-canvas version $CANVAS_VERSION_TO_BUILD in NPM"; + exit 1; +} + +npm install --ignore-scripts || { + echo "failed npm install"; + exit 1; +} + +if [ "$CANVAS_PREBUILT_VERSION" = "" ]; then + echo "You need to specify the prebuilt version, which might be different than the" + echo "canvas version that is being built" + exit 0; +fi; + +source prebuild/$OS/preinstall.sh + +cp prebuild/$OS/binding.gyp node-canvas/binding.gyp + +for ver in $PREBUILD_NODE_VERSIONS; do + echo "------------ Building with node $ver ------------" + + source prebuild/$OS/node_version.sh $ver; + + cd node-canvas + + node-gyp rebuild || { + echo "error building in nodejs version $ver" + exit 1; + } + + cd .. + + source prebuild/$OS/bundle.sh; + + node -e "require('./node-canvas')" || { + echo "error loading binary"; + exit 1; + } + + source prebuild/tarball.sh $CANVAS_PREBUILT_VERSION; +done; + +# echo "------------ Releasing with release.js ------------" +# source prebuild/$OS/node_version.sh 11 +# node prebuild/release.js $PREBUILD_VERSION || exit 1; + +cd .. + diff --git a/prebuild/macOS/.gitignore b/prebuild/macOS/.gitignore new file mode 100644 index 000000000..4110fe0cd --- /dev/null +++ b/prebuild/macOS/.gitignore @@ -0,0 +1 @@ +macdylibbundler/ diff --git a/prebuild/macOS/binding.gyp b/prebuild/macOS/binding.gyp new file mode 100644 index 000000000..00ae2ccbc --- /dev/null +++ b/prebuild/macOS/binding.gyp @@ -0,0 +1,51 @@ +{ + 'targets': [ + { + 'target_name': 'canvas', + 'sources': [ + 'src/backend/Backend.cc', + 'src/backend/ImageBackend.cc', + 'src/backend/PdfBackend.cc', + 'src/backend/SvgBackend.cc', + 'src/bmp/BMPParser.cc', + 'src/Backends.cc', + 'src/Canvas.cc', + 'src/CanvasGradient.cc', + 'src/CanvasPattern.cc', + 'src/CanvasRenderingContext2d.cc', + 'src/closure.cc', + 'src/color.cc', + 'src/Image.cc', + 'src/ImageData.cc', + 'src/init.cc', + 'src/register_font.cc' + ], + 'defines': [ + 'HAVE_GIF', + 'HAVE_JPEG', + 'HAVE_RSVG' + ], + 'libraries': [ + '