Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: generate diff for NPM package #3207

Merged
merged 1 commit into from Jul 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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();
}