Skip to content

Commit

Permalink
[Travis-CI] Run breaking change tool in the CI (#1456)
Browse files Browse the repository at this point in the history
* Run breaking change tool in the CI
getFilesChangedInPR should not return package.json

* Update two swagger to test in CI

* Revert "Update two swagger to test in CI"

This reverts commit e2db85c.

* Addressing code review comments

* Revert "Revert "Update two swagger to test in CI""

This reverts commit c1fb793.

* Path that contains specification word

* Incorporating code review comments

* Revert "Revert "Revert "Update two swagger to test in CI"""

This reverts commit 95aed00.

* Typo fixed
Adding some differentiator for CI output
  • Loading branch information
vishrutshah authored Aug 1, 2017
1 parent 968030d commit 521c0e6
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 3 deletions.
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ env:
- MODE=linter PR_ONLY=true
- MODE=semantic PR_ONLY=true
- MODE=model PR_ONLY=true
- MODE=BreakingChange PR_ONLY=true
- MODE=azurebot PR_ONLY=true
global:
secure: n7Ptb5x7Zdq/7na2L68JlrRPbl/xWtiFQncO7fsrSVuVGI4Mhjj1LD2k07qWAdFPM1PaZYvCRWc3YwbXr1NTOOn485r6qcLUjpN9TICP0ErGcEA9SzctipfbFP1IV4aCh23WSaopMueBki52KfskaGcZ2ox9pvI2LCysCp7q4WwF/0vArLYf48FeZuscWHVaLsU4z8ZMFPT9yHg+RQoqPeBnaR/ZGtG96NZolT+VAlP445geb0qn8wWAuSl4bR1JQV2eA3MwdWu/iVkepBeKTN7d81l3yjWzTvFtP/JRJClWBNQbOMjAed3/2Tr2lGgyRUM6Uwp4KvfRmbX3Xrlggen1AO/YAb2mJDs+HARPnhZXIOtDjgft/ethVeLTTBUsbNFGUN2lcrJMw9dkFi+ai3XefatENJbULqWx8Xb+wMD1b0TrI6sZZpdC8vYHnM/DoqiEh5+h3okkSmQcjPF4K9js294G790PKf4u2CQdur41qh4Ze4IzbvulVsGMON+O93vA6ZRK1sTHC5VUTs2iMhCnf6LtMN59kBq1T2MJ8ndXRpGlFEn2wDTjJSpSr0k0sjoG5i+bIFhbqVF8xegBb/PH4H9/i1ifIypNNp0FGdz4o2cFsYrcUKFsx1C/kFJ6rC809r0odDt32hGSOkOCziTwFHusbR5Nwf0RjOWSgvc=
Expand All @@ -27,6 +28,7 @@ matrix:
- env: MODE=linter PR_ONLY=true
- env: MODE=semantic PR_ONLY=true
- env: MODE=model PR_ONLY=true
- env: MODE=BreakingChange PR_ONLY=true
- env: MODE=azurebot PR_ONLY=true
before_install:
- docker pull lmazuel/swagger-to-sdk
Expand All @@ -47,4 +49,5 @@ script:
- if [[ $MODE == 'linter' ]]; then npm test -- test/linter.js; fi
- if [[ $MODE == 'semantic' ]]; then npm test -- test/semantic.js; fi
- if [[ $MODE == 'model' ]]; then npm test -- test/model.js; fi
- if [[ $MODE == 'BreakingChange' ]]; then node -- scripts/breaking-change.js; fi
- if [[ $MODE == 'azurebot' ]]; then node scripts/momentOfTruth.js; fi
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
"z-schema": "^3.16.1",
"oav": "^0.4.1",
"js-yaml": "^3.8.2",
"azure-storage": "^2.1.0"
"azure-storage": "^2.1.0",
"oad": "^0.1.6"
},
"homepage": "https://github.com/azure/azure-rest-api-specs",
"repository": {
Expand All @@ -31,4 +32,4 @@
"scripts": {
"test": "mocha -t 500000"
}
}
}
117 changes: 117 additions & 0 deletions scripts/breaking-change.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License in the project root for license information.

'use strict';
var utils = require('../test/util/utils'),
path = require('path'),
fs = require('fs'),
os = require('os'),
exec = require('child_process').exec,
execSync = require('child_process').execSync,
oad = require('oad');

// This map is used to store the mapping between files resolved and stored location
var resolvedMapForNewSpecs = {};
let outputFolder = path.join(os.tmpdir(), "resolved");
// Used to enable running script outside TravisCI for debugging
let isRunningInTraviCI = process.env.MODE === 'BreakingChange' && process.env.PR_ONLY === 'true';

