From 5897b9588b1f804deb5f20894e837a3cd0f85b2c Mon Sep 17 00:00:00 2001 From: Gustavo Monteiro Date: Thu, 26 Jan 2023 09:25:06 -0300 Subject: [PATCH 1/7] feat: get diff from conflicted branchs 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.0.10 1.0.11 1.0.12 fix: call conflictDetails func with correct params 1.0.13 feat: log sync check-runs responses 1.0.14 --- package-lock.json | 4 ++-- package.json | 2 +- src/helper.js | 38 +++++++++++++++++++++++++++++++++++--- src/index.js | 9 +++++++-- 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index c2ed6cc..8e93224 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "gitmerge-action", - "version": "1.0.2", + "version": "1.0.14", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "gitmerge-action", - "version": "1.0.2", + "version": "1.0.14", "license": "ISC", "dependencies": { "@actions/core": "^1.10.0", diff --git a/package.json b/package.json index b96dbc3..1aba942 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gitmerge-action", - "version": "1.0.2", + "version": "1.0.14", "description": "Native Github action to make merge and deploy from repo", "main": "index.js", "scripts": { diff --git a/src/helper.js b/src/helper.js index e9d4e2f..d9ffa49 100644 --- a/src/helper.js +++ b/src/helper.js @@ -1,6 +1,6 @@ const github = require('@actions/github') -const { deployRefHead, deployRefName, repoInfo, token, target, ref } = require('./constants') +const { deployRefHead, deployRefName, repoInfo, token, target, ref, deployBranchName } = require('./constants') const octokit = github.getOctokit(token) const timestamp = new Date().getTime() @@ -54,9 +54,22 @@ async function getPrs() { base: target, }) - const prs = data.filter(pr => !pr.draft) - console.log(`Loading ${prs.length} PRs`) + const prs = data.filter(async(pr) => { + return !pr.draft + }) + const promises = prs.map(async(pr) => { + const conclusions = await octokit.request('GET /repos/{owner}/{repo}/commits/{ref}/check-runs', { + ...repoInfo, + ref: pr.head.ref + }) + return conclusions.data + }) + + const responses = await Promise.all(promises) + console.log(responses) + + console.log(`Loading ${prs.length} PRs`) return prs } @@ -75,10 +88,29 @@ async function createBranch(branchName, commitSha) { }) } +async function conflictDetails(head) { + const base = `${deployBranchName}-${timestamp}` + const res = await octokit.request('GET /repos/{owner}/{repo}/compare/{basehead}{?page,per_page}', { + ...repoInfo, + basehead: `${base}...${head}`, + mediaType: { + format: 'vnd.github.merge-info-preview' + } + }) + const { data: { html_url, permalink_url, diff_url, patch_url } } = res + console.log(`Para conferir detalhes do conflito veja os links: + html_url: ${html_url}, + permalink_url: ${permalink_url}, + diff_url: ${diff_url}, + patch_url: ${patch_url}, + `); +} + module.exports = { recreateDeployBranch, getLastCommitSha, + conflictDetails, createAuxBranch, deleteBranch, mergeBranchs, diff --git a/src/index.js b/src/index.js index 51d1b3d..f20c022 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,4 @@ -const { getLastCommitSha, createAuxBranch, deleteBranch, getPrs, mergeBranchs, recreateDeployBranch } = require('./helper') +const { getLastCommitSha, createAuxBranch, deleteBranch, getPrs, mergeBranchs, recreateDeployBranch, conflictDetails } = require('./helper') async function run() { const baseLastCommit = await getLastCommitSha() @@ -7,10 +7,13 @@ async function run() { const pullRequests = await getPrs() + let lastBranchToMerge try { let lastMergeCommitSha for (let pull of pullRequests) { console.log(`Merging PR ${pull.number}`) + lastBranchToMerge = pull.head.ref + const { data } = await mergeBranchs(pull.head.ref) console.log(`Successful merge PR ${pull.number}`); @@ -18,8 +21,10 @@ async function run() { lastMergeCommitSha = data.sha } await recreateDeployBranch(lastMergeCommitSha) + } catch(error) { + await conflictDetails(lastBranchToMerge) } finally { - await deleteBranch(workBranchName) + // await deleteBranch(workBranchName) } } From 7ab4850ed2f2da201abaa3ac43220f1492aa0ca6 Mon Sep 17 00:00:00 2001 From: Gustavo Monteiro Date: Mon, 30 Jan 2023 13:34:14 -0300 Subject: [PATCH 2/7] feat: filter prs by check runs 1.0.15 feat: improving logs 1.0.16 --- package-lock.json | 4 ++-- package.json | 2 +- src/helper.js | 23 +++++++++++++++++------ 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8e93224..6f2858e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "gitmerge-action", - "version": "1.0.14", + "version": "1.0.16", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "gitmerge-action", - "version": "1.0.14", + "version": "1.0.16", "license": "ISC", "dependencies": { "@actions/core": "^1.10.0", diff --git a/package.json b/package.json index 1aba942..c7a2b16 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gitmerge-action", - "version": "1.0.14", + "version": "1.0.16", "description": "Native Github action to make merge and deploy from repo", "main": "index.js", "scripts": { diff --git a/src/helper.js b/src/helper.js index d9ffa49..5003fbc 100644 --- a/src/helper.js +++ b/src/helper.js @@ -54,20 +54,31 @@ async function getPrs() { base: target, }) - const prs = data.filter(async(pr) => { - return !pr.draft - }) + let prs = data.filter(pr => !pr.draft) const promises = prs.map(async(pr) => { const conclusions = await octokit.request('GET /repos/{owner}/{repo}/commits/{ref}/check-runs', { ...repoInfo, - ref: pr.head.ref + ref: pr.head.ref, }) - return conclusions.data + return { + checks: conclusions.data, + pr + } }) const responses = await Promise.all(promises) - console.log(responses) + prs = responses.map(res => { + const hasFailureChecks = res.checks.check_runs.filter(check => { + return ['action_required', 'failure'].includes(check.conclusion) + }).length > 0 + + if (hasFailureChecks) { + console.log(`PR ${res.pr.number} because it has failing checks`); + return null + } + return res.pr + }).filter( pr => pr) console.log(`Loading ${prs.length} PRs`) return prs From c1d0863696bd412b1c9b312f3c95799ed26768c9 Mon Sep 17 00:00:00 2001 From: Gustavo Monteiro Date: Mon, 30 Jan 2023 13:51:04 -0300 Subject: [PATCH 3/7] feat: improve logs 1.0.17 feat: log mergeable status 1.0.18 --- package-lock.json | 4 ++-- package.json | 2 +- src/helper.js | 20 +++++++++++++++++--- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6f2858e..fd3c684 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "gitmerge-action", - "version": "1.0.16", + "version": "1.0.18", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "gitmerge-action", - "version": "1.0.16", + "version": "1.0.18", "license": "ISC", "dependencies": { "@actions/core": "^1.10.0", diff --git a/package.json b/package.json index c7a2b16..e434218 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gitmerge-action", - "version": "1.0.16", + "version": "1.0.18", "description": "Native Github action to make merge and deploy from repo", "main": "index.js", "scripts": { diff --git a/src/helper.js b/src/helper.js index 5003fbc..5d4588b 100644 --- a/src/helper.js +++ b/src/helper.js @@ -15,8 +15,7 @@ async function getLastCommitSha() { ref: ref }) - console.log(`Successful get commit. - Commit message: ${data.commit.message}`); + console.log(`Successful get commit with message: ${data.commit.message}`); return data.sha } @@ -55,6 +54,20 @@ async function getPrs() { }) let prs = data.filter(pr => !pr.draft) + + const merges = prs.map(async(pr) => { + const res = await octokit.request('GET /repos/{owner}/{repo}/pulls/{pull_number}', { + ...repoInfo, + pull_number: pr.number + }) + + console.log( { + pr: pr.number, + mergeable: res.data.mergeable + }) + }) + + await Promise.all(merges) const promises = prs.map(async(pr) => { const conclusions = await octokit.request('GET /repos/{owner}/{repo}/commits/{ref}/check-runs', { @@ -68,13 +81,14 @@ async function getPrs() { }) const responses = await Promise.all(promises) + prs = responses.map(res => { const hasFailureChecks = res.checks.check_runs.filter(check => { return ['action_required', 'failure'].includes(check.conclusion) }).length > 0 if (hasFailureChecks) { - console.log(`PR ${res.pr.number} because it has failing checks`); + console.log(`Skiping PR ${res.pr.number} because it has failing checks`); return null } return res.pr From 24d74d5c904e48f91d4c0cc30be33e60d3f50521 Mon Sep 17 00:00:00 2001 From: Gustavo Monteiro Date: Mon, 30 Jan 2023 14:27:04 -0300 Subject: [PATCH 4/7] feat: filtering not mergeable prs 1.0.19 feat: log error 1.0.20 --- package-lock.json | 4 ++-- package.json | 2 +- src/helper.js | 27 +++++++++++++++++++-------- src/index.js | 3 ++- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index fd3c684..5b2478f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "gitmerge-action", - "version": "1.0.18", + "version": "1.0.20", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "gitmerge-action", - "version": "1.0.18", + "version": "1.0.20", "license": "ISC", "dependencies": { "@actions/core": "^1.10.0", diff --git a/package.json b/package.json index e434218..6d737c7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gitmerge-action", - "version": "1.0.18", + "version": "1.0.20", "description": "Native Github action to make merge and deploy from repo", "main": "index.js", "scripts": { diff --git a/src/helper.js b/src/helper.js index 5d4588b..e5ddc31 100644 --- a/src/helper.js +++ b/src/helper.js @@ -53,23 +53,34 @@ async function getPrs() { base: target, }) + // Filtering draft PRs let prs = data.filter(pr => !pr.draft) - const merges = prs.map(async(pr) => { + // Filtering PRs with merge conflicts with base or pending required reviews + const mergeableStatuses = prs.map(async(pr) => { const res = await octokit.request('GET /repos/{owner}/{repo}/pulls/{pull_number}', { ...repoInfo, pull_number: pr.number }) - console.log( { - pr: pr.number, + return { + pr, mergeable: res.data.mergeable - }) + } }) - await Promise.all(merges) + const mergeable = await Promise.all(mergeableStatuses) + + prs = mergeable.map(ms => { + if (ms.mergeable) { + return ms.pr + } + console.log(`Skiping PR ${ms.pr.number} because it's not mergeable`); + return null + }). filter(pr => pr) - const promises = prs.map(async(pr) => { + // Filtering PRs with failed checks + const checksStatuses = prs.map(async(pr) => { const conclusions = await octokit.request('GET /repos/{owner}/{repo}/commits/{ref}/check-runs', { ...repoInfo, ref: pr.head.ref, @@ -80,9 +91,9 @@ async function getPrs() { } }) - const responses = await Promise.all(promises) + const checksResponses = await Promise.all(checksStatuses) - prs = responses.map(res => { + prs = checksResponses.map(res => { const hasFailureChecks = res.checks.check_runs.filter(check => { return ['action_required', 'failure'].includes(check.conclusion) }).length > 0 diff --git a/src/index.js b/src/index.js index f20c022..7090f9b 100644 --- a/src/index.js +++ b/src/index.js @@ -22,9 +22,10 @@ async function run() { } await recreateDeployBranch(lastMergeCommitSha) } catch(error) { + console.log(error); await conflictDetails(lastBranchToMerge) } finally { - // await deleteBranch(workBranchName) + await deleteBranch(workBranchName) } } From bb9d6d23c41431b5de18c0074dcda61eb2d598ac Mon Sep 17 00:00:00 2001 From: Gustavo Monteiro Date: Mon, 30 Jan 2023 15:00:23 -0300 Subject: [PATCH 5/7] fix: prevent error on delete branch 1.0.21 fix: typo 1.0.22 fix: log position --- package-lock.json | 4 ++-- package.json | 2 +- src/helper.js | 18 ++++++++++++------ 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5b2478f..086c8c0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "gitmerge-action", - "version": "1.0.20", + "version": "1.0.22", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "gitmerge-action", - "version": "1.0.20", + "version": "1.0.22", "license": "ISC", "dependencies": { "@actions/core": "^1.10.0", diff --git a/package.json b/package.json index 6d737c7..540f619 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gitmerge-action", - "version": "1.0.20", + "version": "1.0.22", "description": "Native Github action to make merge and deploy from repo", "main": "index.js", "scripts": { diff --git a/src/helper.js b/src/helper.js index e5ddc31..ef7c6d6 100644 --- a/src/helper.js +++ b/src/helper.js @@ -31,12 +31,18 @@ async function createAuxBranch(commitSha) { async function deleteBranch(branchName) { console.log(`Deleting branch ${branchName}`) - await octokit.rest.git.deleteRef({ - ...repoInfo, - ref: branchName - }) - - console.log('Successful delete branch') + try { + await octokit.rest.git.deleteRef({ + ...repoInfo, + ref: branchName, + }) + console.log('Successful delete branch') + } catch (error) { + if (error.message !== 'Reference does not exist') { + throw Error('Unexpected error on delete branch') + } + console.warn('Branch does not exists'); + } } async function mergeBranchs(pullHeadRef) { From c6570f956b693188256541c3a72f821db83e9f6c Mon Sep 17 00:00:00 2001 From: Gustavo Monteiro Date: Mon, 30 Jan 2023 15:07:22 -0300 Subject: [PATCH 6/7] 1.0.23 feat: log checks names 1.0.24 feat: get pr reference number 1.0.25 feat: skip merge check from referred pr 1.0.26 fix: fix filter releated pr checks 1.0.27 feat: log checks 1.0.28 feat: log related pr checks 1.0.29 feat: improve logs for checks 1.0.30 feat: use action default logger 1.0.31 fix: use correct log level 1.0.32 feat: set job status when error 1.0.33 fix: use env pr sha 1.0.34 feat: log check info 1.0.35 feat: log set status response 1.0.36 feat: use default logger 1.0.37 chore: add comment about possible loop on check runs --- package-lock.json | 4 ++-- package.json | 2 +- src/helper.js | 37 +++++++++++++++++++++---------------- src/index.js | 6 +++--- 4 files changed, 27 insertions(+), 22 deletions(-) diff --git a/package-lock.json b/package-lock.json index 086c8c0..fb8783d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "gitmerge-action", - "version": "1.0.22", + "version": "1.0.37", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "gitmerge-action", - "version": "1.0.22", + "version": "1.0.37", "license": "ISC", "dependencies": { "@actions/core": "^1.10.0", diff --git a/package.json b/package.json index 540f619..70dfb60 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gitmerge-action", - "version": "1.0.22", + "version": "1.0.37", "description": "Native Github action to make merge and deploy from repo", "main": "index.js", "scripts": { diff --git a/src/helper.js b/src/helper.js index ef7c6d6..94164db 100644 --- a/src/helper.js +++ b/src/helper.js @@ -1,3 +1,4 @@ +const core = require('@actions/core') const github = require('@actions/github') const { deployRefHead, deployRefName, repoInfo, token, target, ref, deployBranchName } = require('./constants') @@ -8,40 +9,40 @@ const auxBranchName = `${deployRefHead}-${timestamp}` const auxBranchRef = `${deployRefName}-${timestamp}` async function getLastCommitSha() { - console.log(`Getting last commit from branch ${ref}`); + core.info(`Getting last commit from branch ${ref}`); const { data } = await octokit.rest.repos.getCommit({ ...repoInfo, ref: ref }) - console.log(`Successful get commit with message: ${data.commit.message}`); + core.info(`Successful get commit with message: ${data.commit.message}`); return data.sha } async function createAuxBranch(commitSha) { - console.log(`Creating branch ${auxBranchName}`) + core.info(`Creating branch ${auxBranchName}`) await createBranch(auxBranchName, commitSha) - console.log(`Successful create branch`) + core.info(`Successful create branch`) return auxBranchRef } async function deleteBranch(branchName) { - console.log(`Deleting branch ${branchName}`) + core.info(`Deleting branch ${branchName}`) try { await octokit.rest.git.deleteRef({ ...repoInfo, ref: branchName, }) - console.log('Successful delete branch') + core.info('Successful delete branch') } catch (error) { if (error.message !== 'Reference does not exist') { throw Error('Unexpected error on delete branch') } - console.warn('Branch does not exists'); + core.warning('Branch does not exists'); } } @@ -81,7 +82,7 @@ async function getPrs() { if (ms.mergeable) { return ms.pr } - console.log(`Skiping PR ${ms.pr.number} because it's not mergeable`); + core.info(`Skiping PR ${ms.pr.number} because it's not mergeable`); return null }). filter(pr => pr) @@ -101,25 +102,29 @@ async function getPrs() { prs = checksResponses.map(res => { const hasFailureChecks = res.checks.check_runs.filter(check => { - return ['action_required', 'failure'].includes(check.conclusion) + /** + * For the releted PR, the action status will be (null) at this point because it's in progress. + * It prevents from skip current pr if last check run from this action had report failure status. + */ + return ['action_required', 'cancelled', 'timed_out', 'failure'].includes(check.conclusion) }).length > 0 if (hasFailureChecks) { - console.log(`Skiping PR ${res.pr.number} because it has failing checks`); + core.info(`Skiping PR ${res.pr.number} because it has failing checks`); return null } return res.pr - }).filter( pr => pr) + }).filter(pr => pr) - console.log(`Loading ${prs.length} PRs`) + core.info(`Loading ${prs.length} PRs`) return prs } async function recreateDeployBranch(commitSha) { - console.log(`Recreating branch ${deployRefHead}`) + core.info(`Recreating branch ${deployRefHead}`) await deleteBranch(deployRefName) await createBranch(deployRefHead, commitSha) - console.log(`Successful create branch`) + core.info(`Successful create branch`) } async function createBranch(branchName, commitSha) { @@ -140,12 +145,12 @@ async function conflictDetails(head) { } }) const { data: { html_url, permalink_url, diff_url, patch_url } } = res - console.log(`Para conferir detalhes do conflito veja os links: + core.setFailed(`Para conferir detalhes do conflito veja os links: html_url: ${html_url}, permalink_url: ${permalink_url}, diff_url: ${diff_url}, patch_url: ${patch_url}, - `); + `) } diff --git a/src/index.js b/src/index.js index 7090f9b..68c789b 100644 --- a/src/index.js +++ b/src/index.js @@ -1,3 +1,4 @@ +const core = require('@actions/core') const { getLastCommitSha, createAuxBranch, deleteBranch, getPrs, mergeBranchs, recreateDeployBranch, conflictDetails } = require('./helper') async function run() { @@ -11,18 +12,17 @@ async function run() { try { let lastMergeCommitSha for (let pull of pullRequests) { - console.log(`Merging PR ${pull.number}`) + core.info(`Merging PR ${pull.number}`) lastBranchToMerge = pull.head.ref const { data } = await mergeBranchs(pull.head.ref) - console.log(`Successful merge PR ${pull.number}`); + core.info(`Successful merge PR ${pull.number}`); lastMergeCommitSha = data.sha } await recreateDeployBranch(lastMergeCommitSha) } catch(error) { - console.log(error); await conflictDetails(lastBranchToMerge) } finally { await deleteBranch(workBranchName) From c2503267e37d5d3c11c3249a0eae51a9a7f03fe3 Mon Sep 17 00:00:00 2001 From: Gustavo Monteiro Date: Tue, 14 Feb 2023 16:34:47 -0300 Subject: [PATCH 7/7] 1.0.38 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index fb8783d..13e8d50 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "gitmerge-action", - "version": "1.0.37", + "version": "1.0.38", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "gitmerge-action", - "version": "1.0.37", + "version": "1.0.38", "license": "ISC", "dependencies": { "@actions/core": "^1.10.0", diff --git a/package.json b/package.json index 70dfb60..87d82b1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gitmerge-action", - "version": "1.0.37", + "version": "1.0.38", "description": "Native Github action to make merge and deploy from repo", "main": "index.js", "scripts": {