120 lines
3.3 KiB
JavaScript
120 lines
3.3 KiB
JavaScript
const { Octokit } = require("@octokit/core");
|
|
const { Command } = require("commander");
|
|
const { GraphQLClient } = require("graphql-request");
|
|
|
|
const program = new Command();
|
|
|
|
const repo = "saleor-cloud-deployments";
|
|
const owner = "saleor";
|
|
|
|
program
|
|
.name("Approve PR")
|
|
.description("Approve and merge PR if patch release")
|
|
.option("--version <version>", "version of a project")
|
|
.option("--pull_request_number <pull_request_number>", "Pull Request number")
|
|
.option("--auto_release <auto_release>", "is auto release")
|
|
.option("--dashboard_url <dashboard_url>", "Cypress dashboard url")
|
|
.action(async options => {
|
|
const octokit = new Octokit({
|
|
auth: process.env.GITHUB_TOKEN,
|
|
});
|
|
|
|
const pullNumber = options.pull_request_number;
|
|
|
|
const pullRequest = await octokit.request(
|
|
"GET /repos/{owner}/{repo}/pulls/{pull_number}",
|
|
{
|
|
owner,
|
|
repo,
|
|
pull_number: pullNumber,
|
|
},
|
|
);
|
|
|
|
const commitId = pullRequest.data.merge_commit_sha;
|
|
|
|
const testsStatus = await getTestsStatus(options.dashboard_url);
|
|
|
|
const requestBody =
|
|
testsStatus === "PASSED"
|
|
? `Cypress tests passed. See results at ${options.dashboard_url}`
|
|
: `Some tests failed, need manual approve. See results at ${options.dashboard_url}`;
|
|
const event = "COMMENT";
|
|
|
|
await octokit.request(
|
|
"POST /repos/{owner}/{repo}/pulls/{pull_number}/reviews",
|
|
{
|
|
owner,
|
|
repo,
|
|
pull_number: pullNumber,
|
|
commit_id: commitId,
|
|
body: requestBody,
|
|
event,
|
|
comments: [],
|
|
},
|
|
);
|
|
|
|
if (
|
|
options.auto_release &&
|
|
isPatchRelease(options.version) &&
|
|
testsStatus === "PASSED"
|
|
) {
|
|
await octokit.request(
|
|
"PUT /repos/{owner}/{repo}/pulls/{pull_number}/merge",
|
|
{
|
|
owner,
|
|
repo,
|
|
pull_number: pullNumber,
|
|
},
|
|
);
|
|
}
|
|
})
|
|
.parse();
|
|
|
|
function isPatchRelease(version) {
|
|
const regex = /\d+\.\d+\.[1-9]/;
|
|
return version.match(regex) ? true : false;
|
|
}
|
|
|
|
async function getTestsStatus(dashboardUrl) {
|
|
const getProjectRegex = /\/projects\/([^\/]*)/;
|
|
const getRunRegex = /\/runs\/([^\/]*)/;
|
|
|
|
const requestVariables = {
|
|
projectId: dashboardUrl.match(getProjectRegex)[1],
|
|
buildNumber: dashboardUrl.match(getRunRegex)[1],
|
|
};
|
|
|
|
const client = new GraphQLClient("https://dashboard.cypress.io/graphql");
|
|
|
|
const throwErrorAfterTimeout = setTimeout(function() {
|
|
throw new Error("Run have still running status, after all tests executed");
|
|
}, 1200000);
|
|
|
|
const status = await waitForTestsToFinish(client, requestVariables);
|
|
|
|
clearTimeout(throwErrorAfterTimeout);
|
|
return status;
|
|
}
|
|
|
|
async function waitForTestsToFinish(client, requestVariables) {
|
|
return new Promise((resolve, reject) => {
|
|
client
|
|
.request(
|
|
`query ($projectId: String!, $buildNumber: ID!) {
|
|
runByBuildNumber(buildNumber: $buildNumber, projectId: $projectId) {
|
|
status
|
|
}
|
|
}`,
|
|
requestVariables,
|
|
)
|
|
.then(response => {
|
|
if (response.runByBuildNumber.status === "RUNNING") {
|
|
setTimeout(async function() {
|
|
resolve(await waitForTestsToFinish(client, requestVariables));
|
|
}, 10000);
|
|
} else {
|
|
resolve(response.runByBuildNumber.status);
|
|
}
|
|
});
|
|
});
|
|
}
|