Skip to content

Commit

Permalink
CI: add initial support of Deno build
Browse files Browse the repository at this point in the history
Motivation #2566
  • Loading branch information
IvanGoncharov committed Jun 10, 2020
1 parent 75e0ec7 commit 75e4bf2
Show file tree
Hide file tree
Showing 11 changed files with 252 additions and 153 deletions.
13 changes: 13 additions & 0 deletions .babelrc-deno.json
@@ -0,0 +1,13 @@
{
"plugins": [
"@babel/plugin-transform-flow-strip-types",
["./resources/add-extension-to-import-paths", { "extension": "mjs" }],
"./resources/inline-invariant"
],
"overrides": [
{
"include": "src/error/GraphQLError.js",
"plugins": [["@babel/plugin-transform-classes", { "loose": false }]]
}
]
}
2 changes: 1 addition & 1 deletion .babelrc.json
Expand Up @@ -23,7 +23,7 @@
"mjs": {
"presets": [["@babel/preset-env", { "modules": false }]],
"plugins": [
"./resources/add-extension-to-import-paths",
["./resources/add-extension-to-import-paths", { "extension": "mjs" }],
"./resources/inline-invariant"
]
}
Expand Down
49 changes: 44 additions & 5 deletions .github/workflows/ci.yml
Expand Up @@ -49,8 +49,11 @@ jobs:
- name: Spellcheck
run: npm run check:spelling

- name: Build package
run: npm run build
- name: Build NPM package
run: npm run build:npm

- name: Build Deno package
run: npm run build:deno

fuzz:
name: Run fuzzing tests
Expand Down Expand Up @@ -196,10 +199,46 @@ jobs:
- name: Install Dependencies
run: npm ci

- name: Build package
run: npm run build
- name: Build NPM package
run: npm run build:npm

- name: Deploy to `npm` branch
run: npm run gitpublish:npm
env:
GH_TOKEN: ${{ secrets.GH_NPM_BRANCH_PUBLISH_TOKEN }}

deploy-to-deno-branch:
name: Deploy to `deno` branch
runs-on: ubuntu-latest
if: |
github.event_name == 'push' &&
github.repository == 'graphql/graphql-js' &&
github.ref == 'refs/heads/master'
needs: [test, fuzz, lint]
steps:
- name: Checkout repo
uses: actions/checkout@v2

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

- name: Cache Node.js modules
uses: actions/cache@v2
with:
path: ~/.npm
key: ${{ runner.OS }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.OS }}-node-
- name: Install Dependencies
run: npm ci

- name: Build Deno package
run: npm run build:deno

