From 51283c06ec0157aae5c2901b7ae71c05cf3274a0 Mon Sep 17 00:00:00 2001 From: Maximilian Stoiber Date: Mon, 19 Mar 2018 09:55:19 +0100 Subject: [PATCH 01/14] Add `reset-status` command Adds a new command to set the PR status to "pending" at the beginning of a CI run. --- package.json | 3 ++- source/commands/ci/reset-status.ts | 36 ++++++++++++++++++++++++++ source/commands/danger-reset-status.ts | 12 +++++++++ source/commands/danger.ts | 1 + source/platforms/GitHub.ts | 2 +- source/platforms/platform.ts | 2 +- 6 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 source/commands/ci/reset-status.ts create mode 100644 source/commands/danger-reset-status.ts diff --git a/package.json b/package.json index dea481263..dfd62a010 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "danger-process": "distribution/commands/danger-process.js", "danger-ci": "distribution/commands/danger-ci.js", "danger-init": "distribution/commands/danger-init.js", - "danger-local": "distribution/commands/danger-local.js" + "danger-local": "distribution/commands/danger-local.js", + "danger-reset-status": "distribution/commands/danger-reset-status.js" }, "jest": { "transform": { diff --git a/source/commands/ci/reset-status.ts b/source/commands/ci/reset-status.ts new file mode 100644 index 000000000..90cc4939f --- /dev/null +++ b/source/commands/ci/reset-status.ts @@ -0,0 +1,36 @@ +import chalk from "chalk" +import * as debug from "debug" + +import { getPlatformForEnv } from "../../platforms/platform" +import { SharedCLI } from "../utils/sharedDangerfileArgs" +import getRuntimeCISource from "../utils/getRuntimeCISource" + +import { RunnerConfig } from "./runner" + +const d = debug("danger:reset-status") + +export const runRunner = async (app: SharedCLI, config?: RunnerConfig) => { + d(`Starting sub-process run with ${app.args}`) + const source = (config && config.source) || (await getRuntimeCISource(app)) + + // This does not set a failing exit code + if (source && !source.isPR) { + console.log("Skipping Danger due to this run not executing on a PR.") + } + + // The optimal path + if (source && source.isPR) { + const platform = (config && config.platform) || getPlatformForEnv(process.env, source) + if (!platform) { + console.log(chalk.red(`Could not find a source code hosting platform for ${source.name}.`)) + console.log( + `Currently Danger JS only supports GitHub, if you want other platforms, consider the Ruby version or help out.` + ) + process.exitCode = 1 + } + + if (platform) { + await platform.updateStatus("pending", "Danger is waiting for your CI run to complete...") + } + } +} diff --git a/source/commands/danger-reset-status.ts b/source/commands/danger-reset-status.ts new file mode 100644 index 000000000..51e48d2d1 --- /dev/null +++ b/source/commands/danger-reset-status.ts @@ -0,0 +1,12 @@ +#! /usr/bin/env node + +import * as program from "commander" + +import setSharedArgs, { SharedCLI } from "./utils/sharedDangerfileArgs" +import { runRunner } from "./ci/runner" + +program.usage("[options]").description("Reset the status of a GitHub PR to pending.") +setSharedArgs(program).parse(process.argv) + +const app = (program as any) as SharedCLI +runRunner(app) diff --git a/source/commands/danger.ts b/source/commands/danger.ts index a6b947577..efcfd7084 100644 --- a/source/commands/danger.ts +++ b/source/commands/danger.ts @@ -19,6 +19,7 @@ program .command("pr", "Runs your local Dangerfile against an existing GitHub PR. Will not post on the PR") .command("runner", "Runs a dangerfile against a DSL passed in via STDIN [You probably don't need this]") .command("local", "Runs danger standalone on a repo, useful for git hooks") + .command("reset-status", "Set the status of a PR to pending when a new CI run starts") .on("--help", () => { console.log("\n") console.log(" Docs:") diff --git a/source/platforms/GitHub.ts b/source/platforms/GitHub.ts index 320e58595..b1de6ac83 100644 --- a/source/platforms/GitHub.ts +++ b/source/platforms/GitHub.ts @@ -44,7 +44,7 @@ export class GitHub implements Platform { * then return true. */ - updateStatus = async (passed: boolean, message: string, url?: string): Promise => { + updateStatus = async (passed: boolean | "pending", message: string, url?: string): Promise => { const ghAPI = this.api.getExternalAPI() const prJSON = await this.api.getPullRequestInfo() diff --git a/source/platforms/platform.ts b/source/platforms/platform.ts index 9e66615ab..900602bbb 100644 --- a/source/platforms/platform.ts +++ b/source/platforms/platform.ts @@ -46,7 +46,7 @@ export interface Platform { /** Replace the main Danger comment */ updateOrCreateComment: (dangerID: string, newComment: string) => Promise /** Sets the current PR's status */ - updateStatus: (passed: boolean, message: string, url?: string) => Promise + updateStatus: (passed: boolean | "pending", message: string, url?: string) => Promise /** Get the contents of a file at a path */ getFileContents: (path: string, slug?: string, ref?: string) => Promise } From 9d348308db285896cc254cda70d55629ee0efb13 Mon Sep 17 00:00:00 2001 From: Maximilian Stoiber Date: Mon, 19 Mar 2018 09:57:48 +0100 Subject: [PATCH 02/14] Add changelog entry --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d35a57101..f9d8057d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ ## Master -* [] +* Add `reset-status` command [@mxstbr][] ## 3.2.0 @@ -963,4 +963,5 @@ Not usable for others, only stubs of classes etc. - [@orta][] [@peterjgrainger]: https://github.com/peterjgrainger [@azz]: https://github.com/azz [@mifi]: https://github.com/ionutmiftode +[@mxstbr]: https://github.com/mxstbr [ref]: http://danger.systems/js/reference.html From ddde5e2dd9482e0eb7e8ac0a27134e7645af9640 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zden=C4=9Bk=20Topi=C4=8D?= Date: Tue, 20 Mar 2018 10:10:32 +0100 Subject: [PATCH 03/14] Fix committer for Stash REST API --- source/platforms/bitbucket_server/BitBucketServerGit.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/platforms/bitbucket_server/BitBucketServerGit.ts b/source/platforms/bitbucket_server/BitBucketServerGit.ts index 5c61ee75c..19cf75b2e 100644 --- a/source/platforms/bitbucket_server/BitBucketServerGit.ts +++ b/source/platforms/bitbucket_server/BitBucketServerGit.ts @@ -35,11 +35,11 @@ function bitBucketServerCommitToGitCommit( name: bbsCommit.author.name, date: new Date(bbsCommit.authorTimestamp).toISOString(), }, - committer: { + committer: bbsCommit.committe ? { email: bbsCommit.committer.emailAddress, name: bbsCommit.committer.name, date: new Date(bbsCommit.committerTimestamp).toISOString(), - }, + } : null, message: bbsCommit.message, tree: null, url, From c9f7620530897cb0e2b3caf8e13e71c4b000e9d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zden=C4=9Bk=20Topi=C4=8D?= Date: Tue, 20 Mar 2018 10:22:08 +0100 Subject: [PATCH 04/14] typo --- source/platforms/bitbucket_server/BitBucketServerGit.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/platforms/bitbucket_server/BitBucketServerGit.ts b/source/platforms/bitbucket_server/BitBucketServerGit.ts index 19cf75b2e..dd79519d7 100644 --- a/source/platforms/bitbucket_server/BitBucketServerGit.ts +++ b/source/platforms/bitbucket_server/BitBucketServerGit.ts @@ -35,7 +35,7 @@ function bitBucketServerCommitToGitCommit( name: bbsCommit.author.name, date: new Date(bbsCommit.authorTimestamp).toISOString(), }, - committer: bbsCommit.committe ? { + committer: bbsCommit.committer ? { email: bbsCommit.committer.emailAddress, name: bbsCommit.committer.name, date: new Date(bbsCommit.committerTimestamp).toISOString(), From c8d434d0c8765696dcc6acb5c91d8a13265836f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zden=C4=9Bk=20Topi=C4=8D?= Date: Tue, 20 Mar 2018 10:27:22 +0100 Subject: [PATCH 05/14] put author instead of committer --- source/platforms/bitbucket_server/BitBucketServerGit.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source/platforms/bitbucket_server/BitBucketServerGit.ts b/source/platforms/bitbucket_server/BitBucketServerGit.ts index dd79519d7..91a028fc9 100644 --- a/source/platforms/bitbucket_server/BitBucketServerGit.ts +++ b/source/platforms/bitbucket_server/BitBucketServerGit.ts @@ -39,7 +39,11 @@ function bitBucketServerCommitToGitCommit( email: bbsCommit.committer.emailAddress, name: bbsCommit.committer.name, date: new Date(bbsCommit.committerTimestamp).toISOString(), - } : null, + } : { + email: bbsCommit.author.emailAddress, + name: bbsCommit.author.name, + date: new Date(bbsCommit.authorTimestamp).toISOString(), + }, message: bbsCommit.message, tree: null, url, From 7f27424c0e868edf86982f6d89abe8fa113f7aff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zden=C4=9Bk=20Topi=C4=8D?= Date: Tue, 20 Mar 2018 12:54:04 +0100 Subject: [PATCH 06/14] CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d35a57101..d9143328f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ ## Master -* [] +* Fix `committer` field issue - missing in Stash API. [@zdenektopic][] ## 3.2.0 From b11291ea6065a3a294cfafe5d83ec85e9993a2f7 Mon Sep 17 00:00:00 2001 From: Orta Therox Date: Tue, 20 Mar 2018 08:37:50 -0400 Subject: [PATCH 07/14] Version bump --- CHANGELOG.md | 12 ++++++++++-- package.json | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30116d528..147030631 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,8 +13,16 @@ ## Master -* Fix `committer` field issue - missing in Stash API. [@zdenektopic][] -* Add `reset-status` command [@mxstbr][] +## 3.3.0 + +* Fix `committer` field issue - missing in Stash API by using commit author instead. [@zdenektopic][] +* Adds a new command: `reset-status` + + This command is for setting the CI build status in advance of running Danger. If your Danger build relies + on running tests/linters, then you might want to set the PR status (the red/green/yellow dots) to pending + at the start of your build. You can do this by running `yarn danger reset-status`. + + [@mxstbr][] ## 3.2.0 diff --git a/package.json b/package.json index dfd62a010..172e6eee8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "danger", - "version": "3.2.0", + "version": "3.3.0", "description": "Unit tests for Team Culture", "main": "distribution/danger.js", "typings": "distribution/danger.d.ts", From 5a680314279114ed2ea963007b8f3f03bfd71f16 Mon Sep 17 00:00:00 2001 From: Frederik Wallner Date: Tue, 20 Mar 2018 20:54:18 +0100 Subject: [PATCH 08/14] Support for TeamCity --- source/ci_source/providers/TeamCity.ts | 59 ++++++++++++++++ .../providers/_tests/_teamcity.test.ts | 68 +++++++++++++++++++ source/ci_source/providers/index.ts | 3 + 3 files changed, 130 insertions(+) create mode 100644 source/ci_source/providers/TeamCity.ts create mode 100644 source/ci_source/providers/_tests/_teamcity.test.ts diff --git a/source/ci_source/providers/TeamCity.ts b/source/ci_source/providers/TeamCity.ts new file mode 100644 index 000000000..58fe98d6f --- /dev/null +++ b/source/ci_source/providers/TeamCity.ts @@ -0,0 +1,59 @@ +import { Env, CISource } from "../ci_source" +import { ensureEnvKeysExist } from "../ci_source_helpers" + +/** + * + * ### CI Setup + * + * You need to add `DANGER_GITHUB_API_TOKEN` to the ENV for the build or machine manually. + * Then you also need to figure out how to provide the URL for the pull request in `PULL_REQUEST_URL` ENV. + * + * TeamCity provides the `%teamcity.build.branch%` variable that contains something like `pull/123` that you can use: + * ```sh + * PULL_REQUEST_URL='https://github.com/dager/danger-js/%teamcity.build.branch%' + * ``` + * + */ + +export class TeamCity implements CISource { + constructor(private readonly env: Env) {} + + get name(): string { + return "TeamCity" + } + + get isCI(): boolean { + return ensureEnvKeysExist(this.env, ["TEAMCITY_VERSION"]) + } + + get isPR(): boolean { + if (ensureEnvKeysExist(this.env, ["PULL_REQUEST_URL"])) { + return true + } + + const mustHave = ["PULL_REQUEST_URL"] + return ensureEnvKeysExist(this.env, mustHave) + } + + private _prParseURL(): { owner?: string; reponame?: string; id?: string } { + const prUrl = this.env.PULL_REQUEST_URL || "" + const splitSlug = prUrl.split("/") + if (splitSlug.length === 7) { + const owner = splitSlug[3] + const reponame = splitSlug[4] + const id = splitSlug[6] + return { owner, reponame, id } + } + return {} + } + + get pullRequestID(): string { + const { id } = this._prParseURL() + return id || "" + } + + get repoSlug(): string { + const { owner, reponame } = this._prParseURL() + return owner && reponame ? `${owner}/${reponame}` : "" + } +} diff --git a/source/ci_source/providers/_tests/_teamcity.test.ts b/source/ci_source/providers/_tests/_teamcity.test.ts new file mode 100644 index 000000000..f454049ad --- /dev/null +++ b/source/ci_source/providers/_tests/_teamcity.test.ts @@ -0,0 +1,68 @@ +import { TeamCity } from "../TeamCity" +import { getCISourceForEnv } from "../../get_ci_source" + +const correctEnv = { + TEAMCITY_VERSION: "1.2.3", + PULL_REQUEST_URL: "https://github.com/danger/danger-js/pull/541", +} + +describe("being found when looking for CI", () => { + it("finds TeamCity with the right ENV", () => { + const ci = getCISourceForEnv(correctEnv) + expect(ci).toBeInstanceOf(TeamCity) + }) +}) + +describe(".isCI", () => { + it("validates when all TeamCity environment vars are set", () => { + const teamcity = new TeamCity(correctEnv) + expect(teamcity.isCI).toBeTruthy() + }) + + it("does not validate without env", () => { + const teamcity = new TeamCity({}) + expect(teamcity.isCI).toBeFalsy() + }) +}) + +describe(".isPR", () => { + it("validates when all TeamCity environment vars are set", () => { + const teamcity = new TeamCity(correctEnv) + expect(teamcity.isPR).toBeTruthy() + }) + + it("does not validate outside of TeamCity", () => { + const teamcity = new TeamCity({}) + expect(teamcity.isPR).toBeFalsy() + }) + + const envs = ["TEAMCITY_VERSION", "PULL_REQUEST_URL"] + envs.forEach((key: string) => { + let env = { + TEAMCITY_VERSION: "1.2.3", + PULL_REQUEST_URL: "https://github.com/danger/danger-js/pull/541", + } + env[key] = null + + it(`does not validate when ${key} is missing`, () => { + const teamcity = new TeamCity({}) + expect(teamcity.isPR).toBeFalsy() + }) + }) +}) + +describe(".pullRequestID", () => { + it("pulls it out of the env", () => { + const teamcity = new TeamCity({ + PULL_REQUEST_URL: "https://github.com/danger/danger-js/pull/541", + }) + expect(teamcity.pullRequestID).toEqual("541") + }) +}) + +describe(".repoSlug", () => { + it("derives it from the PR Url", () => { + const teamcity = new TeamCity(correctEnv) + expect(teamcity.repoSlug).toEqual("danger/danger-js") + }) +}) diff --git a/source/ci_source/providers/index.ts b/source/ci_source/providers/index.ts index c7b5ffb10..88121eb42 100644 --- a/source/ci_source/providers/index.ts +++ b/source/ci_source/providers/index.ts @@ -10,6 +10,7 @@ import { Jenkins } from "./Jenkins" import { Nevercode } from "./Nevercode" import { Semaphore } from "./Semaphore" import { Surf } from "./Surf" +import { TeamCity } from "./TeamCity" import { Travis } from "./Travis" import { VSTS } from "./VSTS" @@ -28,6 +29,7 @@ const providers = [ BuddyBuild, VSTS, Bitrise, + TeamCity, ] // Mainly used for Dangerfile linting @@ -44,6 +46,7 @@ const realProviders = [ Buildkite, BuddyBuild, VSTS, + TeamCity, ] export { providers, realProviders } From 4ab042dc6c41c907fa501b0aa15d0857f5a15008 Mon Sep 17 00:00:00 2001 From: Frederik Wallner Date: Tue, 20 Mar 2018 22:14:35 +0100 Subject: [PATCH 09/14] Updated changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 147030631..e53216495 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ ## Master +* Adds support for TeamCity as a CI provider. [@fwal][] + ## 3.3.0 * Fix `committer` field issue - missing in Stash API by using commit author instead. [@zdenektopic][] From 96971d10303cb7b9175392de7a72e18bdbf9f130 Mon Sep 17 00:00:00 2001 From: Frederik Wallner Date: Tue, 20 Mar 2018 22:36:41 +0100 Subject: [PATCH 10/14] Mention TeamCity in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 68565ea73..81a7319e2 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ This provides another logical step in your process, through which Danger can hel You can use Danger to codify your teams norms, leaving humans to think about harder problems. Danger JS currently works with GitHub or BitBucket Server and Travis CI, Circle CI, Semaphore, Jenkins, Docker Cloud, Bitrise, surf-build, -Codeship, Drone, Buildkite, Nevercode, buddybuild or Visual Studio Team Services. +Codeship, Drone, Buildkite, Nevercode, buddybuild, Visual Studio Team Services or TeamCity. [![npm](https://img.shields.io/npm/v/danger.svg)](https://www.npmjs.com/package/danger) [![Build Status](https://travis-ci.org/danger/danger-js.svg?branch=master)](https://travis-ci.org/danger/danger-js) [![Build Status](https://ci.appveyor.com/api/projects/status/ep5hgeox3lbc5c7f?svg=true)](https://ci.appveyor.com/project/orta/danger-js/branch/master) [![Join the community on Spectrum](https://withspectrum.github.io/badge/badge.svg)](https://spectrum.chat/danger) From 2874ae1aed0d26124ad485438e41a3f6c9063af9 Mon Sep 17 00:00:00 2001 From: Michiel Westerbeek Date: Wed, 21 Mar 2018 11:30:35 +0100 Subject: [PATCH 11/14] Changed null to undefined for sourceFileName and sourceMapTarget. Babel 7 returns errors for sourceFileName and sourceMapTarget because they are specified as null. Error: .sourceFileName must be a string, or undefined --- source/runner/runners/utils/transpiler.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/runner/runners/utils/transpiler.ts b/source/runner/runners/utils/transpiler.ts index 24dbf4a61..d84670e74 100644 --- a/source/runner/runners/utils/transpiler.ts +++ b/source/runner/runners/utils/transpiler.ts @@ -87,8 +87,8 @@ export const babelify = (content: string, filename: string, extraPlugins: string filename, filenameRelative: filename, sourceMap: false, - sourceFileName: null, - sourceMapTarget: null, + sourceFileName: undefined, + sourceMapTarget: undefined, sourceType: "module", plugins: [...extraPlugins, ...options.plugins], } From 6f6c1463d4f3b51c4f89f4800dfaac571d6d4f79 Mon Sep 17 00:00:00 2001 From: Michiel Westerbeek Date: Wed, 21 Mar 2018 12:03:15 +0100 Subject: [PATCH 12/14] Added changelog entry --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 147030631..d97e4d885 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ ## Master +* Fixed Babel 7 breaking because of sourceFileName being defined wrong. + + [@happylinks][] + ## 3.3.0 * Fix `committer` field issue - missing in Stash API by using commit author instead. [@zdenektopic][] @@ -973,4 +977,5 @@ Not usable for others, only stubs of classes etc. - [@orta][] [@azz]: https://github.com/azz [@mifi]: https://github.com/ionutmiftode [@mxstbr]: https://github.com/mxstbr +[@happylinks]: https://github.com/happylinks [ref]: http://danger.systems/js/reference.html From 98172b282494d146d21829d14a5b5731d50e11a7 Mon Sep 17 00:00:00 2001 From: Orta Therox Date: Wed, 21 Mar 2018 07:46:52 -0400 Subject: [PATCH 13/14] Prepare for release --- CHANGELOG.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d97e4d885..792522ec5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,9 +13,9 @@ ## Master -* Fixed Babel 7 breaking because of sourceFileName being defined wrong. +## 3.3.1 - [@happylinks][] +* Fixed Babel 7 breaking because of sourceFileName being defined wrong. [@happylinks][] ## 3.3.0 diff --git a/package.json b/package.json index 172e6eee8..dae2e25ff 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "danger", - "version": "3.3.0", + "version": "3.3.1", "description": "Unit tests for Team Culture", "main": "distribution/danger.js", "typings": "distribution/danger.d.ts", From 2cdbc6f1ffed5253c40639fc7ed7bd299347f949 Mon Sep 17 00:00:00 2001 From: Orta Therox Date: Wed, 21 Mar 2018 07:53:13 -0400 Subject: [PATCH 14/14] Prepare for release --- CHANGELOG.md | 3 +++ package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf6dabda8..dbfa0038c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ ## Master +## 3.3.2 + * Adds support for TeamCity as a CI provider. [@fwal][] ## 3.3.1 @@ -980,4 +982,5 @@ Not usable for others, only stubs of classes etc. - [@orta][] [@mifi]: https://github.com/ionutmiftode [@mxstbr]: https://github.com/mxstbr [@happylinks]: https://github.com/happylinks +[@fwal]: https://github.com/fwal [ref]: http://danger.systems/js/reference.html diff --git a/package.json b/package.json index dae2e25ff..83598c907 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "danger", - "version": "3.3.1", + "version": "3.3.2", "description": "Unit tests for Team Culture", "main": "distribution/danger.js", "typings": "distribution/danger.d.ts",