Skip to content

Commit 0d9ca88

Browse files
zbjornsonchearon
authored andcommitted
Move prebuilds to GitHub Actions
1 parent fe186e5 commit 0d9ca88

14 files changed

+533
-2
lines changed

.github/workflows/ci.yaml

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
name: Test
2-
on: [push, pull_request]
2+
on:
3+
push:
4+
paths-ignore:
5+
- ".github/workflows/prebuild.yaml"
6+
pull_request:
7+
paths-ignore:
8+
- ".github/workflows/prebuild.yaml"
9+
310

411
jobs:
512
Linux:

.github/workflows/prebuild.yaml

+238
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
# Triggering prebuilds:
2+
# 1. Create a draft release manually using the GitHub UI.
3+
# 2. Set the `jobs.*.strategy.matrix.node` arrays to the set of Node.js versions
4+
# to build for.
5+
# 3. Set the `jobs.*.strategy.matrix.canvas_tag` arrays to the set of Canvas
6+
# tags to build. (Usually this is a single tag, but can be an array when a
7+
# new version of Node.js is released and older versions of Canvas need to be
8+
# built.)
9+
# 4. Commit and push this file to master.
10+
# 5. Once the builds succeed, promote the draft release to a full release.
11+
12+
name: Make Prebuilds
13+
on:
14+
push:
15+
branches:
16+
- 'master'
17+
paths:
18+
- '.github/workflows/prebuild.yaml'
19+
# UPLOAD_TO can be specified to upload the release assets under a different tag
20+
# name (e.g. for testing). If omitted, the assets are published under the same
21+
# release tag as the canvas version being built.
22+
# env:
23+
# UPLOAD_TO: "v0.0.1"
24+
25+
jobs:
26+
Linux:
27+
strategy:
28+
matrix:
29+
node: [8, 9, 10, 11, 12, 13, 14]
30+
canvas_tag: [] # e.g. "v2.6.1"
31+
name: ${{ matrix.canvas_tag}}, Node.js ${{ matrix.node }}, Linux
32+
runs-on: ubuntu-latest
33+
container:
34+
image: chearon/canvas-prebuilt:7
35+
env:
36+
CANVAS_VERSION_TO_BUILD: ${{ matrix.canvas_tag }}
37+
steps:
38+
- uses: actions/checkout@v2
39+
with:
40+
ref: ${{ matrix.canvas_tag }}
41+
42+
- uses: actions/setup-node@v1
43+
with:
44+
node-version: ${{ matrix.node }}
45+
46+
- name: Build
47+
run: |
48+
npm install -g node-gyp
49+
npm install --ignore-scripts
50+
. prebuild/Linux/preinstall.sh
51+
cp prebuild/Linux/binding.gyp binding.gyp
52+
node-gyp rebuild -j 2
53+
. prebuild/Linux/bundle.sh
54+
55+
- name: Test binary
56+
run: |
57+
cd /root/harfbuzz-* && make uninstall
58+
cd /root/cairo-* && make uninstall
59+
cd /root/pango-* && make uninstall
60+
cd /root/libpng-* && make uninstall
61+
cd /root/libjpeg-* && make uninstall
62+
cd /root/giflib-* && make uninstall
63+
cd $GITHUB_WORKSPACE && npm test
64+
65+
- name: Make bundle
66+
id: make_bundle
67+
run: . prebuild/tarball.sh
68+
69+
- name: Upload
70+
uses: actions/[email protected]
71+
with:
72+
script: |
73+
const fs = require("fs");
74+
const assetName = "${{ steps.make_bundle.outputs.asset_name }}";
75+
const tagName = process.env.UPLOAD_TO || process.env.CANVAS_VERSION_TO_BUILD;
76+
const [owner, repo] = process.env.GITHUB_REPOSITORY.split("/");
77+
78+
const releases = await github.repos.listReleases({owner, repo});
79+
const release = releases.data.find(r => r.tag_name === tagName);
80+
if (!release)
81+
throw new Error(`Tag ${tagName} not found. Did you make the GitHub release?`);
82+
83+
const oldAsset = release.assets.find(a => a.name === assetName);
84+
if (oldAsset)
85+
await github.repos.deleteReleaseAsset({owner, repo, asset_id: oldAsset.id});
86+
87+
// (This is equivalent to actions/upload-release-asset. We're
88+
// already in a script, so might as well do it here.)
89+
const r = await github.repos.uploadReleaseAsset({
90+
url: release.upload_url,
91+
headers: {
92+
"content-type": "application/x-gzip",
93+
"content-length": `${fs.statSync(assetName).size}`
94+
},
95+
name: assetName,
96+
data: fs.readFileSync(assetName)
97+
});
98+
99+
macOS:
100+
strategy:
101+
matrix:
102+
node: [8, 9, 10, 11, 12, 13, 14]
103+
canvas_tag: [] # e.g. "v2.6.1"
104+
name: ${{ matrix.canvas_tag}}, Node.js ${{ matrix.node }}, macOS
105+
runs-on: macos-latest
106+
env:
107+
CANVAS_VERSION_TO_BUILD: ${{ matrix.canvas_tag }}
108+
steps:
109+
- uses: actions/checkout@v2
110+
with:
111+
ref: ${{ matrix.canvas_tag }}
112+
113+
- uses: actions/setup-node@v1
114+
with:
115+
node-version: ${{ matrix.node }}
116+
117+
- name: Build
118+
run: |
119+
npm install -g node-gyp
120+
npm install --ignore-scripts
121+
. prebuild/macOS/preinstall.sh
122+
cp prebuild/macOS/binding.gyp binding.gyp
123+
node-gyp rebuild -j 2
124+
. prebuild/macOS/bundle.sh
125+
126+
- name: Test binary
127+
run: |
128+
brew uninstall --force cairo pango librsvg giflib harfbuzz
129+
npm test
130+
131+
- name: Make bundle
132+
id: make_bundle
133+
run: . prebuild/tarball.sh
134+
135+
- name: Upload
136+
uses: actions/[email protected]
137+
with:
138+
script: |
139+
const fs = require("fs");
140+
const assetName = "${{ steps.make_bundle.outputs.asset_name }}";
141+
const tagName = process.env.UPLOAD_TO || process.env.CANVAS_VERSION_TO_BUILD;
142+
const [owner, repo] = process.env.GITHUB_REPOSITORY.split("/");
143+
144+
const releases = await github.repos.listReleases({owner, repo});
145+
const release = releases.data.find(r => r.tag_name === tagName);
146+
if (!release)
147+
throw new Error(`Tag ${tagName} not found. Did you make the GitHub release?`);
148+
149+
const oldAsset = release.assets.find(a => a.name === assetName);
150+
if (oldAsset)
151+
await github.repos.deleteReleaseAsset({owner, repo, asset_id: oldAsset.id});
152+
153+
// (This is equivalent to actions/upload-release-asset. We're
154+
// already in a script, so might as well do it here.)
155+
const r = await github.repos.uploadReleaseAsset({
156+
url: release.upload_url,
157+
headers: {
158+
"content-type": "application/x-gzip",
159+
"content-length": `${fs.statSync(assetName).size}`
160+
},
161+
name: assetName,
162+
data: fs.readFileSync(assetName)
163+
});
164+
165+
Win:
166+
strategy:
167+
matrix:
168+
node: [8, 9, 10, 11, 12, 13, 14]
169+
canvas_tag: [] # e.g. "v2.6.1"
170+
name: ${{ matrix.canvas_tag}}, Node.js ${{ matrix.node }}, Windows
171+
runs-on: windows-latest
172+
env:
173+
CANVAS_VERSION_TO_BUILD: ${{ matrix.canvas_tag }}
174+
steps:
175+
# TODO drop when https://github.com/actions/virtual-environments/pull/632 lands
176+
- uses: numworks/setup-msys2@v1
177+
with:
178+
update: true
179+
path-type: inherit
180+
181+
- uses: actions/setup-node@v1
182+
with:
183+
node-version: ${{ matrix.node }}
184+
185+
- uses: actions/checkout@v2
186+
with:
187+
ref: ${{ matrix.canvas_tag }}
188+
189+
- name: Build
190+
run: |
191+
npm install -g node-gyp
192+
npm install --ignore-scripts
193+
msys2do . prebuild/Windows/preinstall.sh
194+
msys2do cp prebuild/Windows/binding.gyp binding.gyp
195+
msys2do node-gyp configure
196+
msys2do node-gyp rebuild -j 2
197+
198+
- name: Bundle
199+
run: msys2do . prebuild/Windows/bundle.sh
200+
201+
- name: Test binary
202+
# By not running in msys2, this doesn't have access to the msys2 libs
203+
run: npm test
204+
205+
- name: Make asset
206+
id: make_bundle
207+
# I can't figure out why this isn't an env var already. It shows up with `env`.
208+
run: msys2do UPLOAD_TO=${{ env.UPLOAD_TO }} CANVAS_VERSION_TO_BUILD=${{ env.CANVAS_VERSION_TO_BUILD}} . prebuild/tarball.sh
209+
210+
- name: Upload
211+
uses: actions/[email protected]
212+
with:
213+
script: |
214+
const fs = require("fs");
215+
const assetName = "${{ steps.make_bundle.outputs.asset_name }}";
216+
const tagName = process.env.UPLOAD_TO || process.env.CANVAS_VERSION_TO_BUILD;
217+
const [owner, repo] = process.env.GITHUB_REPOSITORY.split("/");
218+
219+
const releases = await github.repos.listReleases({owner, repo});
220+
const release = releases.data.find(r => r.tag_name === tagName);
221+
if (!release)
222+
throw new Error(`Tag ${tagName} not found. Did you make the GitHub release?`);
223+
224+
const oldAsset = release.assets.find(a => a.name === assetName);
225+
if (oldAsset)
226+
await github.repos.deleteReleaseAsset({owner, repo, asset_id: oldAsset.id});
227+
228+
// (This is equivalent to actions/upload-release-asset. We're
229+
// already in a script, so might as well do it here.)
230+
const r = await github.repos.uploadReleaseAsset({
231+
url: release.upload_url,
232+
headers: {
233+
"content-type": "application/x-gzip",
234+
"content-length": `${fs.statSync(assetName).size}`
235+
},
236+
name: assetName,
237+
data: fs.readFileSync(assetName)
238+
});

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ project adheres to [Semantic Versioning](http://semver.org/).
99
==================
1010
### Changed
1111
* Switch CI to Github Actions. (Adds Windows and macOS builds.)
12+
* Switch prebuilds to GitHub actions in the Automattic/node-canvas repository.
13+
Previously these were in the [node-gfx/node-canvas-prebuilt](https://github.com/node-gfx/node-canvas-prebuilt)
14+
and triggered manually.
1215
### Added
1316
* Export `rsvgVersion`.
1417
### Fixed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
"binary": {
3636
"module_name": "canvas",
3737
"module_path": "build/Release",
38-
"host": "https://github.com/node-gfx/node-canvas-prebuilt/releases/download/",
38+
"host": "https://github.com/Automattic/node-canvas/releases/download/",
3939
"remote_path": "v{version}",
4040
"package_name": "{module_name}-v{version}-{node_abi}-{platform}-{libc}-{arch}.tar.gz"
4141
},

prebuild/Linux/binding.gyp

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
{
2+
'targets': [
3+
{
4+
'target_name': 'canvas',
5+
'sources': [
6+
'src/backend/Backend.cc',
7+
'src/backend/ImageBackend.cc',
8+
'src/backend/PdfBackend.cc',
9+
'src/backend/SvgBackend.cc',
10+
'src/bmp/BMPParser.cc',
11+
'src/Backends.cc',
12+
'src/Canvas.cc',
13+
'src/CanvasGradient.cc',
14+
'src/CanvasPattern.cc',
15+
'src/CanvasRenderingContext2d.cc',
16+
'src/closure.cc',
17+
'src/color.cc',
18+
'src/Image.cc',
19+
'src/ImageData.cc',
20+
'src/init.cc',
21+
'src/register_font.cc'
22+
],
23+
'defines': [
24+
'HAVE_GIF',
25+
'HAVE_JPEG',
26+
'HAVE_RSVG'
27+
],
28+
'libraries': [
29+
'<!@(pkg-config pixman-1 --libs)',
30+
'<!@(pkg-config cairo --libs)',
31+
'<!@(pkg-config libpng --libs)',
32+
'<!@(pkg-config pangocairo --libs)',
33+
'<!@(pkg-config freetype2 --libs)',
34+
'<!@(pkg-config librsvg-2.0 --libs)',
35+
'-ljpeg',
36+
'-lgif'
37+
],
38+
'include_dirs': [
39+
'<!(node -e "require(\'nan\')")',
40+
'<!@(pkg-config cairo --cflags-only-I | sed s/-I//g)',
41+
'<!@(pkg-config libpng --cflags-only-I | sed s/-I//g)',
42+
'<!@(pkg-config pangocairo --cflags-only-I | sed s/-I//g)',
43+
'<!@(pkg-config freetype2 --cflags-only-I | sed s/-I//g)',
44+
'<!@(pkg-config librsvg-2.0 --cflags-only-I | sed s/-I//g)'
45+
],
46+
'ldflags': [
47+
'-Wl,-rpath \'-Wl,$$ORIGIN\''
48+
],
49+
'cflags!': ['-fno-exceptions'],
50+
'cflags_cc!': ['-fno-exceptions']
51+
}
52+
]
53+
}

prebuild/Linux/bundle.sh

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
copies=$(lddtree.sh -l build/Release/canvas.node | sed -r -e '/^\/lib/d' -e '/canvas.node$/d');
2+
3+
for so in $copies; do
4+
cp $so build/Release
5+
done;

prebuild/Linux/preinstall.sh

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# apt-get-style dependencies aren't done here since the
2+
# linux build is done on a docker image that has them
3+
4+
git clone git://anongit.gentoo.org/proj/pax-utils.git
5+
cd pax-utils
6+
PATH=$PATH:$PWD
7+
make
8+
cd ..

0 commit comments

Comments
 (0)