Ci setup (#2)
* chore: terminology change * ci: basic * ci: remove node 8.x * chore: add semantic release * ci: restrict codecov to n12 * ci: undo * docs: spruce up main heading before release * ci: secret name
This commit is contained in:
parent
218f8172ea
commit
98060385e9
7 changed files with 3461 additions and 97 deletions
71
.github/workflows/nodejs.yml
vendored
Normal file
71
.github/workflows/nodejs.yml
vendored
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
name: Node.js CI
|
||||||
|
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Use Node.js 12.x
|
||||||
|
uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: 12.x
|
||||||
|
- run: yarn
|
||||||
|
- run: yarn lint
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
node-version: [10.x, 12.x]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
|
uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
|
- run: yarn
|
||||||
|
- run: yarn test:coverage
|
||||||
|
- name: Coverage
|
||||||
|
uses: codecov/codecov-action@v1
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
fail_ci_if_error: true
|
||||||
|
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: test
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
node-version: [10.x, 12.x]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
|
uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
|
- run: yarn
|
||||||
|
- run: yarn build
|
||||||
|
release:
|
||||||
|
name: Release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.ref == 'master'
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v1
|
||||||
|
- name: Node setup
|
||||||
|
uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: 12
|
||||||
|
- name: Prepare
|
||||||
|
run: yarn && yarn build
|
||||||
|
- name: Release
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||||
|
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||||
|
run: yarn semantic-release
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# PackWatch
|
# 📦 PackWatch 👀
|
||||||
|
|
||||||
> It ain't easy being tiny.
|
> It ain't easy being tiny.
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
"mock-fs": "^4.11.0",
|
"mock-fs": "^4.11.0",
|
||||||
"pre-commit": "^1.2.2",
|
"pre-commit": "^1.2.2",
|
||||||
"prettier": "^1.19.1",
|
"prettier": "^1.19.1",
|
||||||
"rimraf": "^3.0.2"
|
"rimraf": "^3.0.2",
|
||||||
|
"semantic-release": "^17.0.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ const PACKAGE_SIZE_PATT = /package size:\s+([0-9]+\.?[0-9]*\s+[A-Za-z]+)/g
|
||||||
const UNPACKED_SIZE_PATT = /unpacked size:\s+([0-9]+\.?[0-9]*\s+[A-Za-z]+)/g
|
const UNPACKED_SIZE_PATT = /unpacked size:\s+([0-9]+\.?[0-9]*\s+[A-Za-z]+)/g
|
||||||
const SIZE_SUFFIX_PATT = /([A-Za-z]+)/
|
const SIZE_SUFFIX_PATT = /([A-Za-z]+)/
|
||||||
const SIZE_MAGNITUDE_PATT = /([0-9]+\.?[0-9]*)/
|
const SIZE_MAGNITUDE_PATT = /([0-9]+\.?[0-9]*)/
|
||||||
const DIGEST_FILENAME = '.packwatch.json'
|
const MANIFEST_FILENAME = '.packwatch.json'
|
||||||
|
|
||||||
const FS_OPTIONS = { encoding: 'utf-8' }
|
const FS_OPTIONS = { encoding: 'utf-8' }
|
||||||
|
|
||||||
|
@ -38,36 +38,36 @@ function getCurrentPackageStats() {
|
||||||
|
|
||||||
function getPreviousPackageStats() {
|
function getPreviousPackageStats() {
|
||||||
try {
|
try {
|
||||||
const currentDigest = readFileSync(DIGEST_FILENAME, FS_OPTIONS)
|
const currentManifest = readFileSync(MANIFEST_FILENAME, FS_OPTIONS)
|
||||||
const parsedDigest = JSON.parse(currentDigest)
|
const parsedManifest = JSON.parse(currentManifest)
|
||||||
return {
|
return {
|
||||||
...parsedDigest,
|
...parsedManifest,
|
||||||
packageSizeBytes: convertSizeToBytes(parsedDigest.packageSize),
|
packageSizeBytes: convertSizeToBytes(parsedManifest.packageSize),
|
||||||
unpackedSizeBytes: convertSizeToBytes(parsedDigest.unpackedSize),
|
unpackedSizeBytes: convertSizeToBytes(parsedManifest.unpackedSize),
|
||||||
limitBytes: convertSizeToBytes(parsedDigest.limit),
|
limitBytes: convertSizeToBytes(parsedManifest.limit),
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createOrUpdateDigest({ previous, current, updateLimit = false }) {
|
function createOrUpdateManifest({ previous, current, updateLimit = false }) {
|
||||||
const { limit } = previous || {}
|
const { limit } = previous || {}
|
||||||
const { packageSize, unpackedSize } = current
|
const { packageSize, unpackedSize } = current
|
||||||
|
|
||||||
const newDigest = {
|
const newManifest = {
|
||||||
limit: updateLimit ? packageSize : limit || packageSize,
|
limit: updateLimit ? packageSize : limit || packageSize,
|
||||||
packageSize: packageSize,
|
packageSize: packageSize,
|
||||||
unpackedSize: unpackedSize,
|
unpackedSize: unpackedSize,
|
||||||
}
|
}
|
||||||
|
|
||||||
writeFileSync(DIGEST_FILENAME, JSON.stringify(newDigest))
|
writeFileSync(MANIFEST_FILENAME, JSON.stringify(newManifest))
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
createOrUpdateDigest,
|
createOrUpdateManifest,
|
||||||
getPreviousPackageStats,
|
getPreviousPackageStats,
|
||||||
getCurrentPackageStats,
|
getCurrentPackageStats,
|
||||||
convertSizeToBytes,
|
convertSizeToBytes,
|
||||||
DIGEST_FILENAME,
|
MANIFEST_FILENAME,
|
||||||
}
|
}
|
||||||
|
|
30
src/index.js
30
src/index.js
|
@ -3,10 +3,10 @@
|
||||||
const { existsSync } = require('fs')
|
const { existsSync } = require('fs')
|
||||||
|
|
||||||
const {
|
const {
|
||||||
DIGEST_FILENAME,
|
MANIFEST_FILENAME,
|
||||||
getCurrentPackageStats,
|
getCurrentPackageStats,
|
||||||
getPreviousPackageStats,
|
getPreviousPackageStats,
|
||||||
createOrUpdateDigest,
|
createOrUpdateManifest,
|
||||||
} = require('./helpers')
|
} = require('./helpers')
|
||||||
|
|
||||||
if (!existsSync('package.json')) {
|
if (!existsSync('package.json')) {
|
||||||
|
@ -16,19 +16,19 @@ if (!existsSync('package.json')) {
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
const isUpdatingDigest = process.argv.includes('--update-digest')
|
const isUpdatingManifest = process.argv.includes('--update-manifest')
|
||||||
|
|
||||||
const currentStats = getCurrentPackageStats()
|
const currentStats = getCurrentPackageStats()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there is no digest file yet, we can use the current package stats as
|
* If there is no manifest file yet, we can use the current package stats as
|
||||||
* a base to build one. The current package size becomes the limit.
|
* a base to build one. The current package size becomes the limit.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!existsSync(DIGEST_FILENAME)) {
|
if (!existsSync(MANIFEST_FILENAME)) {
|
||||||
createOrUpdateDigest({ current: currentStats })
|
createOrUpdateManifest({ current: currentStats })
|
||||||
console.log(
|
console.log(
|
||||||
`📝 No digest to compare against! Current package stats written to ${DIGEST_FILENAME}!`,
|
`📝 No Manifest to compare against! Current package stats written to ${MANIFEST_FILENAME}!`,
|
||||||
)
|
)
|
||||||
console.log(
|
console.log(
|
||||||
`Package size (${currentStats.packageSize}) adopted as new limit.`,
|
`Package size (${currentStats.packageSize}) adopted as new limit.`,
|
||||||
|
@ -47,38 +47,38 @@ const {
|
||||||
const hasExceededLimit = packageSizeBytes > limitBytes
|
const hasExceededLimit = packageSizeBytes > limitBytes
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we are updating the digest, we can write right away and terminate.
|
* If we are updating the manifest, we can write right away and terminate.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (isUpdatingDigest) {
|
if (isUpdatingManifest) {
|
||||||
createOrUpdateDigest({
|
createOrUpdateManifest({
|
||||||
previous: previousStats,
|
previous: previousStats,
|
||||||
current: currentStats,
|
current: currentStats,
|
||||||
updateLimit: true,
|
updateLimit: true,
|
||||||
})
|
})
|
||||||
console.log(
|
console.log(
|
||||||
`📝 Updated the digest! Package size: ${packageSize}, Limit: ${packageSize}`,
|
`📝 Updated the manifest! Package size: ${packageSize}, Limit: ${packageSize}`,
|
||||||
)
|
)
|
||||||
process.exit(0)
|
process.exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there is a digest file and the current package busts its limit
|
* If there is a manifest file and the current package busts its limit
|
||||||
* we signal it and terminate with an error.
|
* we signal it and terminate with an error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (hasExceededLimit) {
|
if (hasExceededLimit) {
|
||||||
console.log(
|
console.log(
|
||||||
`🔥🔥📦🔥🔥 Your package exceeds the limit set in ${DIGEST_FILENAME}! ${packageSize} > ${limit}`,
|
`🔥🔥📦🔥🔥 Your package exceeds the limit set in ${MANIFEST_FILENAME}! ${packageSize} > ${limit}`,
|
||||||
)
|
)
|
||||||
console.log(
|
console.log(
|
||||||
'Either update the limit by using the --update-digest flag or trim down your packed files!',
|
'Either update the limit by using the --update-manifest flag or trim down your packed files!',
|
||||||
)
|
)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there is a digest file and the limit is not busted, we give
|
* If there is a manifest file and the limit is not busted, we give
|
||||||
* the user some feedback on how the current package compares with
|
* the user some feedback on how the current package compares with
|
||||||
* the previous one.
|
* the previous one.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -7,11 +7,11 @@ jest.mock('child_process')
|
||||||
childProcess.spawnSync = jest.fn(() => ({ stderr: mockPackOutput }))
|
childProcess.spawnSync = jest.fn(() => ({ stderr: mockPackOutput }))
|
||||||
|
|
||||||
const {
|
const {
|
||||||
DIGEST_FILENAME,
|
MANIFEST_FILENAME,
|
||||||
convertSizeToBytes,
|
convertSizeToBytes,
|
||||||
getCurrentPackageStats,
|
getCurrentPackageStats,
|
||||||
getPreviousPackageStats,
|
getPreviousPackageStats,
|
||||||
createOrUpdateDigest,
|
createOrUpdateManifest,
|
||||||
} = require('./helpers')
|
} = require('./helpers')
|
||||||
|
|
||||||
const mockPackageSize = '1.1 kB'
|
const mockPackageSize = '1.1 kB'
|
||||||
|
@ -83,7 +83,7 @@ describe('Helpers', () => {
|
||||||
const limit = '1 kB'
|
const limit = '1 kB'
|
||||||
const limitBytes = 1000
|
const limitBytes = 1000
|
||||||
const mockReport = { packageSize, unpackedSize, limit }
|
const mockReport = { packageSize, unpackedSize, limit }
|
||||||
mockFS({ [DIGEST_FILENAME]: JSON.stringify(mockReport) })
|
mockFS({ [MANIFEST_FILENAME]: JSON.stringify(mockReport) })
|
||||||
|
|
||||||
expect(getPreviousPackageStats()).toEqual({
|
expect(getPreviousPackageStats()).toEqual({
|
||||||
packageSize,
|
packageSize,
|
||||||
|
@ -95,79 +95,79 @@ describe('Helpers', () => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('returns an empty digest if it fails to reads the digest file', () => {
|
it('returns an empty manifest if it fails to reads the manifest file', () => {
|
||||||
mockFS({
|
mockFS({
|
||||||
[DIGEST_FILENAME]: 'not valid JSON',
|
[MANIFEST_FILENAME]: 'not valid JSON',
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(getPreviousPackageStats()).toEqual({})
|
expect(getPreviousPackageStats()).toEqual({})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('Creating or updating the digest', () => {
|
describe('Creating or updating the manifest', () => {
|
||||||
const currentStats = {
|
const currentStats = {
|
||||||
packageSize: '1 kB',
|
packageSize: '1 kB',
|
||||||
unpackedSize: '10 kB',
|
unpackedSize: '10 kB',
|
||||||
}
|
}
|
||||||
|
|
||||||
const previousDigest = {
|
const previousManifest = {
|
||||||
limit: '2 kB',
|
limit: '2 kB',
|
||||||
packageSize: '1.5 kB',
|
packageSize: '1.5 kB',
|
||||||
}
|
}
|
||||||
it('creates a digest from the current data if no previous data is provided', () => {
|
it('creates a anifest from the current data if no previous data is provided', () => {
|
||||||
mockFS({})
|
mockFS({})
|
||||||
|
|
||||||
createOrUpdateDigest({ current: currentStats })
|
createOrUpdateManifest({ current: currentStats })
|
||||||
|
|
||||||
const writtenDigest = readFileSync(DIGEST_FILENAME, {
|
const writtenManifest = readFileSync(MANIFEST_FILENAME, {
|
||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(JSON.parse(writtenDigest)).toEqual({
|
expect(JSON.parse(writtenManifest)).toEqual({
|
||||||
packageSize: currentStats.packageSize,
|
packageSize: currentStats.packageSize,
|
||||||
unpackedSize: currentStats.unpackedSize,
|
unpackedSize: currentStats.unpackedSize,
|
||||||
limit: currentStats.packageSize,
|
limit: currentStats.packageSize,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('updates the previous digest sizes if previous data exists', () => {
|
it('updates the previous manifest sizes if previous data exists', () => {
|
||||||
mockFS({
|
mockFS({
|
||||||
[DIGEST_FILENAME]: JSON.stringify(previousDigest),
|
[MANIFEST_FILENAME]: JSON.stringify(previousManifest),
|
||||||
})
|
})
|
||||||
|
|
||||||
createOrUpdateDigest({
|
createOrUpdateManifest({
|
||||||
current: currentStats,
|
current: currentStats,
|
||||||
previous: previousDigest,
|
previous: previousManifest,
|
||||||
updateLimit: false,
|
updateLimit: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
const writtenDigest = readFileSync(DIGEST_FILENAME, {
|
const writtenManifest = readFileSync(MANIFEST_FILENAME, {
|
||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(JSON.parse(writtenDigest)).toEqual({
|
expect(JSON.parse(writtenManifest)).toEqual({
|
||||||
packageSize: currentStats.packageSize,
|
packageSize: currentStats.packageSize,
|
||||||
unpackedSize: currentStats.unpackedSize,
|
unpackedSize: currentStats.unpackedSize,
|
||||||
limit: previousDigest.limit,
|
limit: previousManifest.limit,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('updates the previous digest sizes and limit if previous data exists and updateLimit is set', () => {
|
it('updates the previous manifest sizes and limit if previous data exists and updateLimit is set', () => {
|
||||||
mockFS({
|
mockFS({
|
||||||
[DIGEST_FILENAME]: JSON.stringify(previousDigest),
|
[MANIFEST_FILENAME]: JSON.stringify(previousManifest),
|
||||||
})
|
})
|
||||||
|
|
||||||
createOrUpdateDigest({
|
createOrUpdateManifest({
|
||||||
current: currentStats,
|
current: currentStats,
|
||||||
previous: previousDigest,
|
previous: previousManifest,
|
||||||
updateLimit: true,
|
updateLimit: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
const writtenDigest = readFileSync(DIGEST_FILENAME, {
|
const writtenManifest = readFileSync(MANIFEST_FILENAME, {
|
||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(JSON.parse(writtenDigest)).toEqual({
|
expect(JSON.parse(writtenManifest)).toEqual({
|
||||||
packageSize: currentStats.packageSize,
|
packageSize: currentStats.packageSize,
|
||||||
unpackedSize: currentStats.unpackedSize,
|
unpackedSize: currentStats.unpackedSize,
|
||||||
limit: currentStats.packageSize,
|
limit: currentStats.packageSize,
|
||||||
|
|
Reference in a new issue