Skip to content

Commit

Permalink
Backport scripts needed by latest workflows (#2192)
Browse files Browse the repository at this point in the history
  • Loading branch information
prprabhu-ms committed Aug 10, 2022
1 parent 040fb2c commit 011c39c
Show file tree
Hide file tree
Showing 8 changed files with 218 additions and 1 deletion.
3 changes: 2 additions & 1 deletion common/scripts/babel-conditional-preprocess.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ function Handle(path, featureSet, stabilizedFeatureSet, relaceWith=undefined) {
if (!node.leadingComments) {
return;
}

const removalInstructions = node.leadingComments.map((comment) => nodeRemovalInstruction(node, comment, featureSet, stabilizedFeatureSet));
if (!shouldRemoveNode(removalInstructions)) {
return;
Expand Down Expand Up @@ -196,4 +197,4 @@ function shouldRemoveNode(instructions) {
return false;
}
return instructions.includes('remove');
}
}
66 changes: 66 additions & 0 deletions common/scripts/force-build-flavor.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/usr/bin/env node
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import { REPO_ROOT } from './lib/index.mjs';
import {updateAllDepVersions} from './package-utils.js';
import { readFileSync, writeFileSync } from 'fs';
import path from 'path';

const MATRIX_JSON = path.join(REPO_ROOT, 'common', 'config', 'workflows', 'matrix.json');

/**
* This script forces the build target and dependencies to be restricted to the provided flavor.
*
* The script is used by release automation -- release branches only build a specific build flavor
* based on the type of the release.
*
* See also `common/scripts/workflow-read-matrix.mjs`.
*/
function main(args) {
const target = args[2]
if (target !== 'stable' && target !== 'beta') {
throw new Error(`Usage: ${args[1]} ['stable' | 'beta']\n`);
}

restrictBuildFlavorForWorkflows(target);
chooseSdkDep(target);
}

function restrictBuildFlavorForWorkflows(target) {
const text = readFileSync(MATRIX_JSON, 'utf8');
const data = JSON.parse(text);
data.include = data.include.filter((include) => include.flavor === target);
writeFileSync(MATRIX_JSON, JSON.stringify(data, null, 2), 'utf8');
}

const SDK_DEPS = ["@azure/communication-calling", "@azure/communication-chat"]

function chooseSdkDep(target) {
const action = target === 'stable' ? chooseStableVersion : chooseBetaVersion;
updateAllDepVersions(action, SDK_DEPS);
}

const chooseStableVersion = (semver) => {
const versions = semver.split('||').map(version => version.trim());
if(versions.length === 1) {
return semver;
}
for(const version of versions) {
if(!version.includes('beta') && !version.includes('alpha')) return version;
}
throw 'can\'t find the right version for stable!';
}

const chooseBetaVersion = (semver) => {
const versions = semver.split('||').map(version => version.trim());
if(versions.length === 1) {
return semver;
}
for(const version of versions) {
if(version.includes('beta')) return version;
}
throw 'can\'t find the right version for beta!';
}

main(process.argv);
10 changes: 10 additions & 0 deletions common/scripts/lib/constants.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import path from 'path';
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

export const REPO_ROOT = path.join(__dirname, '..', '..', '..');
30 changes: 30 additions & 0 deletions common/scripts/lib/exec.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import child_process from 'child_process';

/**
* Execute a command by shelling out.
*
* @param cmd: string - command to run.
* @param env: Optional environment variables for the child process. By default, process.env is forwarded.
*
* - stdout, stderr are piped to the current process' stdout and stderr respectively.
* - the returned Promise is rejected if the child process exits with a non-zero exit code.
*/
export async function exec(cmd, env) {
console.log(`Running ${cmd}`);
// Inheriting the stdio (and implied stderr and stdin) ensures that colorized output is preserved.
const child = child_process.spawn(cmd, { env: env, shell: true, stdio: 'inherit' });
return new Promise((resolve, reject) => {
child.on('exit', (code) => {
if (code != 0) {
reject(`Child exited with non-zero code: ${code}`);
}
resolve();
});
child.on('error', (err) => {
reject(`Child failed to start: ${err}`);
});
});
}
26 changes: 26 additions & 0 deletions common/scripts/lib/getBuildFlavor.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import path from 'path';
import { readFileSync } from 'fs';
import { REPO_ROOT } from './constants.mjs';

const ENV_FILE = path.join(REPO_ROOT, 'common', 'config', 'env', '.env');
const ENV_PREFIX = 'COMMUNICATION_REACT_FLAVOR=';

/**
* Get the current build flavor.
*
* Parses the relevant environment file and returns the build flavor as string.
*
* @return 'stable' | 'beta'
*/
export function getBuildFlavor() {
const data = readFileSync(ENV_FILE, 'utf8');
for (const line of data.split(/\r\n|\r|\n/)) {
if (line.startsWith(ENV_PREFIX)) {
return line.substring(ENV_PREFIX.length).trim()
}
}
throw new Error(`Malformed build flavor: ${data}`);
}
6 changes: 6 additions & 0 deletions common/scripts/lib/index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

export * from './constants.mjs';
export * from './exec.mjs';
export * from './getBuildFlavor.mjs';
55 changes: 55 additions & 0 deletions common/scripts/poll-npm-package-published.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { get } from "https";
import process from "process";

/**
* Script that polls the npm registry to see if a @azure/communication-react package version published.
* By default, it polls on short intervals (5 seconds) and timesout after a longer interval (5 minutes).
*
* @params {string} version - the version to check for
*
* @example node ./poll-npm-package-published.js 1.3.0
*/

const POLL_INTERVAL_MS = 5000; // 5 seconds in millis
const TIMEOUT_TIME_MS = 5 * 60 * 1000; // 5 minutes in millis
const GET_REQUEST_TIMEOUT_MS = 5000;

const GET_REQUEST_OPTIONS = {
hostname: 'registry.npmjs.org',
timeout: GET_REQUEST_TIMEOUT_MS
}

const checkNpm = (packageName, packageVersion) => {
return new Promise((resolve, reject) => {
const request = get({...GET_REQUEST_OPTIONS, path: `/${packageName}/${packageVersion}`}, (response) => {
resolve(response);
});
console.log(`Pinging: https://${GET_REQUEST_OPTIONS.hostname}/${packageName}/${packageVersion}`);
request.end();
});
}

const sleep = (ms) => new Promise(res => setTimeout(res, ms));

const main = async () => {
const packageVersion = process.argv[2];
const packageName = `@azure/communication-react`
const startTime = new Date();
while(true) {
const response = await checkNpm(packageName, packageVersion);
console.log('responseCode: ', response.statusCode);

if (response.statusCode === 200) {
console.log("Successfully found npm package")
process.exitCode = 0;
return;
} else if ((new Date() - startTime) > TIMEOUT_TIME_MS) {
throw new Error('Failed to find package on the npm registry');
} else {
console.log('Sleeping for a bit...');
await sleep(POLL_INTERVAL_MS);
}
}
};

await main();
23 changes: 23 additions & 0 deletions common/scripts/workflow-read-matrix.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env node
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

/**
* This script is used by GitHub workflows to parse and marshal the build matrix
* to be tested.
*
* On the `main` branch, all build flavors are tested.
* On release branches, the build matrix is restricted to the relevant flavor.
*
* See also `common/scripts/force-build-flavor.mjs`.
*/

import { REPO_ROOT } from './lib/index.mjs';
import { readFileSync } from 'fs';
import path from 'path';

const MATRIX_JSON = path.join(REPO_ROOT, 'common', 'config', 'workflows', 'matrix.json');

const text = readFileSync(MATRIX_JSON, 'utf8');
const denseText = JSON.stringify(JSON.parse(text), null, 0);
console.log(denseText);

0 comments on commit 011c39c

Please sign in to comment.