Skip to content

Commit

Permalink
ci: generate diff for NPM package (#3207)
Browse files Browse the repository at this point in the history
  • Loading branch information
IvanGoncharov committed Jul 7, 2021
1 parent 8ca3d89 commit 6a5f51f
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 0 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/ci.yml
Expand Up @@ -209,6 +209,30 @@ jobs:
- name: Run Benchmark
run: 'npm run benchmark -- --revs HEAD HEAD~1'

diff-npm-package:
name: Diff content of NPM package
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v2
with:
fetch-depth: 2

- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: ${{ env.NODE_VERSION_USED_FOR_DEVELOPMENT }}

- name: Generate report
run: 'node resources/diff-npm-package.js ${{ github.event.pull_request.base.sha }} HEAD'

- name: Upload generated report
uses: actions/upload-artifact@v2
with:
name: npm-dist-diff.html
path: ./npm-dist-diff.html
if-no-files-found: ignore

deploy-to-npm-branch:
name: Deploy to `npm` branch
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -5,6 +5,7 @@
# https://help.github.com/articles/ignoring-files/#create-a-global-gitignore
# https://www.gitignore.io/

/diff-npm-package.html
/.eslintcache
/node_modules
/coverage
Expand Down
1 change: 1 addition & 0 deletions .prettierignore
@@ -1,4 +1,5 @@
# Copied from '.gitignore', please keep it in sync.
/diff-npm-package.html
/.eslintcache
/node_modules
/coverage
Expand Down
1 change: 1 addition & 0 deletions cspell.yml
@@ -1,6 +1,7 @@
language: en
ignorePaths:
# Copied from '.gitignore', please keep it in sync.
- diff-npm-package.html
- .eslintcache
- node_modules
- coverage
Expand Down
104 changes: 104 additions & 0 deletions resources/diff-npm-package.js
@@ -0,0 +1,104 @@
'use strict';

const os = require('os');
const fs = require('fs');
const path = require('path');
const cp = require('child_process');

const LOCAL = 'local';
const localRepoDir = path.join(__dirname, '..');
const tmpDir = path.join(os.tmpdir(), 'graphql-js-npm-diff');
fs.rmSync(tmpDir, { recursive: true, force: true });
fs.mkdirSync(tmpDir);

const args = process.argv.slice(2);
let [fromRevision, toRevision] = args;
if (args.length < 2) {
fromRevision = fromRevision ?? 'HEAD';
toRevision = toRevision ?? LOCAL;
console.warn(
`Assuming you meant: diff-npm-package ${fromRevision} ${toRevision}`,
);
}

console.log(`📦 Building NPM package for ${fromRevision}...`);
const fromPackage = prepareNPMPackage(fromRevision);

console.log(`📦 Building NPM package for ${toRevision}...`);
const toPackage = prepareNPMPackage(toRevision);

console.log('➖➕ Generating diff...');
const diff = exec(`npm diff --diff=${fromPackage} --diff=${toPackage}`);

if (diff === '') {
console.log('No changes found!');
} else {
const reportPath = path.join(localRepoDir, 'npm-dist-diff.html');
fs.writeFileSync(reportPath, generateReport(diff), 'utf-8');
console.log('Report saved to: ', reportPath);
}

function generateReport(diffString) {
return `
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8" />
<!-- Make sure to load the highlight.js CSS file before the Diff2Html CSS file -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.7.1/styles/github.min.css" />
<link
rel="stylesheet"
type="text/css"
href="https://cdn.jsdelivr.net/npm/diff2html/bundles/css/diff2html.min.css"
/>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/diff2html/bundles/js/diff2html-ui.min.js"></script>
</head>
<script>
const diffString = ${JSON.stringify(diffString)};
document.addEventListener('DOMContentLoaded', () => {
const targetElement = document.getElementById('myDiffElement');
const configuration = {
drawFileList: true,
fileContentToggle: true,
matching: 'lines',
outputFormat: 'side-by-side',
renderNothingWhenEmpty: false,
};
const diff2htmlUi = new Diff2HtmlUI(targetElement, diffString, configuration);
diff2htmlUi.draw();
diff2htmlUi.highlightCode();
});
</script>
<body>
<div id="myDiffElement"></div>
</body>
</html>
`;
}
function prepareNPMPackage(revision) {
if (revision === LOCAL) {
exec('npm --quiet run build:npm', { cwd: localRepoDir });
return path.join(localRepoDir, 'npmDist');
}

// Returns the complete git hash for a given git revision reference.
const hash = exec(`git rev-parse "${revision}"`);

const repoDir = path.join(tmpDir, hash);
fs.rmSync(repoDir, { recursive: true, force: true });
fs.mkdirSync(repoDir);
exec(`git archive "${hash}" | tar -xC "${repoDir}"`);
exec('npm --quiet ci', { cwd: repoDir });
exec('npm --quiet run build:npm', { cwd: repoDir });
return path.join(repoDir, 'npmDist');
}

function exec(command, options = {}) {
const result = cp.execSync(command, {
encoding: 'utf-8',
stdio: ['inherit', 'pipe', 'inherit'],
...options,
});
return result?.trimEnd();
}

0 comments on commit 6a5f51f

Please sign in to comment.