Skip to content

Commit

Permalink
Remove bot user (#61)
Browse files Browse the repository at this point in the history
* get rid of the bot user and use octokit instead of axios

* update documentation, remove bot user, allow app to
bypass branch protection

* Document additional permissions needed for app
  • Loading branch information
robandpdx authored Aug 4, 2023
1 parent eedef7c commit 0f54340
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 95 deletions.
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,20 @@ The slack notification can be configured by setting the `SLACK_MESSAGE_FILE`. Th
- `#l` is replaced with the label configured in `EMERGENCY_LABEL`
- `#i` is replaced with the url to the issue created, if issue creation is enabled
## Environment setup
### Create Bot User
If you want the app to merge the emergency PR, and you have "Require status checks to pass before merging" in your branch protection, you will need to give the bot user `owner` permissions on the Org or repo.

If you do not have "Require status checks to pass before merging" you can make the bot user a standard user. If you also have more than 1 approval required you will need to configure the bot user in your branch protection section "Allow specified actors to bypass pull request requirements" in order to allow merging.

Generate a PAT for the bot user with repo scope. Configure SSO for the PAT, authorizing the PAT for your org.
### Create GitHub App
Create the GH App in your org or repo. Define a client secrent. Generate a private key.
#### Grant repository permissions
Set Contents access to `Read & write`
Set Issues access to `Read & write`
Set Pull Requests access to `Read & write`
#### Subscripe to events
Check `Issues`
Check `Issue comment`
Check `Pull request`

#### Allow app to bypass branch protection
If you want the app to merge the emergency PR, and you have "Require status checks to pass before merging" in your branch protection, you will need to allow the app to bypass branch protection.

Once you have the bot user setup and the GitHub app configured you are ready to deploy!

### Create a Slack App
Expand Down
85 changes: 38 additions & 47 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@ module.exports = (app) => {
// Approve PR, if configured to do so
if (process.env.APPROVE_PR == 'true') {
console.log(`Adding review to PR`);
await axios({
method: 'post',
url: `${context.payload.pull_request.url}/reviews`,
auth: auth,
data: { "event": "APPROVE" }
await context.octokit.rest.pulls.createReview({
owner: context.payload.repository.owner.login,
repo: context.payload.repository.name,
pull_number: context.payload.pull_request.number,
body: "Approved by emergency PR bot",
event: "APPROVE"
}).then(response => {
console.log(`Review added`);
}).catch(error => {
Expand All @@ -46,16 +47,13 @@ module.exports = (app) => {
}
let issueBody = fs.readFileSync(process.env.ISSUE_BODY_FILE, 'utf8');
issueBody = issueBody.replace('#',context.payload.pull_request.html_url);
await axios({
method: 'post',
url: `${context.payload.repository.url}/issues`,
auth: auth,
data: {
"title": process.env.ISSUE_TITLE,
"body": issueBody,
"labels": [emergencyLabel],
...assignees
}
await context.octokit.rest.issues.create({
owner: context.payload.repository.owner.login,
repo: context.payload.repository.name,
title: process.env.ISSUE_TITLE,
body: issueBody,
labels: [emergencyLabel],
...assignees
}).then(response => {
console.log(`Issue created`)
newIssue = response.data.html_url;
Expand All @@ -69,10 +67,11 @@ module.exports = (app) => {
// Merge PR, if configured to do so
if (process.env.MERGE_PR == 'true') {
console.log(`Merging PR`);
await axios({
method: 'put',
url: `${context.payload.pull_request.url}/merge`,
auth: auth
await context.octokit.rest.pulls.merge({
owner: context.payload.repository.owner.login,
repo: context.payload.repository.name,
pull_number: context.payload.pull_request.number,
//merge_method: "squash"
}).then(response => {
console.log(`PR merged`);
}).catch(error => {
Expand Down Expand Up @@ -135,13 +134,11 @@ module.exports = (app) => {
let errorsArray = [];

// Add emergency label
await axios({
method: 'patch',
url: context.payload.pull_request.issue_url,
auth: auth,
data: {
"labels": [emergencyLabel]
}
await context.octokit.rest.issues.addLabels({
owner: context.payload.repository.owner.login,
repo: context.payload.repository.name,
issue_number: context.payload.pull_request.number,
labels: [emergencyLabel]
}).then(response => {
console.log(`${emergencyLabel} label reapplied to PR: ${context.payload.pull_request.html_url}`);
}).catch(error => {
Expand All @@ -167,13 +164,11 @@ module.exports = (app) => {
let errorsArray = [];

// Add emergency label
await axios({
method: 'patch',
url: context.payload.issue.url,
auth: auth,
data: {
"labels": [emergencyLabel]
}
await context.octokit.rest.issues.addLabels({
owner: context.payload.repository.owner.login,
repo: context.payload.repository.name,
issue_number: context.payload.pull_request.number,
labels: [emergencyLabel]
}).then(response => {
console.log(`${emergencyLabel} label reapplied to PR: ${context.payload.issue.html_url}`);
}).catch(error => {
Expand All @@ -195,13 +190,11 @@ module.exports = (app) => {
if (context.payload.pull_request.body.toLocaleLowerCase().includes(process.env.TRIGGER_STRING)) {
// Found the trigger string, so add the emergency label to trigger the other stuff...
let errorsArray = [];
await axios({
method: 'patch',
url: context.payload.pull_request.issue_url,
auth: auth,
data: {
"labels": [emergencyLabel]
}
await context.octokit.rest.issues.addLabels({
owner: context.payload.repository.owner.login,
repo: context.payload.repository.name,
issue_number: context.payload.pull_request.number,
labels: [emergencyLabel]
}).then(response => {
console.log(`${emergencyLabel} label applied to PR: ${context.payload.pull_request.html_url}`);
newIssue = response.data.html_url;
Expand All @@ -224,13 +217,11 @@ module.exports = (app) => {
if (context.payload.issue.pull_request && context.payload.comment.body.toLocaleLowerCase().includes(process.env.TRIGGER_STRING)) {
// This is a comment on a PR and we found the trigger string, so add the emergency label to trigger the other stuff...
let errorsArray = [];
await axios({
method: 'patch',
url: context.payload.issue.url,
auth: auth,
data: {
"labels": [emergencyLabel]
}
await context.octokit.rest.issues.addLabels({
owner: context.payload.repository.owner.login,
repo: context.payload.repository.name,
issue_number: context.payload.pull_request.number,
labels: [emergencyLabel]
}).then(response => {
console.log(`${emergencyLabel} label applied to PR: ${context.payload.issue.pull_request.html_url}`);
newIssue = response.data.html_url;
Expand Down
8 changes: 0 additions & 8 deletions template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,6 @@ Parameters:
githubPrivateKey:
Description: The base64 encoded private key of your GitHub app
Type: String
githubUser:
Description: The user with admin access
Type: String
githubPat:
Description: The PAT of the user with admin access
Type: String
emergencyLabel:
Description: The label to use for emergency issues
Type: String
Expand Down Expand Up @@ -101,8 +95,6 @@ Resources:
APP_ID: !Ref githubAppId
WEBHOOK_SECRET: !Ref githubWebhookSecret
PRIVATE_KEY: !Ref githubPrivateKey
GITHUB_USER: !Ref githubUser
GITHUB_PAT: !Ref githubPat
EMERGENCY_LABEL: !Ref emergencyLabel
ISSUE_TITLE: !Ref issueTitle
ISSUE_BODY_FILE: !Ref issueBodyFile
Expand Down
Loading

0 comments on commit 0f54340

Please sign in to comment.