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

Publish pre-built bundles to npm #7398

Merged
merged 13 commits into from
Apr 15, 2021
3 changes: 2 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ jobs:
registry-url: "https://registry.npmjs.org/"
- run: npm install
- run: npm test
- run: npm publish --access public
- run: npm run release-build
- run: npm publish build/ --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.idea
/node_modules/
*.log
build/
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
.prettierignore
.prettierrc
.vscode
build
docs
test
schemas
Expand Down
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ LICENSE
.editorconfig
/package-lock.json
/CODE_OF_CONDUCT.md
build/
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"fix": "node scripts/fix",
"mirror": "node scripts/mirror",
"stats": "node scripts/statistics",
"release-build": "node scripts/release-build",
"release-pulls": "node scripts/release-pulls",
"release-stats": "node scripts/release-stats",
"show-errors": "npm test 1> /dev/null",
Expand Down
93 changes: 93 additions & 0 deletions scripts/release-build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
'use strict';

const fs = require('fs').promises;
const path = require('path');

const directory = './build/';

const verbatimFiles = ['LICENSE', 'README.md', 'index.d.ts', 'types.d.ts'];

// Returns a string representing data ready for writing to JSON file
function createDataBundle() {
const bcd = require('../index.js');
const string = JSON.stringify(bcd);
return string;
}

// Returns a promise for writing the data to JSON file
async function writeData() {
const dest = path.resolve(directory, 'data.json');
const data = createDataBundle();
await fs.writeFile(dest, data);
}

// Returns an array of promises for copying of all files that don't need transformation
async function copyFiles() {
for (const file of verbatimFiles) {
const src = path.join('./', file);
const dest = path.join(directory, file);
await fs.copyFile(src, dest);
}
}

function createManifest() {
const full = require('../package.json');
const minimal = { main: 'data.json' };

const minimalKeys = [
'name',
'version',
'description',
'repository',
'keywords',
'author',
'license',
'bugs',
'homepage',
'types',
];

for (const key of minimalKeys) {
if (key in full) {
minimal[key] = full[key];
} else {
throw `Could not create a complete manifest! ${key} is missing!`;
}
}
return JSON.stringify(minimal);
}

async function writeManifest() {
const dest = path.resolve(directory, 'package.json');
const manifest = createManifest();
await fs.writeFile(dest, manifest);
}

async function main() {
// Remove existing files, if there are any
await fs
.rmdir(directory, {
force: true,
recursive: true,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By switching Node versions (with nodenv), I discovered that the recursive option doesn't work on Node 10. But it's EOL in ~2 weeks. I think we can tolerate the (unlikely) annoyance for that long.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, now that I think on it some more: I guess it doesn't matter at all. If all we publish is a .json file, then we can adopt whatever version of Node we want for development.

(Though this also suggests that, should we desire to expose utilities for working with compat data, it would need to be as a separate package.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By switching Node versions (with nodenv), I discovered that the recursive option doesn't work on Node 10.

Yes, the docs say recursive was introduced in 12.

If all we publish is a .json file, then we can adopt whatever version of Node we want for development.

I'll confess: it was my secret plan all along :) . More recent NodeJS versions have nice features, so I wanted to simplify transition to modern NodeJS should you ever choose to.

(Though this also suggests that, should we desire to expose utilities for working with compat data, it would need to be as a separate package.)

Does BCD expose any utilities now?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll confess: it was my secret plan all along :)

😄 Yeah, there's a ton of hidden benefits to this. For example, we could add internal-only fields to the schema that might make working with the data more ergonomic, but filter it out before building the final data for consumers.

Does BCD expose any utilities now?

No, not yet. It's something we've maybe inched toward (see #9441), but have been sort of cautious about it. I rather like the idea of decoupling the data from such utilities anyway and this PR would sort of force that decision.

})
.catch(e => {
// Missing folder is not an issue since we wanted to delete it anyway
if (e.code !== 'ENOENT') throw e;
});

// Crate a new directory
await fs.mkdir(directory);

await writeManifest();
await writeData();
await copyFiles();

console.log('Data bundle is ready');
}

// This is needed because NodeJS does not support top-level await.
// Also, make sure to log all errors and exit with failure code.
main().catch(e => {
console.error(e);
process.exit(1);
});
15 changes: 15 additions & 0 deletions scripts/release-build.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
'use strict';
const assert = require('assert');
const { execSync } = require('child_process');

const prebuiltPath = '../build';

describe('release-build', () => {
it('pre-built bundles are identical to the source', done => {
execSync('npm run release-build');
const regular = require('../');
const bundled = require(prebuiltPath);
assert.deepEqual(regular, bundled);
done();
}).timeout(5000); // Timeout must be long enough for all the file I/O
});