[build] add --all-platforms flag (#24363)

The build script currently builds artifacts for all platforms, which is a slight waste of time on CI and when testing locally. Instead, the default behavior of the build script in this PR is to only build the artifact for the current platform. If the `--all-platforms` flag is supplied (the default when run via `yarn build`, and therefore when building a release) artifacts for all platforms will be created along with deb/rpm packages.
This commit is contained in:
Spencer 2018-10-23 13:29:15 -07:00 committed by GitHub
parent 619211c5ce
commit 1bcdeab4dd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 124 additions and 48 deletions

View file

@ -38,7 +38,7 @@
"test:server": "grunt test:server",
"test:coverage": "grunt test:coverage",
"checkLicenses": "grunt licenses --dev",
"build": "node scripts/build",
"build": "node scripts/build --all-platforms",
"start": "node scripts/kibana --dev",
"debug": "node --nolazy --inspect scripts/kibana --dev",
"debug-break": "node --nolazy --inspect-brk scripts/kibana --dev",

View file

@ -24,7 +24,7 @@ The majority of this logic is extracted from the grunt build that has existed fo
**Config**: [lib/config.js] defines the config used to execute tasks. It is mostly used to determine absolute paths to specific locations, and to get access to the Platforms.
**Platform**: [lib/platform.js] defines the Platform objects, which define the different platforms we build for. Use `config.getPlatforms()` to get the list of platforms, or `config.getLinux/Windows/MacPlatform()` to get a specific platform
**Platform**: [lib/platform.js] defines the Platform objects, which define the different platforms we build for. Use `config.getTargetPlatforms()` to get the list of platforms we are targeting in this build, `config.getNodePlatforms()` to get the list of platform we will download node for, or `config.getLinux/Windows/MacPlatform()` to get a specific platform.
**Log**: We uses the `ToolingLog` defined in [../tooling_log/tooling_log.js]

View file

@ -62,6 +62,7 @@ export async function buildDistributables(options) {
createArchives,
createRpmPackage,
createDebPackage,
targetAllPlatforms,
} = options;
log.verbose('building distributables with options:', {
@ -76,6 +77,7 @@ export async function buildDistributables(options) {
const config = await getConfig({
isRelease,
targetAllPlatforms
});
const run = createRunner({

View file

@ -43,6 +43,7 @@ const flags = getopts(process.argv.slice(0), {
'skip-node-download',
'verbose',
'debug',
'all-platforms'
],
alias: {
v: 'verbose',
@ -74,6 +75,7 @@ if (flags.help) {
--no-oss {dim Only produce the default distributable of Kibana}
--skip-archives {dim Don't produce tar/zip archives}
--skip-os-packages {dim Don't produce rpm/deb packages}
--all-platforms {dim Produce archives for all platforms, not just this one}
--rpm {dim Only build the rpm package}
--deb {dim Only build the deb package}
--release {dim Produce a release-ready distributable}
@ -93,7 +95,7 @@ const log = new ToolingLog({
});
function isOsPackageDesired(name) {
if (flags['skip-os-packages']) {
if (flags['skip-os-packages'] || !flags['all-platforms']) {
return false;
}
@ -114,6 +116,7 @@ buildDistributables({
createArchives: !Boolean(flags['skip-archives']),
createRpmPackage: isOsPackageDesired('rpm'),
createDebPackage: isOsPackageDesired('deb'),
targetAllPlatforms: Boolean(flags['all-platforms']),
}).catch(error => {
if (!isErrorLogged(error)) {
log.error('Uncaught error');

View file

@ -26,106 +26,152 @@ import { getConfig } from '../config';
import { getVersionInfo } from '../version_info';
describe('dev/build/lib/config', () => {
let config;
let buildInfo;
before(async () => {
const setup = async function ({ targetAllPlatforms = true } = {}) {
const isRelease = Boolean(Math.round(Math.random()));
config = await getConfig({
const config = await getConfig({
isRelease,
targetAllPlatforms
});
buildInfo = await getVersionInfo({
const buildInfo = await getVersionInfo({
isRelease,
pkg
});
});
after(() => {
config = null;
});
return { config, buildInfo };
};
describe('#getKibanaPkg()', () => {
it('returns the parsed package.json from the Kibana repo', () => {
it('returns the parsed package.json from the Kibana repo', async () => {
const { config } = await setup();
expect(config.getKibanaPkg()).to.eql(pkg);
});
});
describe('#getNodeVersion()', () => {
it('returns the node version from the kibana package.json', () => {
it('returns the node version from the kibana package.json', async () => {
const { config } = await setup();
expect(config.getNodeVersion()).to.eql(pkg.engines.node);
});
});
describe('#getRepoRelativePath()', () => {
it('converts an absolute path to relative path, from the root of the repo', () => {
it('converts an absolute path to relative path, from the root of the repo', async () => {
const { config } = await setup();
expect(config.getRepoRelativePath(__dirname)).to.match(/^src[\/\\]dev[\/\\]build/);
});
});
describe('#resolveFromRepo()', () => {
it('resolves a relative path', () => {
it('resolves a relative path', async () => {
const { config } = await setup();
expect(config.resolveFromRepo('src/dev/build/lib/__tests__'))
.to.be(__dirname);
});
it('resolves a series of relative paths', () => {
it('resolves a series of relative paths', async () => {
const { config } = await setup();
expect(config.resolveFromRepo('src', 'dev', 'build', 'lib', '__tests__'))
.to.be(__dirname);
});
});
describe('#getPlatforms()', () => {
it('returns an array of platform objects', () => {
const platforms = config.getPlatforms();
describe('#getTargetPlatforms()', () => {
it('returns an array of all platform objects', async () => {
const { config } = await setup();
expect(config.getTargetPlatforms().map(p => p.getName()).sort()).to.eql([
'darwin',
'linux',
'windows'
]);
});
it('returns just this platform when targetAllPlatforms = false', async () => {
const { config } = await setup({ targetAllPlatforms: false });
const platforms = config.getTargetPlatforms();
expect(platforms).to.be.an('array');
for (const platform of platforms) {
expect(['windows', 'linux', 'darwin']).to.contain(platform.getName());
expect(platforms).to.have.length(1);
expect(platforms[0]).to.be(config.getPlatformForThisOs());
});
});
describe('#getNodePlatforms()', () => {
it('returns all platforms', async () => {
const { config } = await setup();
expect(config.getTargetPlatforms().map(p => p.getName()).sort()).to.eql([
'darwin',
'linux',
'windows'
]);
});
it('returns this platform and linux, when targetAllPlatforms = false', async () => {
const { config } = await setup({ targetAllPlatforms: false });
const platforms = config.getNodePlatforms();
expect(platforms).to.be.an('array');
expect(platforms).to.have.length(process.platform === 'linux');
if (process.platform !== 'linux') {
expect(platforms).to.have.length(2);
expect(platforms[0]).to.be(config.getPlatformForThisOs());
expect(platforms[1]).to.be(config.getLinuxPlatform());
} else {
expect(platforms).to.have.length(1);
expect(platforms[0]).to.be(config.getLinuxPlatform());
}
});
});
describe('#getLinuxPlatform()', () => {
it('returns the linux platform', () => {
it('returns the linux platform', async () => {
const { config } = await setup();
expect(config.getLinuxPlatform().getName()).to.be('linux');
});
});
describe('#getWindowsPlatform()', () => {
it('returns the windows platform', () => {
it('returns the windows platform', async () => {
const { config } = await setup();
expect(config.getWindowsPlatform().getName()).to.be('windows');
});
});
describe('#getMacPlatform()', () => {
it('returns the mac platform', () => {
it('returns the mac platform', async () => {
const { config } = await setup();
expect(config.getMacPlatform().getName()).to.be('darwin');
});
});
describe('#getPlatformForThisOs()', () => {
it('returns the platform that matches the arch of this machine', () => {
it('returns the platform that matches the arch of this machine', async () => {
const { config } = await setup();
expect(config.getPlatformForThisOs().getName()).to.be(process.platform);
});
});
describe('#getBuildVersion()', () => {
it('returns the version from the build info', () => {
it('returns the version from the build info', async () => {
const { config, buildInfo } = await setup();
expect(config.getBuildVersion()).to.be(buildInfo.buildVersion);
});
});
describe('#getBuildNumber()', () => {
it('returns the number from the build info', () => {
it('returns the number from the build info', async () => {
const { config, buildInfo } = await setup();
expect(config.getBuildNumber()).to.be(buildInfo.buildNumber);
});
});
describe('#getBuildSha()', () => {
it('returns the sha from the build info', () => {
it('returns the sha from the build info', async () => {
const { config, buildInfo } = await setup();
expect(config.getBuildSha()).to.be(buildInfo.buildSha);
});
});
describe('#resolveFromTarget()', () => {
it('resolves a relative path, from the target directory', () => {
it('resolves a relative path, from the target directory', async () => {
const { config } = await setup();
expect(config.resolveFromTarget()).to.be(resolve(__dirname, '../../../../../target'));
});
});

View file

@ -23,13 +23,14 @@ import { platform as getOsPlatform } from 'os';
import { getVersionInfo } from './version_info';
import { createPlatform } from './platform';
export async function getConfig({ isRelease }) {
export async function getConfig({ isRelease, targetAllPlatforms }) {
const pkgPath = resolve(__dirname, '../../../../package.json');
const pkg = require(pkgPath);
const repoRoot = dirname(pkgPath);
const nodeVersion = pkg.engines.node;
const platforms = ['darwin', 'linux', 'windows'].map(createPlatform);
const versionInfo = await getVersionInfo({
isRelease,
pkg,
@ -71,11 +72,37 @@ export async function getConfig({ isRelease }) {
}
/**
* Return the list of Platforms we are targeting
* Return the list of Platforms we are targeting, if --this-platform flag is
* specified only the platform for this OS will be returned
* @return {Array<Platform>}
*/
getPlatforms() {
return platforms;
getTargetPlatforms() {
if (targetAllPlatforms) {
return platforms;
}
return [this.getPlatformForThisOs()];
}
/**
* Return the list of Platforms we need/have node downloads for. We always
* include the linux platform even if we aren't targeting linux so we can
* reliably get the LICENSE file, which isn't included in the windows version
* @return {Array<Platform>}
*/
getNodePlatforms() {
if (targetAllPlatforms) {
return platforms;
}
if (process.platform === 'linux') {
return [this.getLinuxPlatform()];
}
return [
this.getPlatformForThisOs(),
this.getLinuxPlatform()
];
}
/**

View file

@ -155,7 +155,7 @@ export const CleanExtraBinScriptsTask = {
description: 'Cleaning extra bin/* scripts from platform-specific builds',
async run(config, log, build) {
for (const platform of config.getPlatforms()) {
for (const platform of config.getNodePlatforms()) {
if (platform.isWindows()) {
await deleteAll(log, [
build.resolvePathForPlatform(platform, 'bin', '*'),
@ -202,7 +202,7 @@ export const CleanExtraBrowsersTask = {
return paths;
};
};
for (const platform of config.getPlatforms()) {
for (const platform of config.getNodePlatforms()) {
const getBrowserPaths = getBrowserPathsForPlatform(platform);
if (platform.isWindows()) {
await deleteAll(log, getBrowserPaths({ linux: true, darwin: true }));

View file

@ -23,7 +23,7 @@ import { getNodeDownloadInfo } from './nodejs';
export const CreateArchivesSourcesTask = {
description: 'Creating platform-specific archive source directories',
async run(config, log, build) {
await Promise.all(config.getPlatforms().map(async platform => {
await Promise.all(config.getTargetPlatforms().map(async platform => {
// copy all files from generic build source directory into platform-specific build directory
await copyAll(
build.resolvePath('.'),

View file

@ -25,7 +25,7 @@ export const CreateArchivesTask = {
description: 'Creating the archives for each platform',
async run(config, log, build) {
await Promise.all(config.getPlatforms().map(async platform => {
await Promise.all(config.getTargetPlatforms().map(async platform => {
const source = build.resolvePathForPlatform(platform, '.');
const destination = build.getPlatformArchivePath(platform);

View file

@ -39,7 +39,7 @@ describe('src/dev/build/tasks/nodejs/download_node_builds_task', () => {
const log = {};
const config = {
getPlatforms: () => platforms,
getTargetPlatforms: () => platforms,
getNodeVersion: () => 'nodeVersion',
};

View file

@ -45,7 +45,7 @@ describe('src/dev/build/tasks/node_extract_node_builds_task', () => {
};
const config = {
getPlatforms: () => [platform]
getTargetPlatforms: () => [platform]
};
await ExtractNodeBuildsTask.run(config);
@ -73,7 +73,7 @@ describe('src/dev/build/tasks/node_extract_node_builds_task', () => {
};
const config = {
getPlatforms: () => [platform]
getTargetPlatforms: () => [platform]
};
await ExtractNodeBuildsTask.run(config);

View file

@ -39,7 +39,7 @@ describe('src/dev/build/tasks/nodejs/verify_existing_node_builds_task', () => {
const log = { success: sinon.stub() };
const config = {
getPlatforms: () => platforms,
getTargetPlatforms: () => platforms,
getNodeVersion: () => 'nodeVersion',
};

View file

@ -24,7 +24,7 @@ export const CleanNodeBuildsTask = {
'Cleaning npm from node',
async run(config, log, build) {
for (const platform of config.getPlatforms()) {
for (const platform of config.getNodePlatforms()) {
await deleteAll(log, [
build.resolvePathForPlatform(platform, 'node/lib/node_modules'),
build.resolvePathForPlatform(platform, 'node/bin/npm'),

View file

@ -26,9 +26,8 @@ export const DownloadNodeBuildsTask = {
description: 'Downloading node.js builds for all platforms',
async run(config, log) {
const shasums = await getNodeShasums(config.getNodeVersion());
await Promise.all(
config.getPlatforms().map(async platform => {
config.getNodePlatforms().map(async platform => {
const { url, downloadPath, downloadName } = getNodeDownloadInfo(config, platform);
await download({
log,

View file

@ -27,7 +27,7 @@ export const ExtractNodeBuildsTask = {
description: 'Extracting node.js builds for all platforms',
async run(config) {
await Promise.all(
config.getPlatforms().map(async platform => {
config.getNodePlatforms().map(async platform => {
const { downloadPath, extractDir } = getNodeDownloadInfo(config, platform);
// windows executable is not extractable, it's just a .exe file

View file

@ -25,11 +25,10 @@ export const VerifyExistingNodeBuildsTask = {
global: true,
description: 'Verifying previously downloaded node.js build for all platforms',
async run(config, log) {
const platforms = config.getPlatforms();
const shasums = await getNodeShasums(config.getNodeVersion());
await Promise.all(
platforms.map(async (platform) => {
config.getNodePlatforms().map(async (platform) => {
const { downloadPath, downloadName } = getNodeDownloadInfo(config, platform);
const sha256 = await getFileHash(downloadPath, 'sha256');