Skip to content

Commit

Permalink
github(workflows): add package size checks, add auto demo deploy (#1048)
Browse files Browse the repository at this point in the history
* internal(deps): add deps for ts-node and filesize computation

* internal(node): add tsconfig for node

* build: add computeBuildSizes script

* build: add compareBuildSizes, upsertPullRequestComment scripts

* build: update computeBuildSizes output file

* build: add deploy-demo script

* github(workflows/ci): add Package sizes + Deploy gallery steps

* github(workflows/ci): add pull_request checks to happo, package sizes

* deps(dev): add @types/node-fetch

* deps: update yarn.lock

* type(scripts/upsertPullRequestComment): fix comment type

* github(workflows): separate CI into push + pull_request

* deps(dev): add @octokit/rest

* fix(workflows/pull_request): add needed variables for upsertPullRequestComment

* commit to kick workflow

* github(workflows): fix package size report job

* github(workflow): fix GITHUB_REPOSITORY/ACTOR variable syntax

* fix(scripts/upsertPullRequestComment): better types

* fix(scripts/compareBuildSizes): log errors

* debug(scripts//upsertPullRequestComment): add more debug logs

* debug(scripts/upsertPullRequestComment): add more debug logs

* fix(/workflows/pull_request): remove debug logging

* github(workflows): update branches for testing

* fix(workflows/push)

* fix(scripts/upsertPullRequestComment): fix bot user login check

* deps(demo, annotation, tooltip): react-measure@2.0.3

* fix(demo/axis,pattern,xychart): fix window check for ssr

* fix(/workflows/push): rewrite gallery deploy job to fix credentials

* fix(workflows/push/gallery): try to fix credentials

* fix(github/workflows/push): try https for gallery push

* fix(workflows/push): tweak https syntax

* fix(workflows/push): try github-pages-deploy-action

* fix(workflows/push): don't use working-directory with uses

* fix(workflows/push): try changing persist-credentials mid-workflow

* fix(workflows/push): more changes

* fix(workflows/push): try worktree approach

* fix(workflows/push): build gallery on master

* fix(workflows/push): add out/ contents pre-commit

* fix(workflows/push): fix credentials

* fix(workflows/push): try  not master

* fix(workflows/push): try  not master take 2

* fix(workflows/push): we have a winner

* fix(workflows/push,pull_request): final final

* fix(workflows/push): match 📡 emoji across workflows 🙄

* type(scripts/upsertPullRequestComment): fix types
  • Loading branch information
williaster authored Feb 9, 2021
1 parent a65c635 commit 3d8a245
Show file tree
Hide file tree
Showing 14 changed files with 564 additions and 30 deletions.
27 changes: 17 additions & 10 deletions .github/workflows/ci.yml → .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
name: CI
name: Pull request

on:
push:
branches: [master]
pull_request:
branches: [master]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v2 # checkout visx + this commit
- uses: actions/setup-node@v1
with:
node-version: '12'
Expand All @@ -26,30 +24,39 @@ jobs:
restore-keys: |
${{ runner.os }}-yarn-
- name: Install dependencies
- name: 📡 Install dependencies
run: yarn install --frozen-lockfile --ignore-engines

- name: Build packages
- name: 🛠 Build packages
run: yarn build

- name: Run jest
- name: 🧪 Run jest
run: yarn jest -w 4
env:
CI: true
COVERAGE: true

- name: Report code coverage
- name: 📈 Report code coverage
uses: coverallsapp/github-action@v1.1.1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}

- name: Run lint
- name: Run lint
run: yarn lint

- name: Run happo
- name: 🦛 Run happo
run: yarn run happo-ci-github-actions
working-directory: './packages/visx-demo/'
env:
HAPPO_API_KEY: ${{ secrets.HAPPO_API_KEY }}
HAPPO_API_SECRET: ${{ secrets.HAPPO_API_SECRET }}
HAPPO_COMMAND: '../../node_modules/happo.io/build/cli.js'

- name: 📐 Report package sizes
run: yarn build:sizes && yarn check:sizes
# add needed variables for posting on the PR via octokit
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
GITHUB_REPOSITORY: $GITHUB_REPOSITORY
GITHUB_ACTOR: $GITHUB_ACTOR
70 changes: 70 additions & 0 deletions .github/workflows/push.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: Push

on:
push:
branches: [master]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2 # checkout visx + this commit
- uses: actions/setup-node@v1
with:
node-version: '12'

- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v1
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: 📡 Install dependencies
run: yarn install --frozen-lockfile --ignore-engines

- name: 🛠 Build packages
run: yarn build

- name: 📐 Commit package sizes
run: |
yarn build:sizes
git config user.name github-actions
git config user.email github-actions@github.com
git add .
git commit -m "build(${GITHUB_SHA}): auto-commit package sizes"
git push
- name: 🚀 Build and deploy gallery
# below we
# - setup git credentials provided via actions/checkout@v2
# - initialize gh-pages-branch as an orphan branch so we don't build history
# - checkout the current commit and create gh-pages-root-dir/ as a new worktree
# - outside that directory HEAD is detached at $GITHUB_SHA
# - within that directory we are on the gh-pages-branch we just initialized
# *worktree initialization should be in a root dir, otherwise the worktree inherits nested directories
# - build the static next.js site and copy the output into gh-pages-root-dir/
# - we can't output directly into gh-pages-root-dir/ because next wipes the folder including .git
# - commit the demo site within gh-pages-root-dir/ onto the gh-pages-branch
# - push gh-pages-branch to visx as gh-pages. we overwrite history every time so it must be forced
run: |
git config user.name github-actions
git config user.email github-actions@github.com
git checkout --orphan gh-pages-branch
git reset --hard
touch .nojekyll
git add .nojekyll
git commit -m "bot(${GITHUB_SHA}): initialize gh-pages branch"
git checkout "$GITHUB_SHA"
git worktree add gh-pages-root-dir gh-pages-branch
cd ./packages/visx-demo/
yarn build
mv -v out/* ../../gh-pages-root-dir/
cd ../../gh-pages-root-dir/
git add .
git commit -m "bot(${GITHUB_SHA}): build gh-pages"
git push -f "https://$GITHUB_ACTOR:$GITHUB_TOKEN@github.com/$GITHUB_REPOSITORY.git" HEAD:gh-pages
27 changes: 20 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,29 @@
],
"private": true,
"scripts": {
"build": "yarn run babel && yarn run type:dts",
"build-one": "nimbus babel --clean",
"babel": "yarn run babel:cjs && yarn run babel:esm",
"babel:cjs": "nimbus babel --clean --workspaces=\"@visx/!(demo)\"",
"babel:esm": "nimbus babel --clean --workspaces=\"@visx/!(demo)\" --esm",
"build": "yarn run babel && yarn run type",
"build-one": "echo 'build-one has been replaced with build:workspace' & exit 1",
"build:sizes": "yarn run ts ./scripts/computeBuildSizes.ts",
"build:workspace": "nimbus babel --clean",
"check:sizes": "yarn run ts ./scripts/compareBuildSizes.ts",
"clean": "rm -rf ./packages/**/{lib,esm}",
"format": "yarn run prettier --write",
"jest": "NODE_ENV=test nimbus jest --coverage --verbose",
"lint": "nimbus eslint",
"lint:fix": "yarn run lint --fix",
"prepare-release": "git checkout master && git pull --rebase origin master && lerna updated",
"prettier": "nimbus prettier",
"release": "yarn run prepare-release && lerna publish --exact",
"setup": "yarn run build",
"test": "yarn run jest",
"type:dts": "nimbus typescript --build --reference-workspaces",
"type-one": "nimbus typescript --build",
"prepare-release": "git checkout master && git pull --rebase origin master && lerna updated",
"release": "yarn run prepare-release && lerna publish --exact"
"ts": "ts-node --project ./tsconfig.node.json",
"type": "nimbus typescript --build --reference-workspaces",
"type-one": "echo 'type-one has been replaced with type:workspace' & exit 1",
"type:dts": "echo 'type:dts has been replaced with type' & exit 1",
"type:workspace": "nimbus typescript --build"
},
"devDependencies": {
"@airbnb/config-babel": "^2.1.3",
Expand All @@ -55,26 +61,33 @@
"@airbnb/config-prettier": "^2.0.4",
"@airbnb/config-typescript": "^2.1.2",
"@airbnb/nimbus": "^2.1.3",
"@octokit/rest": "18.1.0",
"@types/enzyme": "^3.10.3",
"@types/jest": "^24.0.18",
"@types/jsdom": "^12.2.4",
"@types/node-fetch": "1.6.9",
"@types/react-test-renderer": "^16.9.0",
"@types/webpack": "^4.41.17",
"chalk": "4.1.0",
"coveralls": "^3.0.6",
"enzyme": "^3.10.0",
"enzyme-adapter-react-16": "^1.14.0",
"enzyme-to-json": "^3.4.0",
"fast-glob": "3.2.5",
"filesize": "6.1.0",
"fs-jetpack": "^1.3.0",
"husky": "^3.0.0",
"jest-mock-console": "^1.0.1",
"lerna": "^3.15.0",
"marked": "^0.7.0",
"node-fetch": "2.6.1",
"raf": "^3.4.0",
"react": "^15.0.0-0 || ^16.0.0-0",
"react-dom": "^15.0.0-0 || ^16.0.0-0",
"react-test-renderer": "^16.8.6",
"regenerator-runtime": "^0.10.5",
"timezone-mock": "^1.1.0"
"timezone-mock": "^1.1.0",
"ts-node": "9.1.1"
},
"workspaces": [
"./packages/*"
Expand Down
2 changes: 1 addition & 1 deletion packages/visx-annotation/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"@visx/text": "1.3.0",
"classnames": "^2.2.5",
"prop-types": "^15.5.10",
"react-use-measure": "2.0.1"
"react-use-measure": "^2.0.3"
},
"devDependencies": {
"resize-observer-polyfill": "^1.5.1"
Expand Down
2 changes: 1 addition & 1 deletion packages/visx-demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
"@visx/xychart": "1.4.0",
"@visx/zoom": "1.3.0",
"@zeit/next-css": "^1.0.1",
"babel-loader": "8.2.2",
"babel-loader": "^8.2.2",
"classnames": "^2.2.5",
"d3-array": "^1.1.1",
"d3-collection": "^1.0.4",
Expand Down
3 changes: 2 additions & 1 deletion packages/visx-demo/src/sandboxes/visx-axis/Example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ export default function Example({
showControls = true,
}: AxisProps) {
// use non-animated components if prefers-reduced-motion is set
const prefersReducedMotionQuery = window?.matchMedia('(prefers-reduced-motion: reduce)');
const prefersReducedMotionQuery =
typeof window === 'undefined' ? false : window.matchMedia('(prefers-reduced-motion: reduce)');
const prefersReducedMotion = !prefersReducedMotionQuery || !!prefersReducedMotionQuery.matches;
const [useAnimatedComponents, setUseAnimatedComponents] = useState(!prefersReducedMotion);

Expand Down
3 changes: 2 additions & 1 deletion packages/visx-demo/src/sandboxes/visx-pattern/Example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ const Patterns: React.FC<{ id: string; prefersReducedMotion?: boolean }>[] = [

export default function Example({ width, height, margin = defaultMargin }: PatternProps) {
// use non-animated components if prefers-reduced-motion is set
const prefersReducedMotionQuery = window?.matchMedia('(prefers-reduced-motion: reduce)');
const prefersReducedMotionQuery =
typeof window === 'undefined' ? false : window.matchMedia('(prefers-reduced-motion: reduce)');
const prefersReducedMotion = !prefersReducedMotionQuery || !!prefersReducedMotionQuery.matches;

const numColumns = 3;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export default function userPrefersReducedMotion() {
const prefersReducedMotionQuery = window?.matchMedia('(prefers-reduced-motion: reduce)');
const prefersReducedMotionQuery =
typeof window === 'undefined' ? false : window.matchMedia('(prefers-reduced-motion: reduce)');
return !prefersReducedMotionQuery || !!prefersReducedMotionQuery.matches;
}
2 changes: 1 addition & 1 deletion packages/visx-tooltip/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"@visx/bounds": "1.0.0",
"classnames": "^2.2.5",
"prop-types": "^15.5.10",
"react-use-measure": "2.0.1"
"react-use-measure": "^2.0.3"
},
"peerDependencies": {
"react": "^16.8.0-0",
Expand Down
124 changes: 124 additions & 0 deletions scripts/compareBuildSizes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import fs from 'fs';
import size from 'filesize';
import chalk from 'chalk';
import fetch from 'node-fetch';
import upsertPullRequestComment from './upsertPullRequestComment';
import { PACKAGE_SIZES_FILENAME } from './computeBuildSizes';

type StatMap = {
[pkg: string]: {
[dir: string]: number;
};
};

function calculateDiff(prev: number, next: number): number {
return (next - prev) / prev;
}

function formatDiff(diff: number): string {
const sum = diff * 100;
const percent = sum.toFixed(1);

// Smaller
if (percent.startsWith('-')) {
return `${sum < -10 ? ':small_red_triangle_down: ' : ''}${percent}%`;
}

// Larger
return `${sum > 10 ? ':small_red_triangle: ' : ''}+${percent}%`;
}

async function compareBuildSizes() {
const nextSizes: StatMap = JSON.parse(fs.readFileSync(PACKAGE_SIZES_FILENAME, 'utf8'));
let prevSizes: StatMap = {};
let sameBuild = false;

try {
const masterFileSizesRequest = await fetch(
`https://raw.githubusercontent.com/airbnb/visx/master/${PACKAGE_SIZES_FILENAME}`,
);

prevSizes = await masterFileSizesRequest.json();
} catch (error) {
console.log(`Could not fetch file ${PACKAGE_SIZES_FILENAME} from master. Aborting.`);
console.log(error.message);

prevSizes = nextSizes;
sameBuild = true;
}

function getPrevSize(name: string, type: string) {
return (prevSizes[name] && prevSizes[name][type]) || 0;
}

const output: string[] = [
'### Size Changes',
'| Package | Diff | ESM | Prev ESM | CJS | Prev CJS |',
'| --- | ---: | ---: | ---: | ---: | ---: |',
];
const rows: string[] = [];

Object.entries(nextSizes).forEach(([pkgName, stats]) => {
const prevEsm = getPrevSize(pkgName, 'esm');
const prevLib = getPrevSize(pkgName, 'lib');
const diff = calculateDiff(prevEsm, stats.esm);

if (!isFinite(diff) || diff === 0 || diff === 0.0) {
return;
}

const row = [
pkgName,
formatDiff(diff),
size(stats.esm),
prevEsm === 0 ? 'N/A' : size(prevEsm),
size(stats.lib),
prevLib === 0 ? 'N/A' : size(prevLib),
];

rows.push(`| ${row.join(' | ')} |`);
});

// Don't post anything if no changes
if (rows.length === 0) {
return;
}

// Sort rows before joining to output
rows.sort();

output.push(...rows);
output.push('> Compared to master. File sizes are unminified and ungzipped.');

// Show dumps for easier debugging
if (!sameBuild) {
output.push(`<details>
<summary>View raw build stats</summary>
#### Previous (master)
\`\`\`json
${JSON.stringify(prevSizes, null, 2)}
\`\`\`
#### Current
\`\`\`json
${JSON.stringify(nextSizes, null, 2)}
\`\`\`
</details>`);
}

// Leave a comment on the PR
const breakdown = output.join('\n');

try {
await upsertPullRequestComment('### Size Changes', breakdown);
} catch (error) {
console.log('Could not post size stats', breakdown);
console.error(error);
}
}

compareBuildSizes().catch(error => {
console.error(chalk.red(error.message));
process.exitCode = 1;
});
Loading

0 comments on commit 3d8a245

Please sign in to comment.