diff --git a/README.md b/README.md index 911a3fd0..810a272e 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,9 @@ on: pull_request_review: types: - submitted + check_suites_run: + types: + - completed status: {} jobs: automerge: @@ -126,6 +129,10 @@ The following merge options are supported: The default is `10000` (10 seconds) and setting it to `0` disables sleeping between retries. + If some cases (travis ci for example), this action can also be triggered by the successful completion of checks + (i.e. builds) via the `check_suites_run` statement in the `automerge.yml`. In that case + you can safely set this to `0`. + - `MERGE_DELETE_BRANCH`: Automatic deletion of branches does not work for all repositories. Set this option to `true` to automatically delete branches after they have been merged. diff --git a/lib/api.js b/lib/api.js index 6c150a92..359ec910 100644 --- a/lib/api.js +++ b/lib/api.js @@ -65,6 +65,8 @@ async function executeGitHubAction(context, eventName, eventData) { await handleStatusUpdate(context, eventName, eventData); } else if (eventName === "pull_request") { await handlePullRequestUpdate(context, eventName, eventData); + } else if (eventName === "check_suite" || eventName === "check_run") { + await handleCheckUpdate(context, eventName, eventData); } else if (eventName === "pull_request_review") { await handlePullRequestReviewUpdate(context, eventName, eventData); } else if (eventName === "schedule") { @@ -85,6 +87,40 @@ async function handlePullRequestUpdate(context, eventName, event) { await merge(context, event.pull_request); } +async function handleCheckUpdate(context, eventName, event) { + const { action } = event; + const { octokit } = context; + const payload = eventName === 'check_suite' ? event.check_suite : event.check_run; + if (action !== "completed") { + logger.info("A status check is not yet complete:", eventName); + throw new NeutralExitError(); + } else { + if (payload.conclusion === "success") { + logger.info("Check has successfully completed - trying to Merge") + const checkPullRequest = payload.pull_requests[0] + if (checkPullRequest != null) { + const { data: pullRequest } = await octokit.request( checkPullRequest.url) + logger.trace("PullrequestData ",pullRequest) + + await update(context, pullRequest); + await merge(context, pullRequest); + } else { + const branchName = payload.head_branch + if (branchName != null ) { + logger.info("Going into the branch listing") + await checkPullRequestsForBranches(context,event, branchName) + } else { + logger.info("Could not find Pull Request Data in this status check result"); + throw new NeutralExitError(); + } + } + } else { + logger.info("A status check completed unsuccessfully:", eventName); + throw new NeutralExitError(); + } + } +} + async function handlePullRequestReviewUpdate(context, eventName, event) { const { action, review } = event; if (action === "submitted") { @@ -112,15 +148,19 @@ async function handleStatusUpdate(context, eventName, event) { return; } - const { octokit } = context; - for (const branch of branches) { - logger.debug("Listing pull requests for", branch.name, "..."); + await checkPullRequestsForBranches(context,event,branch.name) + } +} + +async function checkPullRequestsForBranches(context,event,branchName) { + const { octokit } = context; + logger.debug("Listing pull requests for", branchName, "..."); const { data: pullRequests } = await octokit.pulls.list({ owner: event.repository.owner.login, repo: event.repository.name, state: "open", - head: `${event.repository.owner.login}:${branch.name}`, + head: `${event.repository.owner.login}:${branchName}`, sort: "updated", direction: "desc", per_page: MAX_PR_COUNT @@ -138,12 +178,9 @@ async function handleStatusUpdate(context, eventName, event) { logger.error(e); } } - if (updated === 0) { logger.info("No PRs have been updated/merged"); - return; } - } } async function handleBranchUpdate(context, eventName, event) {