Skip to content

Commit

Permalink
Migrate sizebot to combined workflow
Browse files Browse the repository at this point in the history
Replaces the two separate sizebot jobs (one for each channel, stable and
experimental) with a single combined job that outputs size information
for all bundles in a single GitHub comment.

I didn't attempt to simplify the output at all, but we should. I think
what I would do is remove our custom Rollup sizes plugin, and read the
sizes from the filesystem instead. We would lose some information about
the build configuration used to generate each artifact, but that can be
inferred from the filepath. For example, the filepath
`fb-www/ReactDOM-dev.classic.js` already tells us everything we need to
know about the artifact. Leaving this for a follow up.
  • Loading branch information
acdlite committed Feb 3, 2021
1 parent b8b4f22 commit ba4aafb
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 178 deletions.
82 changes: 22 additions & 60 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -170,17 +170,9 @@ jobs:
- *restore_node_modules
- run: yarn build-combined
- persist_to_workspace:
root: build2
root: .
paths:
- facebook-www
- facebook-react-native
- facebook-relay
- oss-stable
- oss-experimental
- react-native
- dist
- sizes-stable
- sizes-experimental
- build2

get_base_build:
docker: *docker
Expand All @@ -198,25 +190,17 @@ jobs:
scripts/release/download-experimental-build.js --commit=16f3572
mv ./build2 ./base-build
- persist_to_workspace:
root: base-build
root: .
paths:
- facebook-www
- facebook-react-native
- facebook-relay
- oss-stable
- oss-experimental
- react-native
- dist
- sizes-stable
- sizes-experimental
- base-build

process_artifacts_combined:
docker: *docker
environment: *environment
steps:
- checkout
- attach_workspace:
at: build2
at: .
- run: yarn workspaces info | head -n -1 > workspace_info.txt
- *restore_node_modules
- run: echo "<< pipeline.git.revision >>" >> build2/COMMIT_SHA
Expand All @@ -225,6 +209,18 @@ jobs:
- store_artifacts:
path: ./build2.tgz

sizebot:
docker: *docker
environment: *environment
steps:
- checkout
- attach_workspace:
at: .
- run: yarn workspaces info | head -n -1 > workspace_info.txt
- *restore_node_modules
- run:
command: node ./scripts/tasks/danger

build_devtools_and_process_artifacts:
docker: *docker
environment: *environment
Expand Down Expand Up @@ -291,38 +287,6 @@ jobs:
process_artifacts: *process_artifacts
process_artifacts_experimental: *process_artifacts

sizebot_stable:
docker: *docker
environment: *environment
steps:
- checkout
- attach_workspace: *attach_workspace
- run: yarn workspaces info | head -n -1 > workspace_info.txt
- *restore_node_modules
# This runs in the process_artifacts job, too, but it's faster to run
# this step in both jobs instead of running the jobs sequentially
- run: node ./scripts/rollup/consolidateBundleSizes.js
- run:
environment:
RELEASE_CHANNEL: stable
command: node ./scripts/tasks/danger

sizebot_experimental:
docker: *docker
environment: *environment
steps:
- checkout
- attach_workspace: *attach_workspace
- run: yarn workspaces info | head -n -1 > workspace_info.txt
- *restore_node_modules
# This runs in the process_artifacts job, too, but it's faster to run
# this step in both jobs instead of running the jobs sequentially
- run: node ./scripts/rollup/consolidateBundleSizes.js
- run:
environment:
RELEASE_CHANNEL: experimental
command: node ./scripts/tasks/danger

yarn_lint_build:
docker: *docker
environment: *environment
Expand Down Expand Up @@ -371,7 +335,7 @@ jobs:
steps:
- checkout
- attach_workspace:
at: build2
at: .
- run: yarn workspaces info | head -n -1 > workspace_info.txt
- *restore_node_modules
- run: yarn test --build <<parameters.args>> --ci
Expand Down Expand Up @@ -424,9 +388,6 @@ workflows:
- process_artifacts:
requires:
- RELEASE_CHANNEL_stable_yarn_build
- sizebot_stable:
requires:
- RELEASE_CHANNEL_stable_yarn_build
- RELEASE_CHANNEL_stable_yarn_lint_build:
requires:
- RELEASE_CHANNEL_stable_yarn_build
Expand All @@ -443,9 +404,6 @@ workflows:
- process_artifacts_experimental:
requires:
- yarn_build
- sizebot_experimental:
requires:
- yarn_build
- yarn_lint_build:
requires:
- yarn_build
Expand Down Expand Up @@ -528,6 +486,10 @@ workflows:
- get_base_build:
requires:
- setup
- sizebot:
requires:
- get_base_build
- yarn_build_combined
fuzz_tests:
triggers:
- schedule:
Expand Down
164 changes: 46 additions & 118 deletions dangerfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,35 +25,11 @@
//
// `DANGER_GITHUB_API_TOKEN=[ENV_ABOVE] yarn danger pr https://github.com/facebook/react/pull/11865

const {markdown, danger, warn} = require('danger');
const fetch = require('node-fetch');
const {markdown, danger} = require('danger');

const {generateResultsArray} = require('./scripts/rollup/stats');
const {existsSync, readFileSync} = require('fs');
const {exec} = require('child_process');

// This must match the name of the CI job that creates the build artifacts
const RELEASE_CHANNEL =
process.env.RELEASE_CHANNEL === 'experimental' ? 'experimental' : 'stable';
const artifactsJobName =
process.env.RELEASE_CHANNEL === 'experimental'
? 'process_artifacts_experimental'
: 'process_artifacts';