/**
* Compares old and new specifications for breaking change detection.
*
* @param {string} oldSpec Path to the old swagger specification file.
*
* @param {string} newSpec Path to the new swagger specification file.
*/
function runOad(oldSpec, newSpec) {
if (oldSpec === null || oldSpec === undefined || typeof oldSpec.valueOf() !== 'string' || !oldSpec.trim().length) {
return Promise.reject(new Error('oldSpec is a required parameter of type "string" and it cannot be an empty string.'));
}

if (newSpec === null || newSpec === undefined || typeof newSpec.valueOf() !== 'string' || !newSpec.trim().length) {
return Promise.reject(new Error('newSpec is a required parameter of type "string" and it cannot be an empty string.'));
}

console.log(`>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`);
console.log(`Old Spec: "${oldSpec}"`);
console.log(`New Spec: "${newSpec}"`);
console.log(`>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`);

return Promise.resolve(oad.compare(oldSpec, newSpec, { consoleLogLevel: 'warn', json: true }));
}

/**
* Processes the given swagger and stores the resolved swagger on to disk
*
* @param {string} swaggerPath Path to the swagger specification file.
*/
function processViaAutoRest(swaggerPath) {
if (swaggerPath === null || swaggerPath === undefined || typeof swaggerPath.valueOf() !== 'string' || !swaggerPath.trim().length) {
return Promise.reject(new Error('swaggerPath is a required parameter of type "string" and it cannot be an empty string.'));
}

console.log(`Processing via AutoRest...`);

let outputFileNameWithExt = path.basename(swaggerPath);
let outputFileNameWithoutExt = path.basename(swaggerPath, '.json');
let autoRestCmd = `autorest --input-file=${swaggerPath} --output-artifact=swagger-document.json --output-file=${outputFileNameWithoutExt} --output-folder=${outputFolder}`;

console.log(`Executing : ${autoRestCmd}`);

try {
let result = execSync(`${autoRestCmd}`, { encoding: 'utf8', maxBuffer: 1024 * 1024 * 64 });
resolvedMapForNewSpecs[outputFileNameWithExt] = path.join(outputFolder, outputFileNameWithExt);
} catch (err) {
// Do not update map in case of errors
}

return Promise.resolve();
}

//main function
async function runScript() {
// See whether script is in Travis CI context
console.log(`isRunningInTraviCI: ${isRunningInTraviCI}`);

// Create directory to store the processed & resolved swaggers
if (!fs.existsSync(outputFolder)) {
fs.mkdirSync(outputFolder);
}

let swaggersToProcess = utils.getFilesChangedInPR();

// For debugging in your repo, please uncomment following section and update swaggersToProcess array for the desired swaggers
// if (!isRunningInTraviCI) {
// swaggersToProcess = [ '/Users/vishrut/git-repos/azure-rest-api-specs/specification/storage/resource-manager/Microsoft.Storage/2017-06-01/storage.json',
// '/Users/vishrut/git-repos/azure-rest-api-specs/specification/network/resource-manager/Microsoft.Network/2017-06-01/applicationGateway.json' ];
// }
console.log(swaggersToProcess);

for (const swagger of swaggersToProcess) {
await processViaAutoRest(swagger);
}

if (isRunningInTraviCI) {
utils.checkoutTargetBranch();
}

console.log(`Resolved map for the new specification is:`);
console.dir(resolvedMapForNewSpecs);

for (const swagger of swaggersToProcess) {
let outputFileNameWithExt = path.basename(swagger);

console.log(outputFileNameWithExt);
if (resolvedMapForNewSpecs[outputFileNameWithExt]) {
await runOad(swagger, resolvedMapForNewSpecs[outputFileNameWithExt]);
}
}
}

// magic starts here
runScript().then(success => {
process.exit(0);
}).catch(err => {
console.log(err);
process.exit(1);
})
16 changes: 15 additions & 1 deletion test/util/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,20 @@ exports.getTargetBranch = function getTargetBranch() {
return result;
};

/**
* Checkout the targetBranch
*/
exports.checkoutTargetBranch = function checkoutTargetBranch() {
let targetBranch = exports.getTargetBranch();

console.log(`Changing the branch to ${targetBranch}...`);
execSync(`git remote -vv`, { encoding: 'utf8' });
execSync(`git branch --all`, { encoding: 'utf8' });
execSync(`git fetch origin ${targetBranch}`, { encoding: 'utf8' });
execSync(`git checkout ${targetBranch}`, { encoding: 'utf8' });
execSync(`git log -3`, { encoding: 'utf8' });
}

/**
* Gets the name of the source branch from which the PR is sent.
* @returns {string} branchName The source branch name.
Expand Down Expand Up @@ -203,7 +217,7 @@ exports.getFilesChangedInPR = function getFilesChangedInPR() {
console.log('>>>>> Files changed in this PR are as follows:')
console.log(filesChanged);
swaggerFilesInPR = filesChanged.split('\n').filter(function (item) {
if (item.match(/.*json$/ig) == null) {
if (item.match(/.*json$/ig) == null || item.match(/.*specification.*/ig) == null) {
return false;
}
if (item.match(/.*\/examples\/*/ig) !== null) {
Expand Down

0 comments on commit 521c0e6

Please sign in to comment.