diff --git a/docs/local-development.md b/docs/local-development.md index ee25e1ca2c44aa93e9a6cae8dd30ce9299c1b01c..e81a97743eb69f6a073b3b94b45b1fe7cf4f21ba 100644 --- a/docs/local-development.md +++ b/docs/local-development.md @@ -42,10 +42,7 @@ Once you have decided on your platform and account, log in and [generate a "Pers #### Export platform token Although you can specify a token to Renovate using `--token=`, it can be inconvenient if you need to include this every time. -You are better off to instead export an Environment Variable for this. - -If your platform of choice is GitHub, then export `GITHUB_TOKEN`, and if it's GitLab then export `GITLAB_TOKEN`. -It's also find to export both so that you can switch between platforms. +You are better off to instead export the Environment Variable `RENOVATE_TOKEN` for this. #### Run against a real repo diff --git a/docs/self-hosting.md b/docs/self-hosting.md index 830271754a8bf5b25794336371f14f727aea3239..e9aef69cb69c0dcb3330c47e0a9063f62dbe3ffb 100644 --- a/docs/self-hosting.md +++ b/docs/self-hosting.md @@ -117,22 +117,9 @@ You can find instructions for VSTS [vsts](https://www.visualstudio.com/en-us/docs/integrate/get-started/authentication/pats). This token needs to be configured via file, environment variable, or CLI. See -[docs/configuration.md](configuration.md) for details. The simplest way is -to expose it as `GITHUB_TOKEN`, `GITLAB_TOKEN` or `VSTS_TOKEN`. +[docs/configuration.md](configuration.md) for details. The simplest way is to expose it as `RENOVATE_TOKEN`. -For Bitbucket, you can configure `BITBUCKET_USERNAME` and `BITBUCKET_PASSWORD`, or combine them together yourself into `BITBUCKET_TOKEN` using the node REPL: - -``` -const btoa = str => Buffer.from(str, 'binary').toString('base64'); - -btoa(`${user}:${bbaAppPassword}`) -``` - -You must then expose either the token or username + password to your env, or provide them via the CLI. Example: - -```sh -renovate --platform=bitbucket --username=rarkins --password=ABCDEFghijklmop123 rarkins/testrepo1 -``` +For Bitbucket, you can configure `RENOVATE_USERNAME` and `RENOVATE_PASSWORD`. ## Usage @@ -171,15 +158,14 @@ Most people will run Renovate via cron, e.g. once per hour. Here is an example b export PATH="/home/user/.yarn/bin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH" export RENOVATE_CONFIG_FILE="/home/user/renovate-config.js" -export GITHUB_TOKEN="**github-token**" # Delete this if using GitHub Enterprise -export GITLAB_TOKEN="**github-token**" # Delete this if using GitHub -export GITHUB_COM_TOKEN="**github-token**" # Delete this if using GitLab or github.com +export RENOVATE_TOKEN="**some-token**" # GitHub, GitLab, Azure DevOps or BitBucket +export GITHUB_COM_TOKEN="**github-token**" # Delete this if using github.com # Renovate renovate ``` -Note: the GitHub token in env is necessary in order to retrieve Release Notes that are hosted on github.com. Use `GITHUB_COM_TOKEN` if running against GitHub Enterprise or `GITHUB_TOKEN` if running against GitLab. i.e. remove one of the lines as applicable. +Note: the GitHub.com token in env is necessary in order to retrieve Release Notes that are usually hosted on github.com. You don't need to add it if you are already running the bot against github.com, but you do need to add it if you're using GitHub Enterprise, GitLab, Azure DevOps, or Bitbucket. You should save and test out this script manually first, and add it to cron once you've verified it. diff --git a/lib/config/env.js b/lib/config/env.js index 18fe9162169491f0e04e1f6ca472a93d0b978329..d60fa36a87028bdabcd3d8f0b9c86ca89a78a11e 100644 --- a/lib/config/env.js +++ b/lib/config/env.js @@ -39,16 +39,7 @@ function getConfig(env) { } }); - if (env.GITHUB_TOKEN && env.GITHUB_TOKEN !== 'dummy') { - config.hostRules.push({ - platform: 'github', - endpoint: env.GITHUB_ENDPOINT, - token: env.GITHUB_TOKEN, - default: true, - }); - } - - if (env.GITHUB_COM_TOKEN && env.GITHUB_TOKEN !== 'dummy') { + if (env.GITHUB_COM_TOKEN) { config.hostRules.push({ endpoint: 'https://api.github.com/', platform: 'github', @@ -56,37 +47,6 @@ function getConfig(env) { }); } - if (env.GITLAB_TOKEN) { - config.hostRules.push({ - platform: 'gitlab', - endpoint: env.GITLAB_ENDPOINT, - token: env.GITLAB_TOKEN, - }); - } - - if (env.BITBUCKET_TOKEN) { - config.hostRules.push({ - platform: 'bitbucket', - endpoint: env.BITBUCKET_ENDPOINT, - token: env.BITBUCKET_TOKEN, - }); - } else if (env.BITBUCKET_USERNAME && env.BITBUCKET_PASSWORD) { - const base64 = str => Buffer.from(str, 'binary').toString('base64'); - config.hostRules.push({ - platform: 'bitbucket', - endpoint: env.BITBUCKET_ENDPOINT, - token: base64(`${env.BITBUCKET_USERNAME}:${env.BITBUCKET_PASSWORD}`), - }); - } - - if (env.VSTS_ENDPOINT || env.VSTS_TOKEN) { - config.hostRules.push({ - platform: 'vsts', - endpoint: env.VSTS_ENDPOINT, - token: env.VSTS_TOKEN, - }); - } - if (env.DOCKER_USERNAME && env.DOCKER_PASSWORD) { config.hostRules.push({ platform: 'docker', @@ -95,23 +55,20 @@ function getConfig(env) { }); } - if (config.platform === 'gitlab') { - config.endpoint = env.GITLAB_ENDPOINT; - } else if (config.platform === 'vsts') { - config.endpoint = env.VSTS_ENDPOINT; - } else if (env.GITHUB_ENDPOINT) { - // GitHub is default - config.endpoint = env.GITHUB_ENDPOINT; - } - - /* eslint-disable no-param-reassign */ - delete env.GITHUB_TOKEN; - delete env.GITHUB_ENDPOINT; - delete env.GITHUB_COM_TOKEN; - delete env.GITLAB_TOKEN; - delete env.GITLAB_ENDPOINT; - delete env.VSTS_TOKEN; - delete env.VSTS_ENDPOINT; + // These env vars are deprecated and deleted to make sure they're not used + const unsupportedEnv = [ + 'BITBUCKET_TOKEN', + 'BITBUCKET_USERNAME', + 'BITBUCKET_PASSWORD', + 'GITHUB_ENDPOINT', + 'GITHUB_TOKEN', + 'GITLAB_ENDPOINT', + 'GITLAB_TOKEN', + 'VSTS_ENDPOINT', + 'VSTS_TOKEN', + ]; + // eslint-disable-next-line no-param-reassign + unsupportedEnv.forEach(val => delete env[val]); return config; } diff --git a/lib/config/index.js b/lib/config/index.js index a7713b96e6d52669107eb78e40e9e4e64552b9ee..eeb7722067a7bc67316ae852a266ce7489ff1d84 100644 --- a/lib/config/index.js +++ b/lib/config/index.js @@ -83,12 +83,31 @@ async function parseConfigs(env, argv) { // Get global config logger.trace({ config }, 'Full config'); - // Check platforms and tokens - const { platform, endpoint, username, password, token } = config; + // Check platform and authentication + const { platform, username, password } = config; const platformInfo = hostRules.defaults[platform]; if (!platformInfo) { throw new Error(`Unsupported platform: ${config.platform}.`); } + const endpoint = config.endpoint || platformInfo.endpoint; + let token = config.token; + if (!token) { + if (username && password) { + const base64 = str => Buffer.from(str, 'binary').toString('base64'); + token = base64(`${username}:${password}`); + } else { + throw new Error( + `No authentication found for platform ${endpoint} (${platform})` + ); + } + } + config.hostRules.push({ + platform, + endpoint, + username, + password, + token, + }); config.hostRules.forEach(hostRules.update); delete config.hostRules; delete config.token; @@ -104,21 +123,7 @@ async function parseConfigs(env, argv) { } ); - if ( - platform === 'bitbucket' && - !credentials.token && - (username && password) - ) { - logger.debug('Found configured username && password'); - const base64 = str => Buffer.from(str, 'binary').toString('base64'); - credentials.token = base64(`${username}:${password}`); - } - if (!global.appMode) { - if (!credentials.token) { - throw new Error(`You need to supply a ${platformInfo.name} token.`); - } - hostRules.update({ ...credentials, default: true, diff --git a/test/config/__snapshots__/env.spec.js.snap b/test/config/__snapshots__/env.spec.js.snap index bfe82efcf2d739f6c52c742ef8ba769ca042979b..219281be7b6f2e567ca28f884d5347f018f44288 100644 --- a/test/config/__snapshots__/env.spec.js.snap +++ b/test/config/__snapshots__/env.spec.js.snap @@ -2,27 +2,21 @@ exports[`config/env .getConfig(env) supports Bitbucket token 1`] = ` Object { - "hostRules": Array [ - Object { - "endpoint": "a bitbucket endpoint", - "platform": "bitbucket", - "token": "a bitbucket token", - }, - ], + "endpoint": "a bitbucket endpoint", + "hostRules": Array [], + "password": "app-password", "platform": "bitbucket", + "username": "some-username", } `; exports[`config/env .getConfig(env) supports Bitbucket username/password 1`] = ` Object { - "hostRules": Array [ - Object { - "endpoint": "a bitbucket endpoint", - "platform": "bitbucket", - "token": "c29tZS11c2VybmFtZTphcHAtcGFzc3dvcmQ=", - }, - ], + "endpoint": "a bitbucket endpoint", + "hostRules": Array [], + "password": "app-password", "platform": "bitbucket", + "username": "some-username", } `; @@ -37,97 +31,46 @@ exports[`config/env .getConfig(env) supports GitHub custom endpoint and github.c Object { "endpoint": "a ghe endpoint", "hostRules": Array [ - Object { - "default": true, - "endpoint": "a ghe endpoint", - "platform": "github", - "token": "a ghe token", - }, Object { "endpoint": "https://api.github.com/", "platform": "github", "token": "a github.com token", }, ], -} -`; - -exports[`config/env .getConfig(env) supports GitHub custom endpoint and github.com and gitlab.com 1`] = ` -Object { - "endpoint": "a ghe endpoint", - "hostRules": Array [ - Object { - "default": true, - "endpoint": "a ghe endpoint", - "platform": "github", - "token": "a ghe token", - }, - Object { - "endpoint": "https://api.github.com/", - "platform": "github", - "token": "a github.com token", - }, - Object { - "endpoint": undefined, - "platform": "gitlab", - "token": "a gitlab token", - }, - ], + "token": "a ghe token", } `; exports[`config/env .getConfig(env) supports GitHub token 1`] = ` Object { - "hostRules": Array [ - Object { - "default": true, - "endpoint": undefined, - "platform": "github", - "token": "github.com token", - }, - ], + "hostRules": Array [], + "token": "github.com token", } `; exports[`config/env .getConfig(env) supports GitLab custom endpoint 1`] = ` Object { "endpoint": "a gitlab endpoint", - "hostRules": Array [ - Object { - "endpoint": "a gitlab endpoint", - "platform": "gitlab", - "token": "a gitlab token", - }, - ], + "hostRules": Array [], "platform": "gitlab", + "token": "a gitlab token", } `; exports[`config/env .getConfig(env) supports GitLab token 1`] = ` Object { - "endpoint": undefined, - "hostRules": Array [ - Object { - "endpoint": undefined, - "platform": "gitlab", - "token": "a gitlab.com token", - }, - ], + "hostRules": Array [], "platform": "gitlab", + "token": "a gitlab.com token", } `; exports[`config/env .getConfig(env) supports VSTS 1`] = ` Object { "endpoint": "a vsts endpoint", - "hostRules": Array [ - Object { - "endpoint": "a vsts endpoint", - "platform": "vsts", - "token": "a vsts token", - }, - ], + "hostRules": Array [], "platform": "vsts", + "token": "a vsts token", } `; diff --git a/test/config/env.spec.js b/test/config/env.spec.js index e62472d3901970932a2d13df28e6a078a6edcfbf..0ed3d0e44b3ea27ab1b120f220ea4fc3e544015d 100644 --- a/test/config/env.spec.js +++ b/test/config/env.spec.js @@ -35,50 +35,41 @@ describe('config/env', () => { expect(env.getConfig(envParam).lockFileMaintenance).toEqual({}); }); it('supports GitHub token', () => { - const envParam = { GITHUB_TOKEN: 'github.com token' }; + const envParam = { RENOVATE_TOKEN: 'github.com token' }; expect(env.getConfig(envParam)).toMatchSnapshot(); }); it('supports GitHub custom endpoint', () => { - const envParam = { GITHUB_ENDPOINT: 'a ghe endpoint' }; + const envParam = { RENOVATE_ENDPOINT: 'a ghe endpoint' }; expect(env.getConfig(envParam)).toMatchSnapshot(); }); it('supports GitHub custom endpoint and github.com', () => { const envParam = { GITHUB_COM_TOKEN: 'a github.com token', - GITHUB_ENDPOINT: 'a ghe endpoint', - GITHUB_TOKEN: 'a ghe token', - }; - expect(env.getConfig(envParam)).toMatchSnapshot(); - }); - it('supports GitHub custom endpoint and github.com and gitlab.com', () => { - const envParam = { - GITHUB_COM_TOKEN: 'a github.com token', - GITHUB_ENDPOINT: 'a ghe endpoint', - GITHUB_TOKEN: 'a ghe token', - GITLAB_TOKEN: 'a gitlab token', + RENOVATE_ENDPOINT: 'a ghe endpoint', + RENOVATE_TOKEN: 'a ghe token', }; expect(env.getConfig(envParam)).toMatchSnapshot(); }); it('supports GitLab token', () => { const envParam = { RENOVATE_PLATFORM: 'gitlab', - GITLAB_TOKEN: 'a gitlab.com token', + RENOVATE_TOKEN: 'a gitlab.com token', }; expect(env.getConfig(envParam)).toMatchSnapshot(); }); it('supports GitLab custom endpoint', () => { const envParam = { RENOVATE_PLATFORM: 'gitlab', - GITLAB_TOKEN: 'a gitlab token', - GITLAB_ENDPOINT: 'a gitlab endpoint', + RENOVATE_TOKEN: 'a gitlab token', + RENOVATE_ENDPOINT: 'a gitlab endpoint', }; expect(env.getConfig(envParam)).toMatchSnapshot(); }); it('supports VSTS', () => { const envParam = { RENOVATE_PLATFORM: 'vsts', - VSTS_TOKEN: 'a vsts token', - VSTS_ENDPOINT: 'a vsts endpoint', + RENOVATE_TOKEN: 'a vsts token', + RENOVATE_ENDPOINT: 'a vsts endpoint', }; expect(env.getConfig(envParam)).toMatchSnapshot(); }); @@ -92,19 +83,18 @@ describe('config/env', () => { it('supports Bitbucket token', () => { const envParam = { RENOVATE_PLATFORM: 'bitbucket', - BITBUCKET_TOKEN: 'a bitbucket token', - BITBUCKET_ENDPOINT: 'a bitbucket endpoint', - BITBUCKET_USERNAME: 'some-username', - BITBUCKET_PASSWORD: 'app-password', + RENOVATE_ENDPOINT: 'a bitbucket endpoint', + RENOVATE_USERNAME: 'some-username', + RENOVATE_PASSWORD: 'app-password', }; expect(env.getConfig(envParam)).toMatchSnapshot(); }); it('supports Bitbucket username/password', () => { const envParam = { RENOVATE_PLATFORM: 'bitbucket', - BITBUCKET_ENDPOINT: 'a bitbucket endpoint', - BITBUCKET_USERNAME: 'some-username', - BITBUCKET_PASSWORD: 'app-password', + RENOVATE_ENDPOINT: 'a bitbucket endpoint', + RENOVATE_USERNAME: 'some-username', + RENOVATE_PASSWORD: 'app-password', }; expect(env.getConfig(envParam)).toMatchSnapshot(); }); diff --git a/test/config/index.spec.js b/test/config/index.spec.js index b7d41362a445451cdbc6acf79e58276cd6271765..a1f83b43bbf8442c9535614cdf137ad6450358c2 100644 --- a/test/config/index.spec.js +++ b/test/config/index.spec.js @@ -52,7 +52,9 @@ describe('config/index', () => { } catch (e) { err = e; } - expect(err.message).toBe('You need to supply a GitHub token.'); + expect(err.message).toBe( + 'No authentication found for platform https://api.github.com/ (github)' + ); }); it('throws for no GitLab token', async () => { const env = { RENOVATE_PLATFORM: 'gitlab' }; @@ -62,7 +64,9 @@ describe('config/index', () => { } catch (e) { err = e; } - expect(err.message).toBe('You need to supply a GitLab token.'); + expect(err.message).toBe( + 'No authentication found for platform https://gitlab.com/api/v4/ (gitlab)' + ); }); it('throws for no vsts token', async () => { const env = { RENOVATE_PLATFORM: 'vsts' }; @@ -72,10 +76,12 @@ describe('config/index', () => { } catch (e) { err = e; } - expect(err.message).toBe('You need to supply a VSTS token.'); + expect(err.message).toBe( + 'No authentication found for platform undefined (vsts)' + ); }); it('supports token in env', async () => { - const env = { GITHUB_TOKEN: 'abc' }; + const env = { RENOVATE_TOKEN: 'abc' }; await configParser.parseConfigs(env, defaultArgv); }); it('supports token in CLI options', async () => { @@ -85,7 +91,7 @@ describe('config/index', () => { }); it('supports forceCli', async () => { defaultArgv = defaultArgv.concat(['--force-cli=true']); - const env = { GITHUB_TOKEN: 'abc' }; + const env = { RENOVATE_TOKEN: 'abc' }; await configParser.parseConfigs(env, defaultArgv); }); it('supports Bitbucket username/passwod', async () => { @@ -173,7 +179,7 @@ describe('config/index', () => { expect(vstsApi.gitApi.mock.calls.length).toBe(1); }); it('logs if no autodiscovered repositories', async () => { - const env = { GITHUB_TOKEN: 'abc' }; + const env = { RENOVATE_TOKEN: 'abc' }; defaultArgv = defaultArgv.concat(['--autodiscover']); ghGot.mockImplementationOnce(() => ({ headers: {}, @@ -208,7 +214,7 @@ describe('config/index', () => { ).toMatchSnapshot(); }); it('adds a log file', async () => { - const env = { GITHUB_TOKEN: 'abc', RENOVATE_LOG_FILE: 'debug.log' }; + const env = { RENOVATE_TOKEN: 'abc', RENOVATE_LOG_FILE: 'debug.log' }; defaultArgv = defaultArgv.concat(['--autodiscover']); ghGot.mockImplementationOnce(() => ({ headers: {}, @@ -221,7 +227,7 @@ describe('config/index', () => { it('resolves all presets', async () => { defaultArgv.push('--pr-hourly-limit=10', '--automerge=false'); const env = { - GITHUB_TOKEN: 'abc', + RENOVATE_TOKEN: 'abc', RENOVATE_CONFIG_FILE: require.resolve( '../_fixtures/config/file-with-repo-presets.js' ), diff --git a/test/platform/github/index.spec.js b/test/platform/github/index.spec.js index 7d07145af2efa21edb12291e663df0d33ca7744d..af301ed9f765702767bc92232b340bd8bb3d3301 100644 --- a/test/platform/github/index.spec.js +++ b/test/platform/github/index.spec.js @@ -82,7 +82,7 @@ describe('platform/github', () => { ].forEach(([envToken, token, endpoint], i) => { it(`should initialise the config for the repo - ${i}`, async () => { if (envToken !== undefined) { - process.env.GITHUB_TOKEN = envToken; + process.env.RENOVATE_TOKEN = envToken; } const config = await initRepo({ repository: 'some/repo', diff --git a/test/platform/gitlab/index.spec.js b/test/platform/gitlab/index.spec.js index 6269424b1b7f8f9077143671ad45f2ee227fcbba..c30baa3a15bb87626a97b4187c3361e03ba715eb 100644 --- a/test/platform/gitlab/index.spec.js +++ b/test/platform/gitlab/index.spec.js @@ -106,7 +106,7 @@ describe('platform/gitlab', () => { ].forEach(([envToken, token, endpoint, gitAuthor], i) => { it(`should initialise the config for the repo - ${i}`, async () => { if (envToken !== undefined) { - process.env.GITLAB_TOKEN = envToken; + process.env.RENOVATE_TOKEN = envToken; } get.mockReturnValue({ body: [] }); const config = await initRepo({