- name: Deploy to `npm` branch
run: npm run gitpublish
run: npm run gitpublish:deno
env:
GH_TOKEN: ${{ secrets.GH_NPM_BRANCH_PUBLISH_TOKEN }}
3 changes: 2 additions & 1 deletion .gitignore
Expand Up @@ -8,6 +8,7 @@
.eslintcache
node_modules
coverage
dist
npmDist
denoDist
benchmarkDist
npm
8 changes: 5 additions & 3 deletions package.json
Expand Up @@ -28,7 +28,7 @@
},
"scripts": {
"test": "npm run prettier:check && npm run lint && npm run check && npm run testonly && npm run check:ts && npm run check:spelling",
"test:ci": "npm run prettier:check && npm run lint -- --no-cache && npm run check && npm run testonly:cover && npm run check:ts && npm run check:spelling && npm run build",
"test:ci": "npm run prettier:check && npm run lint -- --no-cache && npm run check && npm run testonly:cover && npm run check:ts && npm run check:spelling && npm run build:npm && npm run build:deno",
"fuzzonly": "mocha --full-trace src/**/__tests__/**/*-fuzz.js",
"testonly": "mocha --full-trace src/**/__tests__/**/*-test.js",
"testonly:cover": "nyc npm run testonly",
Expand All @@ -40,11 +40,13 @@
"check:ts": "dtslint src",
"check:cover": "node resources/check-cover.js && nyc report --nycrc-path .nycflowrc.yml",
"check:spelling": "cspell \"./{src/**/,resources/**/}*.{js,ts,md,graphql}\"",
"build": "node resources/build.js",
"build:npm": "node resources/build-npm.js",
"build:deno": "node resources/build-deno.js",
"changelog": "node resources/gen-changelog.js",
"preversion": ". ./resources/checkgit.sh && npm ci",
"version": "node resources/gen-version.js && npm test && git add src/version.js",
"gitpublish": ". ./resources/gitpublish.sh"
"gitpublish:npm": "node ./resources/gitpublish.js npm npmDist",
"gitpublish:deno": "node ./resources/gitpublish.js deon denoDist"
},
"dependencies": {},
"devDependencies": {
Expand Down
12 changes: 6 additions & 6 deletions resources/add-extension-to-import-paths.js
Expand Up @@ -2,6 +2,8 @@

'use strict';

const path = require('path');

/**
* Adds extension to all paths imported inside MJS files
*
Expand All @@ -16,7 +18,7 @@
* export { foo } from './bar.mjs';
*
*/
module.exports = function addExtensionToImportPaths(context) {
module.exports = function addExtensionToImportPaths(context, { extension }) {
const { types } = context;

return {
Expand All @@ -26,18 +28,16 @@ module.exports = function addExtensionToImportPaths(context) {
},
};

function replaceImportPath(path) {
function replaceImportPath(path, state) {
// bail if the declaration doesn't have a source, e.g. "export { foo };"
if (!path.node.source) {
return;
}

const source = path.node.source.value;
if (source.startsWith('./') || source.startsWith('../')) {
if (!source.endsWith('.mjs')) {
const newSourceNode = types.stringLiteral(source + '.mjs');
path.get('source').replaceWith(newSourceNode);
}
const newSourceNode = types.stringLiteral(source + '.' + extension);
path.get('source').replaceWith(newSourceNode);
}
}
};
39 changes: 39 additions & 0 deletions resources/build-deno.js
@@ -0,0 +1,39 @@
// @noflow

'use strict';

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

const babel = require('@babel/core');

const flowRemoveTypes = require('flow-remove-types');

const { rmdirRecursive, readdirRecursive, showDirStats } = require('./utils');

if (require.main === module) {
rmdirRecursive('./denoDist');
fs.mkdirSync('./denoDist');

const srcFiles = readdirRecursive('./src', { ignoreDir: /^__.*__$/ });
for (const filepath of srcFiles) {
const srcPath = path.join('./src', filepath);
const destPath = path.join('./denoDist', filepath);

fs.mkdirSync(path.dirname(destPath), { recursive: true });
if (filepath.endsWith('.js')) {
const source = fs.readFileSync(srcPath, 'utf8');

const options = { babelrc: false, configFile: './.babelrc-deno.json' };
const output = babel.transformFileSync(srcPath, options).code + '\n';
fs.writeFileSync(destPath, output);
} else if (filepath.endsWith('.d.ts')) {
fs.copyFileSync(srcPath, destPath);
}
}

fs.copyFileSync('./LICENSE', './denoDist/LICENSE');
fs.copyFileSync('./README.md', './denoDist/README.md');

showDirStats('./denoDist');
}
74 changes: 74 additions & 0 deletions resources/build-npm.js
@@ -0,0 +1,74 @@
// @noflow

'use strict';

const fs = require('fs');
const path = require('path');
const assert = require('assert');

const babel = require('@babel/core');

const { rmdirRecursive, readdirRecursive, showDirStats } = require('./utils');

if (require.main === module) {
rmdirRecursive('./npmDist');
fs.mkdirSync('./npmDist');

const srcFiles = readdirRecursive('./src', { ignoreDir: /^__.*__$/ });
for (const filepath of srcFiles) {
const srcPath = path.join('./src', filepath);
const destPath = path.join('./npmDist', filepath);

fs.mkdirSync(path.dirname(destPath), { recursive: true });
if (filepath.endsWith('.js')) {
fs.copyFileSync(srcPath, destPath + '.flow');

const cjs = babelBuild(srcPath, { envName: 'cjs' });
fs.writeFileSync(destPath, cjs);

const mjs = babelBuild(srcPath, { envName: 'mjs' });
fs.writeFileSync(destPath.replace(/\.js$/, '.mjs'), mjs);
} else if (filepath.endsWith('.d.ts')) {
fs.copyFileSync(srcPath, destPath);
}
}

fs.copyFileSync('./LICENSE', './npmDist/LICENSE');
fs.copyFileSync('./README.md', './npmDist/README.md');

// Should be done as the last step so only valid packages can be published
const packageJSON = buildPackageJSON();
fs.writeFileSync('./npmDist/package.json', JSON.stringify(packageJSON, null, 2));

showDirStats('./npmDist');
}

function babelBuild(srcPath, options) {
return babel.transformFileSync(srcPath, options).code + '\n';
}

function buildPackageJSON() {
const packageJSON = require('../package.json');
delete packageJSON.private;
delete packageJSON.scripts;
delete packageJSON.devDependencies;

packageJSON.engines = packageJSON.engines_on_npm;
delete packageJSON.engines_on_npm;

const versionJS = require('../npmDist/version.js');
assert(
versionJS.version === packageJSON.version,
'Version in package.json and version.js should match',
);

if (versionJS.preReleaseTag != null) {
const [tag] = versionJS.preReleaseTag.split('.');
assert(['alpha', 'beta', 'rc'].includes(tag), `"${tag}" tag is supported.`);

assert(!packageJSON.publishConfig, 'Can not override "publishConfig".');
packageJSON.publishConfig = { tag: tag || 'latest' };
}

return packageJSON;
}
120 changes: 0 additions & 120 deletions resources/build.js

This file was deleted.

0 comments on commit 75e4bf2

Please sign in to comment.