This commit is contained in:
Sonic Build Admin 2023-10-31 19:57:57 +08:00
Родитель b8d70878e1
Коммит 27b78d5101
6 изменённых файлов: 148 добавлений и 73 удалений

Просмотреть файл

@ -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({