-
-
Notifications
You must be signed in to change notification settings - Fork 364
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #436 from danger/init_2
More work on danger init
- Loading branch information
Showing
10 changed files
with
283 additions
and
86 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
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
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
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
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,101 @@ | ||
import { InitUI, InitState, highlight } from "./interfaces" | ||
|
||
export const travis = async (ui: InitUI, state: InitState) => { | ||
// https://travis-ci.org/artsy/eigen/settings | ||
|
||
if (state.repoSlug) { | ||
const travisLink = ui.link( | ||
`Travis Settings for ${state.repoSlug}`, | ||
`https://travis-ci.org/${state.repoSlug}/settings` | ||
) | ||
ui.say("In order to add the environment variable, go to: " + travisLink) | ||
} else { | ||
const travisLink = ui.link("Travis Account profile", "https://travis-ci.org/profile/") | ||
ui.say("In order to add the environment variable, go to: " + travisLink) | ||
ui.say("And find the project for this repo, click the settings cog.") | ||
} | ||
|
||
ui.say( | ||
"The variable name is " + | ||
highlight("DANGER_GITHUB_API_TOKEN") + | ||
" and the value is the GitHub Personal Access Token you just created." | ||
) | ||
if (state.isAnOSSRepo) { | ||
ui.say('As you have an OSS repo - make sure to have "Display value in build log" enabled.') | ||
} | ||
|
||
ui.say("Next, you need to edit your `.travis.yml` to include `yarn danger`. If you already have") | ||
ui.say("a `script:` section then we recommend adding this command at the end of the script step: `- yarn danger`.\n") | ||
ui.say("Otherwise, add a `before_script` step to the root of the `.travis.yml` with `yarn danger`\n") | ||
|
||
ui.say(" ```yaml") | ||
ui.say(" before_script:") | ||
ui.say(" - yarn danger") | ||
ui.say(" ```\n") | ||
|
||
ui.say("Adding this to your `.travis.yml` allows Danger to fail your build.") | ||
ui.say("With that set up, you can edit your job to add `yarn danger` at the build action.") | ||
} | ||
|
||
export const circle = async (ui: InitUI, state: InitState) => { | ||
// https://circleci.com/gh/artsy/eigen/edit#env-vars | ||
const repo = state.repoSlug || "[Your_Repo]" | ||
if (state.isAnOSSRepo) { | ||
ui.say( | ||
"Before we start, it's important to be up-front. CircleCI only really has one option to support running Danger" | ||
) | ||
ui.say( | ||
"for forks on OSS repos. It is quite a drastic option, and I want to let you know the best place to understand" | ||
) | ||
ui.say("the ramifications of turning on a setting I'm about to advise.\n") | ||
ui.link("Circle CI: Fork PR builds", "https://circleci.com/docs/fork-pr-builds") | ||
ui.say( | ||
"TLDR: If you have anything other than Danger config settings in CircleCI, then you should not turn on this setting." | ||
) | ||
ui.say("I'll give you a minute to read it...") | ||
ui.waitForReturn() | ||
|
||
ui.say( | ||
"On danger/danger we turn on " + | ||
highlight("Permissive building of fork pull requests") + | ||
" this exposes the token to Danger" | ||
) | ||
const circleSettings = ui.link("Circle Settings", `https://circleci.com/gh/${repo}/edit#advanced-settings`) | ||
ui.say(`You can find this setting at: ${circleSettings}.`) | ||
ui.say("I'll hold...") | ||
ui.waitForReturn() | ||
} | ||
|
||
const circleSettings = ui.link("Circle Env Settings", `https://circleci.com/gh/${repo}/edit#env-vars`) | ||
ui.say(`In order to expose the environment variable, go to: ${circleSettings}`) | ||
|
||
ui.say("The name is " + highlight("DANGER_GITHUB_API_TOKEN") + " and the value is the GitHub Personal Access Token.") | ||
|
||
ui.say("With that set up, you can you add `yarn danger` to your `circle.yml`. If you override the default") | ||
ui.say("`test:` section, then add danger as an extra step. \nOtherwise add a new `pre` section to the test:\n") | ||
ui.say(" ``` ruby") | ||
ui.say(" test:") | ||
ui.say(" override:") | ||
ui.say(" - yarn danger") | ||
ui.say(" ```") | ||
} | ||
|
||
export const unsure = async (ui: InitUI, _state: InitState) => { | ||
ui.say( | ||
"You need to expose a token called " + | ||
highlight("DANGER_GITHUB_API_TOKEN") + | ||
" and the value is the GitHub Personal Access Token." | ||
) | ||
ui.say( | ||
"Depending on the CI system, this may need to be done on the machine (in the " + | ||
highlight("~/.bashprofile") + | ||
") or in a web UI somewhere." | ||
) | ||
ui.say("We have a guide for all supported CI systems on danger.systems:") | ||
ui.say( | ||
ui.link( | ||
"Danger Systems - Getting Started", | ||
"http://danger.systems/js/guides/getting_started.html#setting-up-danger-to-run-on-your-ci" | ||
) | ||
) | ||
} |
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
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,13 @@ | ||
import * as parseGitConfig from "parse-git-config" | ||
import * as parseGithubURL from "parse-github-url" | ||
|
||
export const getRepoSlug = () => { | ||
const config = parseGitConfig.sync() | ||
const possibleRemotes = [config['remote "upstream"'], config['remote "origin"']].filter(f => f) | ||
if (possibleRemotes.length === 0) { | ||
return null | ||
} | ||
|
||
const ghData = possibleRemotes.map(r => parseGithubURL(r.url))[0] | ||
return ghData.repo | ||
} |
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,33 @@ | ||
import * as chalk from "chalk" | ||
|
||
export interface InitState { | ||
filename: string | ||
botName: string | ||
|
||
isWindows: boolean | ||
isMac: boolean | ||
isBabel: boolean | ||
isTypeScript: boolean | ||
supportsHLinks: boolean | ||
|
||
isAnOSSRepo: boolean | ||
|
||
hasCreatedDangerfile: boolean | ||
hasSetUpAccount: boolean | ||
hasSetUpAccountToken: boolean | ||
|
||
repoSlug: string | null | ||
ciType: "travis" | "circle" | "unknown" | ||
} | ||
|
||
export interface InitUI { | ||
header: (msg: String) => void | ||
command: (command: string) => void | ||
say: (msg: String) => void | ||
pause: (secs: number) => Promise<{}> | ||
waitForReturn: () => void | ||
link: (name: string, href: string) => string | ||
askWithAnswers: (message: string, answers: string[]) => string | ||
} | ||
|
||
export const highlight = chalk.bold.yellow |
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,65 @@ | ||
import * as readlineSync from "readline-sync" | ||
import * as supportsHyperlinks from "supports-hyperlinks" | ||
import * as hyperLinker from "hyperlinker" | ||
import * as chalk from "chalk" | ||
|
||
import { basename } from "path" | ||
import { setTimeout } from "timers" | ||
import * as fs from "fs" | ||
|
||
import { getRepoSlug } from "./get-repo-slug" | ||
import { InitState, InitUI } from "./interfaces" | ||
|
||
export const createUI = (state: InitState, app: any): InitUI => { | ||
const say = (msg: String) => console.log(msg) | ||
const fancyLink = (name: string, href: string) => hyperLinker(name, href) | ||
const inlineLink = (_name: string, href: string) => chalk.underline(href) | ||
const linkToUse = state.supportsHLinks ? fancyLink : inlineLink | ||
|
||
return { | ||
say, | ||
header: (msg: String) => say(chalk.bold("\n## " + msg + "\n")), | ||
command: (command: string) => say("> " + chalk.white.bold(command) + " \n"), | ||
link: (name: string, href: string) => linkToUse(name, href), | ||
pause: async (secs: number) => new Promise(done => setTimeout(done, secs * 1000)), | ||
waitForReturn: () => (app.impatient ? Promise.resolve() : readlineSync.question("\n↵ ")), | ||
askWithAnswers: (_message: string, answers: string[]) => { | ||
const a = readlineSync.keyInSelect(answers, "", { defaultInput: answers[0] }) | ||
return answers[a] | ||
}, | ||
} | ||
} | ||
|
||
export const generateInitialState = (osProcess: NodeJS.Process): InitState => { | ||
const isMac = osProcess.platform === "darwin" | ||
const isWindows = osProcess.platform === "win32" | ||
const folderName = capitalizeFirstLetter(camelCase(basename(osProcess.cwd()))) | ||
const isTypeScript = checkForTypeScript() | ||
const isBabel = checkForBabel() | ||
const hasTravis = fs.existsSync(".travis.yml") | ||
const hasCircle = fs.existsSync("circle.yml") | ||
const ciType = hasTravis ? "travis" : hasCircle ? "circle" : "unknown" | ||
|
||
return { | ||
isMac, | ||
isWindows, | ||
isTypeScript, | ||
isBabel, | ||
isAnOSSRepo: true, | ||
supportsHLinks: supportsHyperlinks.stdout, | ||
filename: isTypeScript ? "Dangerfile.ts" : "Dangerfile.js", | ||
botName: folderName + "Bot", | ||
hasSetUpAccount: false, | ||
hasCreatedDangerfile: false, | ||
hasSetUpAccountToken: false, | ||
repoSlug: getRepoSlug(), | ||
ciType, | ||
} | ||
} | ||
|
||
const checkForTypeScript = () => fs.existsSync("node_modules/typescript/package.json") | ||
const checkForBabel = () => | ||
fs.existsSync("node_modules/babel-core/package.json") || fs.existsSync("node_modules/@babel/core/package.json") | ||
|
||
const capitalizeFirstLetter = (string: string) => string.charAt(0).toUpperCase() + string.slice(1) | ||
const camelCase = (str: string) => str.split("-").reduce((a, b) => a + b.charAt(0).toUpperCase() + b.slice(1)) |
Oops, something went wrong.