Skip to content

Commit 6a5f51f

Browse files
ci: generate diff for NPM package (#3207)
1 parent 8ca3d89 commit 6a5f51f

File tree

5 files changed

+131
-0
lines changed

5 files changed

+131
-0
lines changed

.github/workflows/ci.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,30 @@ jobs:
209209
- name: Run Benchmark
210210
run: 'npm run benchmark -- --revs HEAD HEAD~1'
211211

212+
diff-npm-package:
213+
name: Diff content of NPM package
214+
runs-on: ubuntu-latest
215+
steps:
216+
- name: Checkout repo
217+
uses: actions/checkout@v2
218+
with:
219+
fetch-depth: 2
220+
221+
- name: Setup Node.js
222+
uses: actions/setup-node@v2
223+
with:
224+
node-version: ${{ env.NODE_VERSION_USED_FOR_DEVELOPMENT }}
225+
226+
- name: Generate report
227+
run: 'node resources/diff-npm-package.js ${{ github.event.pull_request.base.sha }} HEAD'
228+
229+
- name: Upload generated report
230+
uses: actions/upload-artifact@v2
231+
with:
232+
name: npm-dist-diff.html
233+
path: ./npm-dist-diff.html
234+
if-no-files-found: ignore
235+
212236
deploy-to-npm-branch:
213237
name: Deploy to `npm` branch
214238
runs-on: ubuntu-latest

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
# https://help.github.com/articles/ignoring-files/#create-a-global-gitignore
66
# https://www.gitignore.io/
77

8+
/diff-npm-package.html
89
/.eslintcache
910
/node_modules
1011
/coverage

.prettierignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# Copied from '.gitignore', please keep it in sync.
2+
/diff-npm-package.html
23
/.eslintcache
34
/node_modules
45
/coverage

cspell.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
language: en
22
ignorePaths:
33
# Copied from '.gitignore', please keep it in sync.
4+
- diff-npm-package.html
45
- .eslintcache
56
- node_modules
67
- coverage

resources/diff-npm-package.js

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
'use strict';
2+
3+
const os = require('os');
4+
const fs = require('fs');
5+
const path = require('path');
6+
const cp = require('child_process');
7+
8+
const LOCAL = 'local';
9+
const localRepoDir = path.join(__dirname, '..');
10+
const tmpDir = path.join(os.tmpdir(), 'graphql-js-npm-diff');
11+
fs.rmSync(tmpDir, { recursive: true, force: true });
12+
fs.mkdirSync(tmpDir);
13+
14+
const args = process.argv.slice(2);
15+
let [fromRevision, toRevision] = args;
16+
if (args.length < 2) {
17+
fromRevision = fromRevision ?? 'HEAD';
18+
toRevision = toRevision ?? LOCAL;
19+
console.warn(
20+
`Assuming you meant: diff-npm-package ${fromRevision} ${toRevision}`,
21+
);
22+
}
23+
24+
console.log(`📦 Building NPM package for ${fromRevision}...`);
25+
const fromPackage = prepareNPMPackage(fromRevision);
26+
27+
console.log(`📦 Building NPM package for ${toRevision}...`);
28+
const toPackage = prepareNPMPackage(toRevision);
29+
30+
console.log('➖➕ Generating diff...');
31+
const diff = exec(`npm diff --diff=${fromPackage} --diff=${toPackage}`);
32+
33+
if (diff === '') {
34+
console.log('No changes found!');
35+
} else {
36+
const reportPath = path.join(localRepoDir, 'npm-dist-diff.html');
37+
fs.writeFileSync(reportPath, generateReport(diff), 'utf-8');
38+
console.log('Report saved to: ', reportPath);
39+
}
40+
41+
function generateReport(diffString) {
42+
return `
43+
<!DOCTYPE html>
44+
<html lang="en-us">
45+
<head>
46+
<meta charset="utf-8" />
47+
<!-- Make sure to load the highlight.js CSS file before the Diff2Html CSS file -->
48+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.7.1/styles/github.min.css" />
49+
<link
50+
rel="stylesheet"
51+
type="text/css"
52+
href="https://cdn.jsdelivr.net/npm/diff2html/bundles/css/diff2html.min.css"
53+
/>
54+
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/diff2html/bundles/js/diff2html-ui.min.js"></script>
55+
</head>
56+
<script>
57+
const diffString = ${JSON.stringify(diffString)};
58+
59+
document.addEventListener('DOMContentLoaded', () => {
60+
const targetElement = document.getElementById('myDiffElement');
61+
const configuration = {
62+
drawFileList: true,
63+
fileContentToggle: true,
64+
matching: 'lines',
65+
outputFormat: 'side-by-side',
66+
renderNothingWhenEmpty: false,
67+
};
68+
const diff2htmlUi = new Diff2HtmlUI(targetElement, diffString, configuration);
69+
diff2htmlUi.draw();
70+
diff2htmlUi.highlightCode();
71+
});
72+
</script>
73+
<body>
74+
<div id="myDiffElement"></div>
75+
</body>
76+
</html>
77+
`;
78+
}
79+
function prepareNPMPackage(revision) {
80+
if (revision === LOCAL) {
81+
exec('npm --quiet run build:npm', { cwd: localRepoDir });
82+
return path.join(localRepoDir, 'npmDist');
83+
}
84+
85+
// Returns the complete git hash for a given git revision reference.
86+
const hash = exec(`git rev-parse "${revision}"`);
87+
88+
const repoDir = path.join(tmpDir, hash);
89+
fs.rmSync(repoDir, { recursive: true, force: true });
90+
fs.mkdirSync(repoDir);
91+
exec(`git archive "${hash}" | tar -xC "${repoDir}"`);
92+
exec('npm --quiet ci', { cwd: repoDir });
93+
exec('npm --quiet run build:npm', { cwd: repoDir });
94+
return path.join(repoDir, 'npmDist');
95+
}
96+
97+
function exec(command, options = {}) {
98+
const result = cp.execSync(command, {
99+
encoding: 'utf-8',
100+
stdio: ['inherit', 'pipe', 'inherit'],
101+
...options,
102+
});
103+
return result?.trimEnd();
104+
}

0 commit comments

Comments
 (0)