assign-approved-pr-to-test: Filter out statuses from `e2e-tests-check-bot` in `getReviewApprovalState` when state is `unstable`
This commit is contained in:
parent
733794a7c3
commit
bc135c4c2e
|
@ -38,6 +38,7 @@ To get your environment set up, go through the following steps:
|
|||
```
|
||||
|
||||
After this, you can start the bot by running the following:
|
||||
|
||||
```sh
|
||||
npm start
|
||||
```
|
||||
|
@ -119,7 +120,7 @@ Examples of settings that can be configured:
|
|||
- `bounty-project-board/awaiting-approval-label-name`: Name of the label used in issues to declare that an issue is awaiting approval to become a bounty
|
||||
- `bounty-project-board/bounty-label-name`: Name of the label used in issues to declare that an issue is a bounty
|
||||
- `bounty-project-board/bounty-size-label-name-regex`: Regular expression that matches the bounty size label and returns a group containing the size itself
|
||||
- `bounty-project-board/post-approved-bounties-to-slack-room`: Name of the Slack room where to cross-post approved bounties
|
||||
- `bounty-project-board/post-approved-bounties-to-slack-room`: Name of the Slack room where to cross-post approved bounties
|
||||
|
||||
- Automated tests settings:
|
||||
- `automated-tests/repo-full-name`: Full name of the repo to watch in project cards in order to automatically run automated tests CI job (e.g. `status-im/status-react`)
|
||||
|
|
|
@ -22,11 +22,28 @@ const botName = 'assign-approved-pr-to-test'
|
|||
module.exports = robot => {
|
||||
createScheduler(robot, { interval: 10 * 60 * 1000, delay: !process.env.DISABLE_DELAY })
|
||||
robot.on('schedule.repository', context => checkOpenPullRequests(robot, context))
|
||||
robot.on('pull_request.opened', context => handleOpenedPullRequest(robot, context))
|
||||
}
|
||||
|
||||
// This method creates a sentinel status in new PRs so that they can't be merged before an e2e test run has successfully completed
|
||||
async function handleOpenedPullRequest (robot, context) {
|
||||
const config = await getConfig(context, 'github-bot.yml', defaultConfig(robot, '.github/github-bot.yml'))
|
||||
const projectBoardConfig = config ? config['project-board'] : null
|
||||
const automatedTestsConfig = config ? config['automated-tests'] : null
|
||||
if (!projectBoardConfig || !automatedTestsConfig) {
|
||||
return
|
||||
}
|
||||
|
||||
await context.github.repos.createStatus(context.repo({
|
||||
context: 'Mobile e2e tests',
|
||||
description: 'Tests will run once the PR is moved to the TO TEST column',
|
||||
sha: context.payload.pull_request.head.sha,
|
||||
state: 'error'
|
||||
}))
|
||||
}
|
||||
|
||||
async function checkOpenPullRequests (robot, context) {
|
||||
const { github, payload } = context
|
||||
const repo = payload.repository
|
||||
const { github, payload: { repository: repo } } = context
|
||||
const repoInfo = context.repo()
|
||||
const config = await getConfig(context, 'github-bot.yml', defaultConfig(robot, '.github/github-bot.yml'))
|
||||
const projectBoardConfig = config ? config['project-board'] : null
|
||||
|
@ -94,7 +111,12 @@ async function assignPullRequestToCorrectColumn (context, robot, repo, pullReque
|
|||
|
||||
let state = null
|
||||
try {
|
||||
state = await gitHubHelpers.getReviewApprovalState(github, robot, prInfo, testedPullRequestLabelName)
|
||||
// Ignore statuses created by us
|
||||
const filterFn = (status) => !(status.context === 'Mobile e2e tests' &&
|
||||
status.creator &&
|
||||
(status.creator.login === 'status-github-bot[bot]' || status.creator.login === 'e2e-tests-check-bot[bot]'))
|
||||
|
||||
state = await gitHubHelpers.getReviewApprovalState(context, robot, prInfo, testedPullRequestLabelName, filterFn)
|
||||
} catch (err) {
|
||||
robot.log.error(`${botName} - Couldn't calculate the PR approval state: ${err}`, prInfo)
|
||||
}
|
||||
|
|
2
index.js
2
index.js
|
@ -9,7 +9,7 @@
|
|||
// Author:
|
||||
// PombeirP
|
||||
|
||||
//const Slack = require('./lib/slack')
|
||||
// const Slack = require('./lib/slack')
|
||||
const memjs = require('memjs')
|
||||
|
||||
module.exports = async (robot) => {
|
||||
|
|
|
@ -35,10 +35,13 @@ async function _getPullRequestReviewStates (github, prInfo) {
|
|||
return Array.from(finalReviewsMap.values())
|
||||
}
|
||||
|
||||
async function _getReviewApprovalState (github, robot, prInfo, testedPullRequestLabelName) {
|
||||
async function _getReviewApprovalState (context, robot, prInfo, testedPullRequestLabelName, filterIgnoredStatusContextFn) {
|
||||
const { github } = context
|
||||
|
||||
// Get detailed pull request
|
||||
const pullRequestPayload = await github.pullRequests.get(prInfo)
|
||||
const pullRequest = pullRequestPayload.data
|
||||
context.payload.pull_request = pullRequest
|
||||
if (pullRequest.mergeable !== null && pullRequest.mergeable !== undefined && !pullRequest.mergeable) {
|
||||
robot.log.debug(`pullRequest.mergeable is ${pullRequest.mergeable}, considering as failed`)
|
||||
return 'failed'
|
||||
|
@ -57,6 +60,15 @@ async function _getReviewApprovalState (github, robot, prInfo, testedPullRequest
|
|||
case 'dirty':
|
||||
state = 'failed'
|
||||
break
|
||||
case 'unstable':
|
||||
if (filterIgnoredStatusContextFn) {
|
||||
const isSuccess = await _isPullRequestStatusSuccessIgnoringContext(context, filterIgnoredStatusContextFn, pullRequest)
|
||||
if (isSuccess) {
|
||||
state = 'approved'
|
||||
robot.log.debug(`All important statuses are successful, so considering state as $${state}`)
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
robot.log.debug(`pullRequest.mergeable_state is ${pullRequest.mergeable_state}, considering state as ${state}`)
|
||||
|
||||
|
@ -179,3 +191,44 @@ async function _getPullRequestCurrentStatusForContext (context, statusContext, p
|
|||
|
||||
return (statuses.find(status => status.context === statusContext) || {}).state
|
||||
}
|
||||
|
||||
async function _isPullRequestStatusSuccessIgnoringContext (context, filterIgnoredStatusContextFn, pullRequest) {
|
||||
if (!pullRequest) {
|
||||
pullRequest = context.payload.pull_request
|
||||
}
|
||||
|
||||
const statuses = await context.github.paginate(
|
||||
context.github.repos.listStatusesForRef(context.repo({
|
||||
ref: pullRequest.head.sha,
|
||||
per_page: 100
|
||||
})),
|
||||
res => res.data)
|
||||
|
||||
const contexts = {}
|
||||
for (let i = statuses.length - 1; i >= 0; i--) {
|
||||
const status = statuses[i]
|
||||
if (filterIgnoredStatusContextFn(status)) {
|
||||
contexts[status.context] = status.state
|
||||
}
|
||||
}
|
||||
|
||||
let isSuccess = true
|
||||
for (const context in contexts) {
|
||||
if (contexts.hasOwnProperty(context)) {
|
||||
const state = contexts[context]
|
||||
|
||||
switch (state) {
|
||||
case 'pending':
|
||||
case 'error':
|
||||
isSuccess = false
|
||||
break
|
||||
}
|
||||
|
||||
if (!isSuccess) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return isSuccess
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -19,18 +19,18 @@
|
|||
"joi": "^13.7.0",
|
||||
"mem-cache": "0.0.5",
|
||||
"memjs": "^1.2.0",
|
||||
"probot": "^5.0.1",
|
||||
"probot": "^7.5.0",
|
||||
"probot-config": "^0.1.0",
|
||||
"probot-scheduler": "^1.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint-config-standard": "^11.0.0",
|
||||
"eslint-plugin-import": "^2.14.0",
|
||||
"eslint-plugin-import": "^2.15.0",
|
||||
"eslint-plugin-node": "^5.2.1",
|
||||
"eslint-plugin-promise": "^3.8.0",
|
||||
"eslint-plugin-standard": "^3.1.0",
|
||||
"ethereumjs-util": "^5.2.0",
|
||||
"husky": "^1.1.1",
|
||||
"husky": "^1.3.1",
|
||||
"jest": "^22.4.4",
|
||||
"smee-client": "^1.0.2",
|
||||
"standard": "^10.0.3"
|
||||
|
|
Loading…
Reference in New Issue