Skip to content

Commit

Permalink
Add support for posting GitHub statuses (#280)
Browse files Browse the repository at this point in the history
See #279
  • Loading branch information
orta authored and macklinu committed Jun 13, 2017
1 parent 587530e commit ecacadb
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 15 deletions.
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

### Master

- Posts status reports for passing/failing builds, if the account for danger has access - orta
- Adds prettier to the codebase - orta
- Converts a bunch of Danger's dangerfile into a plugin - [danger-plugin-yarn](https://github.com/orta/danger-plugin-yarn) - orta

Expand Down
4 changes: 4 additions & 0 deletions source/platforms/FakePlatform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,8 @@ export class FakePlatform implements Platform {
async editMainComment(_comment: string): Promise<boolean> {
return true
}

async updateStatus(_success: boolean, _message: string): Promise<boolean> {
return true
}
}
9 changes: 9 additions & 0 deletions source/platforms/GitHub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ export class GitHub {
return issue || { labels: [] }
}

/**
* Fails the current build, if status setting succeeds
* then return true.
*/

async updateStatus(passed: boolean, message: string): Promise<boolean> {
return await this.api.updateStatus(passed, message)
}

/**
* Returns the `github` object on the Danger DSL
*
Expand Down
20 changes: 20 additions & 0 deletions source/platforms/github/GitHubAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,26 @@ export class GitHubAPI {

return res.ok ? res.json() : { labels: [] }
}

async updateStatus(passed: boolean, message: string): Promise<any> {
const repo = this.repoMetadata.repoSlug

const prJSON = await this.getPullRequestInfo()
const ref = prJSON.head.sha
const res = await this.post(
`repos/${repo}/statuses/${ref}`,
{},
{
state: passed ? "success" : "failure",
context: "Danger",
target_url: "https://danger.systems/js",
description: message,
}
)

return res.ok
}

// API Helpers

private api(path: string, headers: any = {}, body: any = {}, method: string) {
Expand Down
14 changes: 2 additions & 12 deletions source/platforms/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,20 +43,10 @@ export interface Platform {
editMainComment: (newComment: string) => Promise<any>
/** Replace the main Danger comment */
updateOrCreateComment: (newComment: string) => Promise<any>
/** Sets the current PR's status */
updateStatus: (passed: boolean, message: string) => Promise<boolean>
}

// /** Download all the comments in a PR */
// async downloadComments: (id: string) => Promise<Comment[]>;

// /** Create a comment on a PR */
// async createComment: (body: string) => Promise<?Comment>;

// /** Delete comments on a PR */
// async deleteComment: (env: any) => Promise<booleanean>;

// /** Edit an existing comment */
// async editComment: (comment: Comment, newBody: string) => Promise<booleanean>;

/**
* Pulls out a platform for Danger to communicate on based on the environment
* @param {Env} env The environment.
Expand Down
20 changes: 19 additions & 1 deletion source/runner/Executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ export class Executor {

this.d(results)

const failed = fails.length > 0
const successPosting = await this.platform.updateStatus(!failed, messageForResults(results))

if (failureCount + messageCount === 0) {
console.log("No issues or messages were sent. Removing any existing messages.")
await this.platform.deleteMainComment()
Expand All @@ -153,7 +156,9 @@ export class Executor {
const s = fails.length === 1 ? "" : "s"
const are = fails.length === 1 ? "is" : "are"
console.log(`Failing the build, there ${are} ${fails.length} fail${s}.`)
process.exitCode = 1
if (!successPosting) {
process.exitCode = 1
}
} else if (warnings.length > 0) {
console.log("Found only warnings, not failing the build.")
} else if (messageCount > 0) {
Expand Down Expand Up @@ -185,3 +190,16 @@ export class Executor {
}
}
}

const compliment = () => {
const compliments = ["Well done.", "Congrats.", "Woo!", "Yay.", "Jolly good show.", "Good on 'ya.", "Nice work."]
return compliments[Math.floor(Math.random() * compliments.length)]
}

const messageForResults = (results: DangerResults) => {
if (!results.fails.length && !results.warnings.length) {
return `All green. ${compliment()}`
} else {
return "⚠️ Danger found some issues. Don't worry, everything is fixable."
}
}
37 changes: 36 additions & 1 deletion source/runner/_tests/_executor.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Executor } from "../Executor"
import { FakeCI } from "../../ci_source/providers/Fake"
import { FakePlatform } from "../../platforms/FakePlatform"
import { emptyResults, warnResults } from "./fixtures/ExampleDangerResults"
import { emptyResults, warnResults, failsResults } from "./fixtures/ExampleDangerResults"

const defaultConfig = {
stdoutOnly: false,
Expand Down Expand Up @@ -65,4 +65,39 @@ describe("setup", () => {
await exec.handleResults(warnResults)
expect(platform.updateOrCreateComment).toBeCalled()
})

it("Updates or Creates comments for warnings", async () => {
const platform = new FakePlatform()
const exec = new Executor(new FakeCI({}), platform, defaultConfig)
platform.updateOrCreateComment = jest.fn()

await exec.handleResults(warnResults)
expect(platform.updateOrCreateComment).toBeCalled()
})

it("Updates the status with success for a passed results", async () => {
const platform = new FakePlatform()
const exec = new Executor(new FakeCI({}), platform, defaultConfig)
platform.updateOrCreateComment = jest.fn()
platform.updateStatus = jest.fn()

await exec.handleResults(warnResults)
expect(platform.updateStatus).toBeCalledWith(
true,
"⚠️ Danger found some issues. Don't worry, everything is fixable."
)
})

it("Updates the status with success for a passed results", async () => {
const platform = new FakePlatform()
const exec = new Executor(new FakeCI({}), platform, defaultConfig)
platform.updateOrCreateComment = jest.fn()
platform.updateStatus = jest.fn()

await exec.handleResults(failsResults)
expect(platform.updateStatus).toBeCalledWith(
false,
"⚠️ Danger found some issues. Don't worry, everything is fixable."
)
})
})
2 changes: 1 addition & 1 deletion source/runner/_tests/fixtures/ExampleDangerResults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const emptyResults: DangerResults = {
}

export const failsResultsWithoutMessages: DangerResults = {
fails: [{}, {}],
fails: [{} as any, {} as any],
warnings: [],
messages: [],
markdowns: [],
Expand Down

0 comments on commit ecacadb

Please # to comment.