diff --git a/CHANGELOG.md b/CHANGELOG.md index f41c547da..891f7718b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/docs/usage/danger-process.html.md b/docs/usage/danger-process.html.md index 428ac97f0..74de3f6e0 100644 --- a/docs/usage/danger-process.html.md +++ b/docs/usage/danger-process.html.md @@ -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. @@ -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 @@ -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]: diff --git a/source/ci_source/providers/Fake.ts b/source/ci_source/providers/Fake.ts index e62006e0e..d491c2796 100644 --- a/source/ci_source/providers/Fake.ts +++ b/source/ci_source/providers/Fake.ts @@ -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 } diff --git a/source/ci_source/providers/index.ts b/source/ci_source/providers/index.ts index 186fd22eb..71d7df917 100644 --- a/source/ci_source/providers/index.ts +++ b/source/ci_source/providers/index.ts @@ -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, diff --git a/source/commands/utils/runDangerSubprocess.ts b/source/commands/utils/runDangerSubprocess.ts index 6ddd6c617..f27603761 100644 --- a/source/commands/utils/runDangerSubprocess.ts +++ b/source/commands/utils/runDangerSubprocess.ts @@ -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) { @@ -38,17 +42,28 @@ 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) @@ -56,7 +71,10 @@ export const runDangerSubprocess = ( const withoutURLs: string = data .toString() .replace(maybeJSON, "") + .replace(maybeJSONURL + "\n", "") .replace(maybeJSONURL, "") + .replace(messageToSendDSL + "\n", "") + .replace(messageToSendDSL, "") console.log(withoutURLs) diff --git a/source/platforms/platform.ts b/source/platforms/platform.ts index b1a37eb87..881fd998e 100644 --- a/source/platforms/platform.ts +++ b/source/platforms/platform.ts @@ -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 @@ -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.")