UNPKG

@microsoft.azure/autorest.testserver

Version:

This project contains a set of OpenAPI definitions and a server implementing the corresponding API. Use this to test compliance of AutoRest generators.

128 lines (112 loc) 6.07 kB
const { createBlobService } = require("azure-storage"); const { readFileSync, readdirSync } = require('fs'); const { join } = require("path"); const { GitHubCiClient } = require("./github"); const commentIndicatorPublish = "<!--AUTO-GENERATED PUBLISH JOB COMMENT-->\n"; const commentIndicatorCoverage = "<!--AUTO-GENERATED TESTSERVER COVERAGE COMMENT-->\n"; async function collectCoverage() { // search for reports const coverageFolder = __dirname; const report = {}; const getMergedReport = (category) => { const reports = readdirSync(coverageFolder).filter(f => f.startsWith(`report-${category}`) && f.endsWith(".json")).map(f => require(join(coverageFolder, f))); const result = {}; for (const feature of [].concat.apply([], reports.map(r => Object.keys(r)))) { result[feature] = Math.max(...reports.map(r => r[feature] || 0)); } return result; }; report.General = getMergedReport("vanilla"); report.Azure = getMergedReport("azure"); if (Object.keys(report).every(cat => Object.keys(report[cat]).length === 0)) throw "no report"; // post report let comment = ""; for (const category of Object.keys(report)) { const categoryObject = report[category]; const features = Object.keys(categoryObject).sort().map(x => [x, categoryObject[x] > 0]); const countTotal = features.length; const countCovered = features.filter(x => x[1]).length; const countMissing = countTotal - countCovered; const percentCoverage = countCovered / (countTotal || 1) * 100 | 0; comment += `## ${percentCoverage === 100 ? "✔️" : "❌️"} ${category}: ${percentCoverage}%\n\n`; if (countMissing > 0) { comment += `<details><summary>${countMissing} out of ${countTotal} features are not covered by tests</summary><p>\n\n`; let first = true; for (const feature of features.filter(x => !x[1])) { if (!first) comment += `, `; first = false; const f = feature[0]; comment += `[\`${f}\`](https://github.com/Azure/autorest.testserver/search?q=${f})`; } comment += "</p></details>"; } else if (countTotal === 0) { comment += `no tests were run for this category\n`; } comment += "\n\n"; } const testServerVersion = require(join(coverageFolder, "..", "..", "package.json")).version; return `${commentIndicatorCoverage}# 🤖 AutoRest automatic feature coverage report 🤖\n*feature set version ${testServerVersion}*\n\n${comment}`; } function getPublishedPackageVersion() { return require(join(__dirname, "..", "..", "..", "..", "..", "package.json")).version; } async function pushCoverage(repo, ref, azStorageAccount, azStorageAccessKey, comment, version) { if (!version) { version = getPublishedPackageVersion(); } const blobSvc = createBlobService(azStorageAccount, azStorageAccessKey); const container = await new Promise((res, rej) => blobSvc.createContainerIfNotExists( `autorest-ci-coverage-report`, { publicAccessLevel: "blob" }, (error, result) => error ? rej(error) : res(result.name))); await new Promise((res, rej) => blobSvc.createBlockBlobFromText( container, `${repo.split('/')[1]}_${version}.md`, `<!-- ${ref} -->\n` + comment, { contentSettings: { contentType: "text/markdown; charset=utf-8" } }, (error, result) => error ? rej(error) : res(result.name))); } async function show(repo, pr, token) { const comment = await collectCoverage(); const ghClient = new GitHubCiClient(repo, token); // try cleaning up previous auto-comments try { const comments = await ghClient.getCommentsWithIndicator(pr, commentIndicatorCoverage); for (const comment of comments) await ghClient.tryDeleteComment(comment.id); } catch (_) { } // send comment await ghClient.createComment(pr, comment); } async function push(repo, pr, token, azStorageAccount, azStorageAccessKey, version) { const ghClient = new GitHubCiClient(repo, token); // try pushing coverage const coverageComment = (await ghClient.getCommentsWithIndicator(pr, commentIndicatorCoverage))[0]; if (coverageComment) await pushCoverage(repo, pr, azStorageAccount, azStorageAccessKey, coverageComment.message, version); } async function immediatePush(repo, ref, githubToken, azStorageAccount, azStorageAccessKey, version) { const postComment = githubToken && githubToken !== "skip"; if (postComment) { // try posting "published" comment on GitHub (IMPORTANT: this assumes that this script is only run after successful publish!) try { // try deriving PR associated with last commit const lastCommitMessage = require("child_process").execSync("git log -1 --pretty=%B").toString(); const pr = +(/\(\#(\d+)\)/g.exec(lastCommitMessage) || [])[1]; if (isNaN(pr)) throw `Could not deduce PR number from commit message ${JSON.stringify(lastCommitMessage)}`; if (!version) { version = getPublishedPackageVersion(); } const ghClient = new GitHubCiClient(repo, githubToken); await ghClient.createComment(pr, `${commentIndicatorPublish} # 🤖 AutoRest automatic publish job 🤖 ## success (version: ${version}) <!--IMPORTANT: this assumes that this script is only run after successful publish via VSTS! So no "Continue on error" on the publish task!-->`); } catch(e) { console.log("Posting 'published' comment to GitHub failed."); console.log(e); } } const comment = await collectCoverage(); await pushCoverage(repo, ref, azStorageAccount, azStorageAccessKey, comment, version); } module.exports = { show, push, immediatePush };