Ci setup #2
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.
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
"mock-fs": "^4.11.0",
|
||||
"pre-commit": "^1.2.2",
|
||||
"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 SIZE_SUFFIX_PATT = /([A-Za-z]+)/
|
||||
const SIZE_MAGNITUDE_PATT = /([0-9]+\.?[0-9]*)/
|
||||
const DIGEST_FILENAME = '.packwatch.json'
|
||||
const MANIFEST_FILENAME = '.packwatch.json'
|
||||
|
||||
const FS_OPTIONS = { encoding: 'utf-8' }
|
||||
|
||||
|
@ -38,36 +38,36 @@ function getCurrentPackageStats() {
|
|||
|
||||
function getPreviousPackageStats() {
|
||||
try {
|
||||
const currentDigest = readFileSync(DIGEST_FILENAME, FS_OPTIONS)
|
||||
const parsedDigest = JSON.parse(currentDigest)
|
||||
const currentManifest = readFileSync(MANIFEST_FILENAME, FS_OPTIONS)
|
||||
const parsedManifest = JSON.parse(currentManifest)
|
||||
return {
|
||||
...parsedDigest,
|
||||
packageSizeBytes: convertSizeToBytes(parsedDigest.packageSize),
|
||||
unpackedSizeBytes: convertSizeToBytes(parsedDigest.unpackedSize),
|
||||
limitBytes: convertSizeToBytes(parsedDigest.limit),
|
||||
...parsedManifest,
|
||||
packageSizeBytes: convertSizeToBytes(parsedManifest.packageSize),
|
||||
unpackedSizeBytes: convertSizeToBytes(parsedManifest.unpackedSize),
|
||||
limitBytes: convertSizeToBytes(parsedManifest.limit),
|
||||
}
|
||||
} catch (e) {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
function createOrUpdateDigest({ previous, current, updateLimit = false }) {
|
||||
function createOrUpdateManifest({ previous, current, updateLimit = false }) {
|
||||
const { limit } = previous || {}
|
||||
const { packageSize, unpackedSize } = current
|
||||
|
||||
const newDigest = {
|
||||
const newManifest = {
|
||||
limit: updateLimit ? packageSize : limit || packageSize,
|
||||
packageSize: packageSize,
|
||||
unpackedSize: unpackedSize,
|
||||
}
|
||||
|
||||
writeFileSync(DIGEST_FILENAME, JSON.stringify(newDigest))
|
||||
writeFileSync(MANIFEST_FILENAME, JSON.stringify(newManifest))
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createOrUpdateDigest,
|
||||
createOrUpdateManifest,
|
||||
getPreviousPackageStats,
|
||||
getCurrentPackageStats,
|
||||
convertSizeToBytes,
|
||||
DIGEST_FILENAME,
|
||||
MANIFEST_FILENAME,
|
||||
}
|
||||
|
|
30
src/index.js
30
src/index.js
|
@ -3,10 +3,10 @@
|
|||
const { existsSync } = require('fs')
|
||||
|
||||
const {
|
||||
DIGEST_FILENAME,
|
||||
MANIFEST_FILENAME,
|
||||
getCurrentPackageStats,
|
||||
getPreviousPackageStats,
|
||||
createOrUpdateDigest,
|
||||
createOrUpdateManifest,
|
||||
} = require('./helpers')
|
||||
|
||||
if (!existsSync('package.json')) {
|
||||
|
@ -16,19 +16,19 @@ if (!existsSync('package.json')) {
|
|||
process.exit(1)
|
||||
}
|
||||
|
||||
const isUpdatingDigest = process.argv.includes('--update-digest')
|
||||
const isUpdatingManifest = process.argv.includes('--update-manifest')
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
if (!existsSync(DIGEST_FILENAME)) {
|
||||
createOrUpdateDigest({ current: currentStats })
|
||||
if (!existsSync(MANIFEST_FILENAME)) {
|
||||
createOrUpdateManifest({ current: currentStats })
|
||||
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(
|
||||
`Package size (${currentStats.packageSize}) adopted as new limit.`,
|
||||
|
@ -47,38 +47,38 @@ const {
|
|||
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) {
|
||||
createOrUpdateDigest({
|
||||
if (isUpdatingManifest) {
|
||||
createOrUpdateManifest({
|
||||
previous: previousStats,
|
||||
current: currentStats,
|
||||
updateLimit: true,
|
||||
})
|
||||
console.log(
|
||||
`📝 Updated the digest! Package size: ${packageSize}, Limit: ${packageSize}`,
|
||||
`📝 Updated the manifest! Package size: ${packageSize}, Limit: ${packageSize}`,
|
||||
)
|
||||
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.
|
||||
*/
|
||||
|
||||
if (hasExceededLimit) {
|
||||
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(
|
||||
'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)
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 previous one.
|
||||
*/
|
||||
|
|
|
@ -7,11 +7,11 @@ jest.mock('child_process')
|
|||
childProcess.spawnSync = jest.fn(() => ({ stderr: mockPackOutput }))
|
||||
|
||||
const {
|
||||
DIGEST_FILENAME,
|
||||
MANIFEST_FILENAME,
|
||||
convertSizeToBytes,
|
||||
getCurrentPackageStats,
|
||||
getPreviousPackageStats,
|
||||
createOrUpdateDigest,
|
||||
createOrUpdateManifest,
|
||||
} = require('./helpers')
|
||||
|
||||
const mockPackageSize = '1.1 kB'
|
||||
|
@ -83,7 +83,7 @@ describe('Helpers', () => {
|
|||
const limit = '1 kB'
|
||||
const limitBytes = 1000
|
||||
const mockReport = { packageSize, unpackedSize, limit }
|
||||
mockFS({ [DIGEST_FILENAME]: JSON.stringify(mockReport) })
|
||||
mockFS({ [MANIFEST_FILENAME]: JSON.stringify(mockReport) })
|
||||
|
||||
expect(getPreviousPackageStats()).toEqual({
|
||||
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({
|
||||
[DIGEST_FILENAME]: 'not valid JSON',
|
||||
[MANIFEST_FILENAME]: 'not valid JSON',
|
||||
})
|
||||
|
||||
expect(getPreviousPackageStats()).toEqual({})
|
||||
})
|
||||
})
|
||||
|
||||
describe('Creating or updating the digest', () => {
|
||||
describe('Creating or updating the manifest', () => {
|
||||
const currentStats = {
|
||||
packageSize: '1 kB',
|
||||
unpackedSize: '10 kB',
|
||||
}
|
||||
|
||||
const previousDigest = {
|
||||
const previousManifest = {
|
||||
limit: '2 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({})
|
||||
|
||||
createOrUpdateDigest({ current: currentStats })
|
||||
createOrUpdateManifest({ current: currentStats })
|
||||
|
||||
const writtenDigest = readFileSync(DIGEST_FILENAME, {
|
||||
const writtenManifest = readFileSync(MANIFEST_FILENAME, {
|
||||
encoding: 'utf-8',
|
||||
})
|
||||
|
||||
expect(JSON.parse(writtenDigest)).toEqual({
|
||||
expect(JSON.parse(writtenManifest)).toEqual({
|
||||
packageSize: currentStats.packageSize,
|
||||
unpackedSize: currentStats.unpackedSize,
|
||||
limit: currentStats.packageSize,
|
||||
})
|
||||
})
|
||||
|
||||
it('updates the previous digest sizes if previous data exists', () => {
|
||||
it('updates the previous manifest sizes if previous data exists', () => {
|
||||
mockFS({
|
||||
[DIGEST_FILENAME]: JSON.stringify(previousDigest),
|
||||
[MANIFEST_FILENAME]: JSON.stringify(previousManifest),
|
||||
})
|
||||
|
||||
createOrUpdateDigest({
|
||||
createOrUpdateManifest({
|
||||
current: currentStats,
|
||||
previous: previousDigest,
|
||||
previous: previousManifest,
|
||||
updateLimit: false,
|
||||
})
|
||||
|
||||
const writtenDigest = readFileSync(DIGEST_FILENAME, {
|
||||
const writtenManifest = readFileSync(MANIFEST_FILENAME, {
|
||||
encoding: 'utf-8',
|
||||
})
|
||||
|
||||
expect(JSON.parse(writtenDigest)).toEqual({
|
||||
expect(JSON.parse(writtenManifest)).toEqual({
|
||||
packageSize: currentStats.packageSize,
|
||||
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({
|
||||
[DIGEST_FILENAME]: JSON.stringify(previousDigest),
|
||||
[MANIFEST_FILENAME]: JSON.stringify(previousManifest),
|
||||
})
|
||||
|
||||
createOrUpdateDigest({
|
||||
createOrUpdateManifest({
|
||||
current: currentStats,
|
||||
previous: previousDigest,
|
||||
previous: previousManifest,
|
||||
updateLimit: true,
|
||||
})
|
||||
|
||||
const writtenDigest = readFileSync(DIGEST_FILENAME, {
|
||||
const writtenManifest = readFileSync(MANIFEST_FILENAME, {
|
||||
encoding: 'utf-8',
|
||||
})
|
||||
|
||||
expect(JSON.parse(writtenDigest)).toEqual({
|
||||
expect(JSON.parse(writtenManifest)).toEqual({
|
||||
packageSize: currentStats.packageSize,
|
||||
unpackedSize: currentStats.unpackedSize,
|
||||
limit: currentStats.packageSize,
|
||||
|
|
Reference in a new issue