Skip to content

Commit

Permalink
CI: add initial support of Deno build (#2636)
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 eb1cfe2
Show file tree
Hide file tree
Showing 12 changed files with 255 additions and 152 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 }]]
}
]
}
5 changes: 4 additions & 1 deletion .babelrc.json
Expand Up @@ -23,7 +23,10 @@
"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 }}
4 changes: 3 additions & 1 deletion .gitignore
Expand Up @@ -8,6 +8,8 @@
.eslintcache
node_modules
coverage
dist
npmDist
denoDist
benchmarkDist
npm
deno
3 changes: 3 additions & 0 deletions cspell.json
Expand Up @@ -19,6 +19,9 @@
"Tatooine",
"astromech",

// TODO: contribute upstream
"deno",

// TODO: remove bellow words
"Graphi", // GraphiQL
"QL's", // GraphQL's
Expand Down
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
8 changes: 3 additions & 5 deletions resources/add-extension-to-import-paths.js
Expand Up @@ -16,7 +16,7 @@
* export { foo } from './bar.mjs';
*
*/
module.exports = function addExtensionToImportPaths(context) {
module.exports = function addExtensionToImportPaths(context, { extension }) {
const { types } = context;

return {
Expand All @@ -34,10 +34,8 @@ module.exports = function addExtensionToImportPaths(context) {

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);
}
}
};
35 changes: 35 additions & 0 deletions resources/build-deno.js
@@ -0,0 +1,35 @@
// @noflow

'use strict';

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

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

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 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');
}
77 changes: 77 additions & 0 deletions resources/build-npm.js
@@ -0,0 +1,77 @@
// @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 eb1cfe2

Please sign in to comment.