Skip to content

Commit 47aaaf8

Browse files
ci: 👷 add zip files to github releases (#1593)
Co-authored-by: Joshua Hemphill <[email protected]> Co-authored-by: Guillaume Chau <[email protected]>
1 parent 744ff9b commit 47aaaf8

File tree

9 files changed

+351
-27
lines changed

9 files changed

+351
-27
lines changed

.circleci/config.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ jobs:
1313
# Download and cache dependencies
1414
- restore_cache:
1515
keys:
16-
- v3-dependencies-{{ checksum "yarn.lock" }}
17-
# fallback to using the latest cache if no exact match is found
18-
- v3-dependencies-
16+
- v3-dependencies-{{ checksum "yarn.lock" }}
17+
# fallback to using the latest cache if no exact match is found
18+
- v3-dependencies-
1919

2020
- run: yarn install --pure-lockfile
2121

@@ -27,7 +27,7 @@ jobs:
2727
key: v3-dependencies-{{ checksum "yarn.lock" }}
2828

2929
# run tests!
30-
- run: yarn test
30+
- run: yarn build && yarn test
3131

3232
- store_artifacts:
3333
path: cypress/videos

.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ module.exports = {
6060
files: [
6161
'release.js',
6262
'sign-firefox.js',
63+
'extension-zips.js',
6364
'packages/build-tools/**',
6465
'packages/shell-electron/**',
6566
'**webpack.config.js',

.github/workflows/tagged-release.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Create binary for release
2+
3+
on:
4+
push:
5+
tags:
6+
- "v*"
7+
8+
jobs:
9+
build:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Checkout
13+
uses: actions/checkout@v2
14+
15+
- name: Set up Node.js
16+
uses: actions/setup-node@v2
17+
with:
18+
node-version: 14.x
19+
20+
- name: Set up lerna yarn cache
21+
uses: actions/cache@v2
22+
with:
23+
path: |
24+
node_modules
25+
*/*/node_modules
26+
~/.cache/yarn
27+
~/.cache/Cypress
28+
key: ${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}
29+
30+
- name: Install yarn dependencies
31+
if: steps.cache.outputs.cache-hit != 'true'
32+
run: yarn install --pure-lockfile
33+
34+
- name: Build the extension
35+
run: yarn run build && node release.js && yarn run test && yarn run zip
36+
37+
- name: Release
38+
uses: softprops/action-gh-release@v1
39+
if: startsWith(github.ref, 'refs/tags/')
40+
with:
41+
files: |
42+
dist/devtools-*

extension-zips.js

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
// require modules
2+
const fs = require('fs')
3+
const path = require('path')
4+
const archiver = require('archiver')
5+
const IS_CI = !!(process.env.CIRCLECI || process.env.GITHUB_ACTIONS)
6+
const ProgressBar = !IS_CI ? require('progress') : {}
7+
const readDirGlob = !IS_CI ? require('readdir-glob') : {}
8+
9+
const INCLUDE_GLOBS = [
10+
'build/**',
11+
'icons/**',
12+
'popups/**',
13+
'devtools.html',
14+
'devtools-background.html',
15+
'manifest.json',
16+
'package.json',
17+
]
18+
// SKIP_GLOBS makes glob searches more efficient
19+
const SKIP_DIR_GLOBS = ['node_modules', 'src']
20+
21+
function bytesToSize (bytes) {
22+
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']
23+
if (bytes === 0) return '0 Byte'
24+
const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)))
25+
return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i]
26+
}
27+
28+
(async () => {
29+
await writeZip('devtools-chrome.zip', 'shell-chrome')
30+
await writeZip('devtools-firefox.zip', 'shell-chrome')
31+
32+
async function writeZip (fileName, packageDir) {
33+
// create a file to stream archive data to.
34+
const output = fs.createWriteStream(path.join(__dirname, 'dist', fileName))
35+
const archive = archiver('zip', {
36+
zlib: { level: 9 }, // Sets the compression level.
37+
})
38+
39+
if (!IS_CI) {
40+
const status = {
41+
total: 0,
42+
cFile: '...',
43+
cSize: '0 Bytes',
44+
tBytes: 0,
45+
tSize: '0 Bytes',
46+
}
47+
48+
async function parseFileStats () {
49+
return new Promise((resolve, reject) => {
50+
const globber = readDirGlob(path.join('packages', packageDir),
51+
{ pattern: INCLUDE_GLOBS, skip: SKIP_DIR_GLOBS, mark: true, stat: true })
52+
globber.on('match', match => {
53+
if (!match.stat.isDirectory()) status.total++
54+
})
55+
globber.on('error', err => {
56+
reject(err)
57+
})
58+
globber.on('end', () => {
59+
resolve()
60+
})
61+
})
62+
}
63+
await parseFileStats().catch(err => {
64+
console.error(err)
65+
process.exit(1)
66+
})
67+
68+
const bar = new ProgressBar(`${fileName} @ :tSize [:bar] :current/:total :percent +:cFile@:cSize`, {
69+
width: 18,
70+
incomplete: ' ',
71+
total: status.total,
72+
})
73+
bar.tick(0, status)
74+
75+
archive.on('entry', (entry) => {
76+
if (!entry.stats.isDirectory()) {
77+
const n = entry.name
78+
status.written++
79+
status.cFile = n.length > 14
80+
? '...' + n.slice(n.length - 11)
81+
: n
82+
status.cSize = bytesToSize(entry.stats.size)
83+
status.tBytes += entry.stats.size
84+
status.tSize = bytesToSize(status.tBytes)
85+
bar.tick(1, status)
86+
}
87+
})
88+
}
89+
90+
const end = new Promise((resolve) => {
91+
// listen for all archive data to be written
92+
// 'close' event is fired only when a file descriptor is involved
93+
output.on('close', () => {
94+
if (archive.pointer() < 1000) {
95+
console.warn(`Zip file (${fileName}) is only ${archive.pointer()} bytes`)
96+
}
97+
resolve()
98+
})
99+
})
100+
101+
// This event is fired when the data source is drained no matter what was the data source.
102+
// It is not part of this library but rather from the NodeJS Stream API.
103+
// @see: https://nodejs.org/api/stream.html#stream_event_end
104+
output.on('end', function () {
105+
'nothing'
106+
})
107+
108+
// good practice to catch warnings (ie stat failures and other non-blocking errors)
109+
archive.on('warning', function (err) {
110+
if (err.code !== 'ENOENT') {
111+
// throw error
112+
console.error(err)
113+
process.exit(1)
114+
}
115+
})
116+
117+
// good practice to catch this error explicitly
118+
archive.on('error', function (err) {
119+
console.error(err)
120+
process.exit(1)
121+
})
122+
123+
// pipe archive data to the file
124+
archive.pipe(output)
125+
126+
INCLUDE_GLOBS.forEach(glob => {
127+
// append files from a glob pattern
128+
archive.glob(glob, { cwd: path.join('packages', packageDir), skip: SKIP_DIR_GLOBS })
129+
})
130+
131+
// finalize the archive (ie we are done appending files but streams have to finish yet)
132+
// 'close', 'end' or 'finish' may be fired right after calling this method so register to them beforehand
133+
archive.finalize()
134+
135+
await end
136+
}
137+
})()

package.json

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@
1515
"build:watch": "lerna run build --scope @vue-devtools/app-backend* --scope @vue-devtools/shared-* --scope @vue/devtools-api && lerna run build:watch --stream --no-sort --concurrency 99",
1616
"lint": "eslint --ext .js,.ts,.vue .",
1717
"run:firefox": "web-ext run -s packages/shell-chrome -a dist -i src",
18-
"zip": "npm run zip:chrome && npm run zip:firefox",
19-
"zip:chrome": "cd packages && zip -r -FS ../dist/chrome.zip shell-chrome -x *src/* -x *webpack.config.js -x *node_modules/*",
20-
"zip:firefox": "web-ext build -s packages/shell-chrome -a dist -i src --overwrite-dest",
18+
"zip": "node ./extension-zips.js",
2119
"sign:firefox": "node ./sign-firefox.js",
2220
"release": "npm run test && node release.js && npm run build && npm run zip && npm run pub",
2321
"release:beta": "cross-env RELEASE_CHANNEL=beta npm run release && npm run sign:firefox",
@@ -51,6 +49,7 @@
5149
"@typescript-eslint/parser": "^4.23.0",
5250
"@vue/eslint-config-standard": "^6.0.0",
5351
"@vue/eslint-config-typescript": "^7.0.0",
52+
"archiver": "^5.3.0",
5453
"autoprefixer": "^9.1.5",
5554
"concurrently": "^5.1.0",
5655
"cross-env": "^5.2.0",
@@ -82,4 +81,4 @@
8281
"engines": {
8382
"node": ">=8.10"
8483
}
85-
}
84+
}

packages/build-tools/src/createConfig.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ exports.createConfig = (config, target = { chrome: 52, firefox: 48 }) => {
186186
safari10: true,
187187
},
188188
},
189-
parallel: true,
189+
parallel: false,
190190
}),
191191
],
192192
}

release.js

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@ const semver = require('semver')
44
const pkg = require('./package.json')
55
const manifest = require('./packages/shell-chrome/manifest.json')
66

7+
const IS_CI = !!(process.env.CIRCLECI || process.env.GITHUB_ACTIONS)
8+
79
const curVersion = pkg.version
810

911
;(async () => {
10-
const { newVersion } = await inquirer.prompt([{
11-
type: 'input',
12-
name: 'newVersion',
13-
message: `Please provide a version (current: ${curVersion}):`,
14-
}])
12+
const { newVersion } = IS_CI
13+
? { newVersion: curVersion }
14+
: await inquirer.prompt([{
15+
type: 'input',
16+
name: 'newVersion',
17+
message: `Please provide a version (current: ${curVersion}):`,
18+
}])
1519

1620
if (!semver.valid(newVersion)) {
1721
console.error(`Invalid version: ${newVersion}`)
@@ -23,11 +27,13 @@ const curVersion = pkg.version
2327
process.exit(1)
2428
}
2529

26-
const { yes } = await inquirer.prompt([{
27-
name: 'yes',
28-
message: `Release ${newVersion}?`,
29-
type: 'confirm',
30-
}])
30+
const { yes } = IS_CI
31+
? { yes: true }
32+
: await inquirer.prompt([{
33+
name: 'yes',
34+
message: `Release ${newVersion}?`,
35+
type: 'confirm',
36+
}])
3137

3238
if (yes) {
3339
const isBeta = newVersion.includes('beta')

tsconfig.json

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,14 @@
22
"compilerOptions": {
33
"baseUrl": ".",
44
"paths": {
5-
"@back/*": ["packages/app-backend-core/src/*"],
6-
"@front/*": ["packages/app-frontend/src/*"],
5+
"@back/*": [
6+
"packages/app-backend-core/src/*"
7+
],
8+
"@front/*": [
9+
"packages/app-frontend/src/*"
10+
],
711
},
12+
"outDir": "lib",
813
"moduleResolution": "node",
914
"allowSyntheticDefaultImports": true,
1015
"esModuleInterop": true,
@@ -30,4 +35,4 @@
3035
"exclude": [
3136
"node_modules"
3237
],
33-
}
38+
}

0 commit comments

Comments
 (0)