forked from mheap/github-action-pr-heroku-review-app
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
6,309 additions
and
1,033 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,31 @@ | ||
FROM node:10.14.2-alpine | ||
WORKDIR /app | ||
# Use the latest version of Node.js | ||
# | ||
# You may prefer the full image: | ||
# FROM node | ||
# | ||
# or even an alpine image (a smaller, faster, less-feature-complete image): | ||
# FROM node:alpine | ||
# | ||
# You can specify a version: | ||
# FROM node:10-slim | ||
FROM node:slim | ||
|
||
# Labels for GitHub to read your action | ||
LABEL "com.github.actions.name"="Heroku Review Application" | ||
LABEL "com.github.actions.description"="Create a Heroku review app when a PR is raised by someone with write or admin access" | ||
# Here are all of the available icons: https://feathericons.com/ | ||
LABEL "com.github.actions.icon"="book-open" | ||
# And all of the available colors: https://developer.github.com/actions/creating-github-actions/creating-a-docker-container/#label | ||
LABEL "com.github.actions.color"="orange" | ||
|
||
# Copy the package.json and package-lock.json | ||
COPY package*.json ./ | ||
RUN npm install --only=production | ||
|
||
# Install dependencies | ||
RUN npm ci | ||
|
||
# Copy the rest of your action's code | ||
COPY . . | ||
ENTRYPOINT ["node", "/app/create-review-app.js"] | ||
|
||
# Run `node /index.js` | ||
ENTRYPOINT ["node", "/index.js"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,8 @@ | ||
name: 'Heroku Review Apps for contributors' | ||
description: 'Create a Heroku review app when a PR is raised by someone with write or admin access' | ||
author: 'Michael Heap' | ||
branding: | ||
icon: 'book-open' | ||
color: 'orange' | ||
name: Heroku Review Application | ||
description: Create a Heroku review app when a PR is raised by someone with write or admin access | ||
runs: | ||
using: 'docker' | ||
image: 'Dockerfile' | ||
using: docker | ||
image: Dockerfile | ||
branding: | ||
icon: book-open | ||
color: orange |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
const { Toolkit } = require("actions-toolkit"); | ||
|
||
const Heroku = require("heroku-client"); | ||
const heroku = new Heroku({ token: process.env.HEROKU_API_TOKEN }); | ||
|
||
// Run your GitHub Action! | ||
Toolkit.run( | ||
async (tools) => { | ||
const pr = tools.context.payload.pull_request; | ||
|
||
// Required information | ||
const branch = pr.head.ref; | ||
const version = pr.head.sha; | ||
const fork = pr.head.repo.fork; | ||
const pr_number = pr.number; | ||
const source_url = `${pr.head.repo.html_url}/tarball/${branch}`; | ||
|
||
let fork_repo_id; | ||
if (fork) { | ||
fork_repo_id = pr.head.repo.id; | ||
} | ||
|
||
tools.log.debug("Deploy Info", { | ||
branch, | ||
version, | ||
fork, | ||
pr_number, | ||
source_url, | ||
}); | ||
|
||
// Do they have the required permissions? | ||
let requiredCollaboratorPermission = process.env.COLLABORATOR_PERMISSION; | ||
if (requiredCollaboratorPermission) { | ||
requiredCollaboratorPermission = requiredCollaboratorPermission.split( | ||
"," | ||
); | ||
} else { | ||
requiredCollaboratorPermission = ["triage", "write", "maintain", "admin"]; | ||
} | ||
|
||
const reviewAppLabelName = | ||
process.env.REVIEW_APP_LABEL_NAME || "review-app"; | ||
|
||
const perms = await tools.github.repos.getCollaboratorPermissionLevel({ | ||
...tools.context.repo, | ||
username: tools.context.actor, | ||
}); | ||
|
||
if (!requiredCollaboratorPermission.includes(perms.data.permission)) { | ||
tools.exit.success("User is not a collaborator. Skipping"); | ||
} | ||
|
||
tools.log.info(`User is a collaborator: ${perms.data.permission}`); | ||
|
||
let createReviewApp = false; | ||
|
||
let action = tools.context.payload.action; | ||
if (["opened", "synchronize"].indexOf(action) !== -1) { | ||
tools.log.info("PR opened by collaborator"); | ||
createReviewApp = true; | ||
await tools.github.issues.addLabels({ | ||
...tools.context.repo, | ||
labels: ["review-app"], | ||
issue_number: pr_number, | ||
}); | ||
} else if (action === "labeled") { | ||
const labelName = tools.context.payload.label.name; | ||
tools.log.info(`${labelName} label was added by collaborator`); | ||
|
||
if (labelName === reviewAppLabelName) { | ||
createReviewApp = true; | ||
} else { | ||
tools.log.debug(`Unexpected label, not creating app: ${labelName}`); | ||
} | ||
} | ||
|
||
if (createReviewApp) { | ||
try { | ||
tools.log.pending("Creating review app"); | ||
const resp = await heroku.post("/review-apps", { | ||
body: { | ||
branch, | ||
pipeline: process.env.HEROKU_PIPELINE_ID, | ||
source_blob: { | ||
url: source_url, | ||
version, | ||
}, | ||
fork_repo_id, | ||
pr_number, | ||
}, | ||
}); | ||
tools.log.complete("Created review app"); | ||
} catch (e) { | ||
// A 409 is a conflict, which means the app already exists | ||
if (e.statusCode !== 409) { | ||
throw e; | ||
} | ||
} | ||
} | ||
}, | ||
{ | ||
event: [ | ||
"pull_request.opened", | ||
"pull_request.synchronize", | ||
"pull_request.labeled", | ||
], | ||
secrets: ["GITHUB_TOKEN", "HEROKU_API_TOKEN", "HEROKU_PIPELINE_ID"], | ||
} | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
const { Toolkit } = require('actions-toolkit') | ||
|
||
describe('Heroku Review Application', () => { | ||
let action, tools | ||
|
||
// Mock Toolkit.run to define `action` so we can call it | ||
Toolkit.run = jest.fn((actionFn) => { action = actionFn }) | ||
// Load up our entrypoint file | ||
require('.') | ||
|
||
beforeEach(() => { | ||
// Create a new Toolkit instance | ||
tools = new Toolkit() | ||
// Mock methods on it! | ||
tools.exit.success = jest.fn() | ||
}) | ||
|
||
it('exits successfully', () => { | ||
action(tools) | ||
expect(tools.exit.success).toHaveBeenCalled() | ||
expect(tools.exit.success).toHaveBeenCalledWith('We did it!') | ||
}) | ||
}) |
Oops, something went wrong.