Skip to content

Commit

Permalink
Merge pull request #8 from stone-ton/feat/show-conflict-details
Browse files Browse the repository at this point in the history
Feat: show conflict details - v1.1.0
  • Loading branch information
MarceloHEcker authored Feb 16, 2023
2 parents fbf5555 + c250326 commit cabc0c9
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 24 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "gitmerge-action",
"version": "1.0.2",
"version": "1.0.38",
"description": "Native Github action to make merge and deploy from repo",
"main": "index.js",
"scripts": {
Expand Down
115 changes: 97 additions & 18 deletions src/helper.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,49 @@
const core = require('@actions/core')
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()
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.
Commit 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}`)

await octokit.rest.git.deleteRef({
...repoInfo,
ref: branchName
})

console.log('Successful delete branch')
core.info(`Deleting branch ${branchName}`)

try {
await octokit.rest.git.deleteRef({
...repoInfo,
ref: branchName,
})
core.info('Successful delete branch')
} catch (error) {
if (error.message !== 'Reference does not exist') {
throw Error('Unexpected error on delete branch')
}
core.warning('Branch does not exists');
}
}

async function mergeBranchs(pullHeadRef) {
Expand All @@ -54,17 +60,71 @@ async function getPrs() {
base: target,
})

const prs = data.filter(pr => !pr.draft)
console.log(`Loading ${prs.length} PRs`)
// Filtering draft PRs
let prs = data.filter(pr => !pr.draft)

// 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
})

return {
pr,
mergeable: res.data.mergeable
}
})

const mergeable = await Promise.all(mergeableStatuses)

prs = mergeable.map(ms => {
if (ms.mergeable) {
return ms.pr
}
core.info(`Skiping PR ${ms.pr.number} because it's not mergeable`);
return null
}). filter(pr => 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,
})
return {
checks: conclusions.data,
pr
}
})

const checksResponses = await Promise.all(checksStatuses)

prs = checksResponses.map(res => {
const hasFailureChecks = res.checks.check_runs.filter(check => {
/**
* 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) {
core.info(`Skiping PR ${res.pr.number} because it has failing checks`);
return null
}
return res.pr
}).filter(pr => pr)

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) {
Expand All @@ -75,10 +135,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
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},
`)
}


module.exports = {
recreateDeployBranch,
getLastCommitSha,
conflictDetails,
createAuxBranch,
deleteBranch,
mergeBranchs,
Expand Down
12 changes: 9 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const { getLastCommitSha, createAuxBranch, deleteBranch, getPrs, mergeBranchs, recreateDeployBranch } = require('./helper')
const core = require('@actions/core')
const { getLastCommitSha, createAuxBranch, deleteBranch, getPrs, mergeBranchs, recreateDeployBranch, conflictDetails } = require('./helper')

async function run() {
const baseLastCommit = await getLastCommitSha()
Expand All @@ -7,17 +8,22 @@ async function run() {

const pullRequests = await getPrs()

let lastBranchToMerge
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) {
await conflictDetails(lastBranchToMerge)
} finally {
await deleteBranch(workBranchName)
}
Expand Down

0 comments on commit cabc0c9

Please sign in to comment.