if (!existsSync('./build/bundle-sizes.json')) {
// This indicates the build failed previously.
// In that case, there's nothing for the Dangerfile to do.
// Exit early to avoid leaving a redundant (and potentially confusing) PR comment.
warn(
'No bundle size information found. This indicates the build ' +
'job failed.'
);
process.exit(0);
}

const currentBuildResults = JSON.parse(
readFileSync('./build/bundle-sizes.json')
);
const {readFileSync, readdirSync} = require('fs');
const path = require('path');

/**
* Generates a Markdown table
Expand Down Expand Up @@ -100,99 +76,23 @@ function setBoldness(row, isBold) {
}
}

/**
* Gets the commit that represents the merge between the current branch
* and master.
*/
function git(args) {
return new Promise(res => {
exec('git ' + args, (err, stdout, stderr) => {
if (err) {
throw err;
} else {
res(stdout.trim());
}
});
});
}

(async function() {
// Use git locally to grab the commit which represents the place
// where the branches differ
const upstreamRepo = danger.github.pr.base.repo.full_name;
if (upstreamRepo !== 'facebook/react') {
// Exit unless we're running in the main repo
return;
}

markdown(`## Size changes (${RELEASE_CHANNEL})`);

const upstreamRef = danger.github.pr.base.ref;
await git(`remote add upstream https://github.com/facebook/react.git`);
await git('fetch upstream');
const baseCommit = await git(`merge-base HEAD upstream/${upstreamRef}`);

let previousBuildResults = null;
try {
let baseCIBuildId = null;
const statusesResponse = await fetch(
`https://api.github.com/repos/facebook/react/commits/${baseCommit}/status`
);
const {statuses, state} = await statusesResponse.json();
if (state === 'failure') {
warn(`Base commit is broken: ${baseCommit}`);
return;
function getBundleSizes(pathToSizesDir) {
const filenames = readdirSync(pathToSizesDir);
let bundleSizes = [];
for (let i = 0; i < filenames.length; i++) {
const filename = filenames[i];
if (filename.endsWith('.json')) {
const json = readFileSync(path.join(pathToSizesDir, filename));
bundleSizes.push(...JSON.parse(json).bundleSizes);
}
for (let i = 0; i < statuses.length; i++) {
const status = statuses[i];
if (status.context === `ci/circleci: ${artifactsJobName}`) {
if (status.state === 'success') {
baseCIBuildId = /\/facebook\/react\/([0-9]+)/.exec(
status.target_url
)[1];
break;
}
if (status.state === 'pending') {
warn(`Build job for base commit is still pending: ${baseCommit}`);
return;
}
}
}

if (baseCIBuildId === null) {
warn(`Could not find build artifacts for base commit: ${baseCommit}`);
return;
}

const baseArtifactsInfoResponse = await fetch(
`https://circleci.com/api/v1.1/project/github/facebook/react/${baseCIBuildId}/artifacts`
);
const baseArtifactsInfo = await baseArtifactsInfoResponse.json();

for (let i = 0; i < baseArtifactsInfo.length; i++) {
const info = baseArtifactsInfo[i];
if (info.path.endsWith('bundle-sizes.json')) {
const resultsResponse = await fetch(info.url);
previousBuildResults = await resultsResponse.json();
break;
}
}
} catch (error) {
warn(`Failed to fetch build artifacts for base commit: ${baseCommit}`);
return;
}

if (previousBuildResults === null) {
warn(`Could not find build artifacts for base commit: ${baseCommit}`);
return;
}
return {bundleSizes};
}

async function printResultsForChannel(baseResults, headResults) {
// Take the JSON of the build response and
// make an array comparing the results for printing
const results = generateResultsArray(
currentBuildResults,
previousBuildResults
);
const results = generateResultsArray(baseResults, headResults);

const packagesToShow = results
.filter(
Expand Down Expand Up @@ -281,9 +181,6 @@ function git(args) {
<details>
<summary>Details of bundled changes.</summary>
<p>Comparing: ${baseCommit}...${danger.github.pr.head.sha}</p>
${allTables.join('\n')}
</details>
Expand All @@ -292,4 +189,35 @@ function git(args) {
} else {
markdown('No significant bundle size changes to report.');
}
}

(async function() {
// Use git locally to grab the commit which represents the place
// where the branches differ

const upstreamRepo = danger.github.pr.base.repo.full_name;
if (upstreamRepo !== 'facebook/react') {
// Exit unless we're running in the main repo
return;
}

markdown('## Size changes');

const headSha = (readFileSync('./build2/COMMIT_SHA') + '').trim();
const headSizesStable = getBundleSizes('./build2/sizes-stable');
const headSizesExperimental = getBundleSizes('./build2/sizes-experimental');

const baseSha = (readFileSync('./base-build/COMMIT_SHA') + '').trim();
const baseSizesStable = getBundleSizes('./base-build/sizes-stable');
const baseSizesExperimental = getBundleSizes(
'./base-build/sizes-experimental'
);

markdown(`<p>Comparing: ${baseSha}...${headSha}</p>`);

markdown('## Stable channel');
printResultsForChannel(baseSizesStable, headSizesStable);

markdown('## Experimental channel');
printResultsForChannel(baseSizesExperimental, headSizesExperimental);
})();

0 comments on commit ba4aafb

Please sign in to comment.