Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow sub-processes to request DSL JSON #769

Merged
merged 2 commits into from
Nov 20, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
## Master

- Adds `html_url` to the PR JSON declaration - [@orta][]
- Adds a way for a sub-process to tell danger-js that it wants a copy of the DSL. This is a potential fix for when you
have a process that might not be ready to grab the DSL instantly from danger-js. The subprocess can print the message
`danger://send-dsl` to stdout and danger-js will re-send the DSL via STDIN.
[danger/swift#108](https://github.com/danger/swift/issues/108). - [@orta][]
- Allows a FakeCI to get a FakePlatform, should fix [#767](https://github.com/danger/danger-js/issues/767) - [@orta][]

# 6.1.4

Expand Down
10 changes: 8 additions & 2 deletions docs/usage/danger-process.html.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Danger in my Language
subtitle: Using Danger Process
subtitle: Using --process to build danger runners
layout: guide_js
order: 3
blurb: How to use `danger process` to create a Danger runner for any language.
Expand Down Expand Up @@ -86,7 +86,7 @@ STDOUT.write(results.to_json)

As Ruby is duck-typed, it doesn't need any infrastructure. You can parse the incoming JSON into an object, then work
with the standard library to provide a Dangerfile environment. If you saved this file as `dangerfile.rb`, and
`chmod +x dangerfile.rb` then you can run `danger process 'dangerfile.rb`.
`chmod +x dangerfile.rb` then you can run `danger pr --process 'dangerfile.rb`.

### Tiny, and not too simple

Expand Down Expand Up @@ -192,6 +192,12 @@ It's pretty likely that your CI already has node, so it can just be `npm install

Finally, let me ([@orta][]) know! I want to keep track of them all on the Danger Systems site :+1:.

### Troubleshooting

- If you're having timeout issues on waiting for STDIN from Danger JS, then it's possible that Danger JS is sending the
STDIN too soon for your process to catch it. To work around this, have your process print `danger://send-dsl` and
Danger JS will re-send the JSON to your process.

[danger-swift]: https://github.com/danger/danger-swift
[swift-json]: https://github.com/danger/danger-swift/blob/master/fixtures/eidolon_609.json
[swift-stdin]:
Expand Down
1 change: 1 addition & 0 deletions source/ci_source/providers/Fake.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export class FakeCI implements CISource {
get isCI(): boolean {
return ensureEnvKeysExist(this.env, ["DANGER_FAKE_CI"]) || ensureEnvKeysExist(this.env, ["DANGER_LOCAL_NO_CI"])
}

get isPR(): boolean {
return true
}
Expand Down
2 changes: 1 addition & 1 deletion source/ci_source/providers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ import { Travis } from "./Travis"
import { VSTS } from "./VSTS"

const providers = [
FakeCI,
GitHubActions,
Travis,
Circle,
Semaphore,
Nevercode,
Jenkins,
FakeCI,
Surf,
DockerCloud,
Codeship,
Expand Down
30 changes: 24 additions & 6 deletions source/commands/utils/runDangerSubprocess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import { RunnerConfig } from "../ci/runner"

const d = debug("runDangerSubprocess")

// If a sub-process passes this to stdout then danger-js will pass
// the DSL back to the process
const messageToSendDSL = "danger://send-dsl"

// Sanitizes the DSL so for sending via STDOUT
export const prepareDangerDSL = (dangerDSL: DangerDSLJSONType) => {
if (dangerDSL.github && dangerDSL.github.api) {
Expand Down Expand Up @@ -38,25 +42,39 @@ export const runDangerSubprocess = (
d(`Running subprocess: ${processDisplayName} - ${args}`)
const child = spawn(processName, args, { env: { ...process.env, ...config.additionalEnvVars } })

d(`Started passing in STDIN`)
child.stdin.write(dslJSONString)
child.stdin.end()
d(`Passed in STDIN`)
const sendDSLToSubprocess = () => {
d(`Started passing in STDIN`)
child.stdin.write(dslJSONString)
child.stdin.end()
d(`Passed in STDIN`)
}

// Initial sending of the DSL
sendDSLToSubprocess()

let allLogs = ""
child.stdout.on("data", async data => {
const stdout = data.toString()
const stdout: string = data.toString()
allLogs += stdout

// There are two checks
// Provide a way for a process to request the DSL
// if they missed the first go.
if (stdout.includes(messageToSendDSL)) {
sendDSLToSubprocess()
}

// There are two checks for a response
const maybeJSON = getJSONFromSTDOUT(stdout)
const maybeJSONURL = getJSONURLFromSTDOUT(stdout)

// Remove message sent back to danger-js
const withoutURLs: string = data
.toString()
.replace(maybeJSON, "")
.replace(maybeJSONURL + "\n", "")
.replace(maybeJSONURL, "")
.replace(messageToSendDSL + "\n", "")
.replace(messageToSendDSL, "")

console.log(withoutURLs)

Expand Down
6 changes: 6 additions & 0 deletions source/platforms/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { DangerResults } from "../dsl/DangerResults"
import { ExecutorOptions } from "../runner/Executor"
import { DangerRunner } from "../runner/runners/runner"
import chalk from "chalk"
import { FakePlatform } from "./FakePlatform"

/** A type that represents the downloaded metadata about a code review session */
export type Metadata = any
Expand Down Expand Up @@ -123,6 +124,11 @@ export function getPlatformForEnv(env: Env, source: CISource, requireAuth = true
return github
}

// Support automatically returning a fake platform if you pass a Fake CI
if (source.name === "Fake Testing CI") {
return new FakePlatform()
}

console.error("The DANGER_GITHUB_API_TOKEN/DANGER_BITBUCKETSERVER_HOST environmental variable is missing")
console.error("Without an api token, danger will be unable to comment on a PR")
throw new Error("Cannot use authenticated API requests.")
Expand Down