This commit is contained in:
Родитель
b8d70878e1
Коммит
27b78d5101
|
@ -1,93 +1,153 @@
|
|||
const akv = require('./keyvault');
|
||||
const spawnSync = require('child_process').spawnSync;
|
||||
const owner = 'sonic-net'
|
||||
const repo = 'sonic-buildimage'
|
||||
const { Octokit } = require('@octokit/rest');
|
||||
const akv = require('./keyvault');
|
||||
const fs = require('fs');
|
||||
const { stderr } = require('process');
|
||||
const InProgress = 'in_progress'
|
||||
const MsConflict = 'ms_conflict'
|
||||
var commentid = ''
|
||||
|
||||
function init(app) {
|
||||
app.log.info("Init conflict detect");
|
||||
|
||||
app.on(["pull_request.opened", "pull_request.synchronize", "pull_request.reopened", "issue_comment.created"], async (context) => {
|
||||
app.on( ["pull_request.opened", "pull_request.synchronize", "pull_request.reopened", "issue_comment.created"] , async (context) => {
|
||||
var payload = context.payload;
|
||||
var gh_token = await akv.getSecretFromCache("GH_TOKEN")
|
||||
var mssonic_token = await akv.getSecretFromCache("MSSONIC_TOKEN")
|
||||
var msazure_token = await akv.getSecretFromCache("MSAZURE_TOKEN")
|
||||
var conflict_script_url = await akv.getSecretFromCache("CONFLICT_SCRIPT_URL")
|
||||
var url, commit
|
||||
|
||||
console.log("conflict_detect.js ", payload.name, payload.action)
|
||||
if (payload.repository.name != repo){
|
||||
console.log("repo not match")
|
||||
let full_name = payload.repository.full_name
|
||||
let owner = full_name.split('/')[0]
|
||||
let repo = full_name.split('/')[1]
|
||||
// TODO: change to full_name != "sonic-net/sonic-buildimage"
|
||||
if ("sonic-buildimage" != repo) {
|
||||
app.log.info("repo not match!")
|
||||
return
|
||||
}
|
||||
if (payload.issue && payload.action == "created"){
|
||||
let issue_user_login = payload.issue.user.login;
|
||||
let comment_user_login = payload.comment.user.login;
|
||||
let comment_body = payload.comment.body.trim();
|
||||
if (comment_body.toLowerCase() != '/azpw ms_conflict'){
|
||||
if (payload.issue) {
|
||||
if ( commentid == payload.comment.id.toString() ) { return } else { commentid = payload.comment.id.toString() }
|
||||
app.log.info("conflict_detect " + "issue_comment.created " + payload.comment.user.login + " " + payload.comment.id.toString() + ' "' + payload.comment.body + '"')
|
||||
} else {
|
||||
if ( commentid == payload.number.toString() + payload.pull_request.updated_at.toString() ) { return } else { commentid == payload.number.toString() + payload.pull_request.updated_at.toString() }
|
||||
app.log.info("conflict_detect " + "pull_request." + payload.action + " " + payload.pull_request.user.login + " " + payload.pull_request.html_url)
|
||||
}
|
||||
|
||||
var url, number, commit, base_branch, pr_owner
|
||||
let gh_token = await akv.getSecretFromCache("GH_TOKEN")
|
||||
let script_url = await akv.getSecretFromCache("CONFLICT_SCRIPT_URL")
|
||||
let msazure_token = await akv.getSecretFromCache("MSAZURE_TOKEN")
|
||||
|
||||
if (payload.issue && payload.action == "created") {
|
||||
// issue_comment.created
|
||||
let comment_body = payload.comment.body.trim()
|
||||
if (comment_body.toLowerCase() != '/azpw ' + MsConflict) {
|
||||
return
|
||||
}
|
||||
if (! payload.issue.pull_request){
|
||||
if (!payload.issue.pull_request) {
|
||||
return
|
||||
}
|
||||
url = payload.issue.html_url.toString();
|
||||
let number = url.split('/').slice(-1)[0]
|
||||
url = payload.issue.html_url
|
||||
number = payload.issue.number.toString()
|
||||
let pr = await context.octokit.rest.pulls.get({
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
pull_number: number,
|
||||
});
|
||||
commit = pr.data.head.sha
|
||||
base_branch = pr.data.base.ref
|
||||
pr_owner = pr.data.head.user.login
|
||||
} else {
|
||||
// pull_request.opened/synchronize/reopend
|
||||
url = payload.pull_request.html_url
|
||||
number = payload.number.toString()
|
||||
commit = payload.pull_request.head.sha
|
||||
base_branch = payload.pull_request.base.ref
|
||||
pr_owner = payload.pull_request.user.login
|
||||
}
|
||||
console.log(url)
|
||||
app.log.info([url, number, commit, base_branch, pr_owner].join(" "))
|
||||
|
||||
await context.octokit.rest.checks.create({
|
||||
context.octokit.rest.checks.create({
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
head_sha: commit,
|
||||
name: 'ms_conflict',
|
||||
status: 'in_progress',
|
||||
name: MsConflict,
|
||||
status: InProgress,
|
||||
});
|
||||
// If it belongs to ms, comment on PR.
|
||||
var result = 'failure'
|
||||
let run = spawnSync('bash', ['-c', ['./conflict_detect.sh', repo, url, gh_token, msazure_token, script_url, pr_owner, number, base_branch].join(" ") ], { encoding: 'utf-8' })
|
||||
if (run.status == 254) {
|
||||
app.log.info("Conflict detected! PR is not completed.")
|
||||
} else if (run.status != 0){
|
||||
app.log.error("=============================")
|
||||
app.log.error(run.stderr)
|
||||
app.log.error(run.stdout)
|
||||
app.log.error("-----------------------------")
|
||||
} else {
|
||||
app.log.info("No Conflict.")
|
||||
result = 'success'
|
||||
}
|
||||
);
|
||||
console.log(url, gh_token, mssonic_token, msazure_token, conflict_script_url)
|
||||
var result = 'success'
|
||||
try {
|
||||
run = spawnSync('bash', ['./conflict_detect.sh', url, gh_token, mssonic_token, msazure_token, conflict_script_url], { encoding: 'utf-8' })
|
||||
console.log(run)
|
||||
if ( run.status != 0 ) {
|
||||
result = 'failure'
|
||||
if ( run.status != 254) { console.log(run.status,run) };
|
||||
|
||||
let description = '', comment_at = '', mspr = ''
|
||||
if (run.status == 254 || run.status == 253 || run.status == 252){
|
||||
for (const line of run.stdout.split(/\r?\n/)){
|
||||
if (line.startsWith("pr_owner: ")){
|
||||
comment_at = line.replace("pr_owner: ", "")
|
||||
}
|
||||
if (line.startsWith("ms_pr: ")){
|
||||
mspr = line.replace("ms_pr: ", "")
|
||||
}
|
||||
if (line.startsWith("ms_pr_new: ")){
|
||||
mspr = line.replace("ms_pr_new: ", "")
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
return
|
||||
}
|
||||
|
||||
url = ''
|
||||
for ( const element of run.output[1].split(/\r?\n|\r|\n/g) ) {
|
||||
if ( element.startsWith('https://dev.azure') ) {
|
||||
url = element
|
||||
break
|
||||
if (comment_at == '' || mspr == ''){
|
||||
app.log.error("Error output by conflict_detect.sh")
|
||||
}
|
||||
description = `@${comment_at} PR: ${url} is conflict with MS internal repo<br>Please complete the following PR by pushing fix commit to sonicbld/conflict_prefix/${number}-fix<br>${mspr}<br>Then comment "/azpw ms_conflict" to rerun PR checker.`
|
||||
let mssonicbld_ghclient = new Octokit({
|
||||
auth: gh_token,
|
||||
});
|
||||
let now = new Date()
|
||||
now.setDate(now.getDate() -1)
|
||||
let comments = await mssonicbld_ghclient.rest.issues.listComments({
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
issue_number: number,
|
||||
since : now.toISOString(),
|
||||
per_page: 100,
|
||||
});
|
||||
let need_comment = true
|
||||
if ( Object.values(comments.data).length > 0){
|
||||
for (const comment of Object.values(comments.data)) {
|
||||
if ( comment.body == description ) {
|
||||
need_comment = false
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (need_comment) {
|
||||
mssonicbld_ghclient.rest.issues.createComment({
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
issue_number: number,
|
||||
body: description,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var check = await context.octokit.rest.checks.create({
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
head_sha: commit,
|
||||
name: 'ms_conflict',
|
||||
conclusion: result,
|
||||
status: 'completed',
|
||||
output: {
|
||||
title: "ms code conflict",
|
||||
summary: "conflict details:\n" + url + "\nPlease resolve conflict in the PR by pushing to PRID-fix branch.\nThen comment on PR: /azpw ms_conflict"
|
||||
}
|
||||
}
|
||||
);
|
||||
if ( check.status != 201 && check.status != 202 ) { console.log(check) }
|
||||
});
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
head_sha: commit,
|
||||
name: MsConflict,
|
||||
conclusion: result,
|
||||
status: 'completed',
|
||||
output: {
|
||||
title: "ms code conflict",
|
||||
summary: description,
|
||||
},
|
||||
});
|
||||
if (check.status != 201 && check.status != 202 && check.status != 200) { app.log.error(check) }
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = Object.freeze({
|
||||
|
|
|
@ -1,21 +1,34 @@
|
|||
set -ex
|
||||
|
||||
URL=$1
|
||||
GH_TOKEN=$2
|
||||
MSSONIC_TOKEN=$3
|
||||
MSAZURE_TOKEN=$4
|
||||
SCRIPT_URL=$5
|
||||
#!/bin/bash
|
||||
|
||||
REPO=$1
|
||||
mkdir -p workspace
|
||||
cd workspace
|
||||
rm -rf $(find . -name "tmp.*" -type d -cmin +10)
|
||||
|
||||
rm -rf $(find . -name "tmp.*" -type d -cmin +30)
|
||||
mkdir $REPO -p
|
||||
cd $REPO
|
||||
tmp=$(mktemp -p ./ -d)
|
||||
cd $tmp
|
||||
|
||||
curl "https://mssonicbld:$GH_TOKEN@$SCRIPT_URL" -o ms_conflict_detect.sh
|
||||
wc -l ms_conflict_detect.sh
|
||||
echo "tmp dir: $tmp"
|
||||
|
||||
bash ms_conflict_detect.sh $MSAZURE_TOKEN $MSSONIC_TOKEN $GH_TOKEN $URL
|
||||
cd ..
|
||||
cat > .bashenv << EOF
|
||||
URL=$2
|
||||
GH_TOKEN=$3
|
||||
MSAZURE_TOKEN=$4
|
||||
SCRIPT_URL=$5
|
||||
PR_OWNER=$6
|
||||
PR_ID=$7
|
||||
BASE_BRANCH=$8
|
||||
EOF
|
||||
|
||||
. .bashenv
|
||||
|
||||
curl "https://mssonicbld:$GH_TOKEN@$SCRIPT_URL/ms_conflict_detect.sh" -o ms_conflict_detect.sh -L
|
||||
curl "https://mssonicbld:$GH_TOKEN@$SCRIPT_URL/azdevops_git_api.sh" -o azdevops_git_api.sh -L
|
||||
bash ms_conflict_detect.sh
|
||||
rc=$?
|
||||
|
||||
cd ../
|
||||
rm -rf $tmp
|
||||
exit $rc
|
||||
|
|
|
@ -12,9 +12,9 @@ module.exports = (app) => {
|
|||
// Your code here
|
||||
app.log.info("Yay, the app was loaded!");
|
||||
|
||||
issue_comment.init(app);
|
||||
// issue_comment.init(app);
|
||||
check_run.init(app);
|
||||
eventhub.init(app);
|
||||
// eventhub.init(app);
|
||||
conflict_detect.init(app);
|
||||
|
||||
// For more information on building apps:
|
||||
|
|
|
@ -19,8 +19,8 @@ function init(app) {
|
|||
comment_body = payload.comment.body.trim();
|
||||
command = null;
|
||||
|
||||
console.log(`issue_comment.created, ${payload.comment.id}`);
|
||||
if (comment_body.toLowerCase().startsWith('/azpw ms_conflict') ){ return };
|
||||
console.log(`issue_comment.created, ${payload.comment.id}`);
|
||||
if (isDevEnv){
|
||||
if (comment_body.toLowerCase().startsWith('/azpwd comment')){
|
||||
await context.octokit.rest.issues.createComment({
|
||||
|
|
|
@ -31,7 +31,8 @@ async function getSecretFromCache(secretName){
|
|||
|
||||
async function getAppPrivateKey()
|
||||
{
|
||||
return await getSecretFromCache("PRIVATE_KEY");
|
||||
// TODO
|
||||
return await getSecretFromCache("PRIVATE_KEY1");
|
||||
}
|
||||
|
||||
async function getAppWebhookSecret()
|
||||
|
|
|
@ -5,6 +5,7 @@ const akv = require('./keyvault.js');
|
|||
async function startServer() {
|
||||
var privateKey = await akv.getAppPrivateKey();
|
||||
var secret = await akv.getAppWebhookSecret();
|
||||
secret = "default";
|
||||
|
||||
const server = new Server({
|
||||
Probot: Probot.defaults({
|
||||
|
|
Загрузка…
Ссылка в новой задаче