diff --git a/__tests__/lib/fetch.test.js b/__tests__/lib/fetch.test.js index bd6386089..a92c69236 100644 --- a/__tests__/lib/fetch.test.js +++ b/__tests__/lib/fetch.test.js @@ -6,50 +6,74 @@ const pkg = require('../../package.json'); describe('#fetch()', () => { describe('GitHub Actions environment', () => { + // List of all GitHub Actions env variables: + // https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables beforeEach(() => { process.env.GITHUB_ACTIONS = 'true'; + process.env.GITHUB_REPOSITORY = 'octocat/Hello-World'; + process.env.GITHUB_RUN_ATTEMPT = '3'; + process.env.GITHUB_RUN_ID = '1658821493'; + process.env.GITHUB_RUN_NUMBER = '3'; + process.env.GITHUB_SHA = 'ffac537e6cbbf934b08745a378932722df287a53'; }); afterEach(() => { delete process.env.GITHUB_ACTIONS; + delete process.env.GITHUB_REPOSITORY; + delete process.env.GITHUB_RUN_ATTEMPT; + delete process.env.GITHUB_RUN_ID; + delete process.env.GITHUB_RUN_NUMBER; + delete process.env.GITHUB_SHA; }); - it('should use correct user-agent for requests in GitHub Action env', async () => { + it('should have correct headers for requests in GitHub Action env', async () => { const key = 'API_KEY'; const mock = getApiNock() .get('/api/v1') .basicAuth({ user: key }) .reply(200, function () { - return this.req.headers['user-agent']; + return this.req.headers; }); - const userAgent = await fetch(`${config.get('host')}/api/v1`, { + const headers = await fetch(`${config.get('host')}/api/v1`, { method: 'get', headers: cleanHeaders(key), }).then(handleRes); - expect(userAgent.shift()).toBe(`rdme-github/${pkg.version}`); + expect(headers['user-agent'].shift()).toBe(`rdme-github/${pkg.version}`); + expect(headers['x-readme-source'].shift()).toBe('cli-gh'); + expect(headers['x-github-repository'].shift()).toBe('octocat/Hello-World'); + expect(headers['x-github-run-attempt'].shift()).toBe('3'); + expect(headers['x-github-run-id'].shift()).toBe('1658821493'); + expect(headers['x-github-run-number'].shift()).toBe('3'); + expect(headers['x-github-sha'].shift()).toBe('ffac537e6cbbf934b08745a378932722df287a53'); mock.done(); }); }); - it('should wrap all requests with a rdme User-Agent', async () => { + it('should wrap all requests with standard user-agent and source headers', async () => { const key = 'API_KEY'; const mock = getApiNock() .get('/api/v1') .basicAuth({ user: key }) .reply(200, function () { - return this.req.headers['user-agent']; + return this.req.headers; }); - const userAgent = await fetch(`${config.get('host')}/api/v1`, { + const headers = await fetch(`${config.get('host')}/api/v1`, { method: 'get', headers: cleanHeaders(key), }).then(handleRes); - expect(userAgent.shift()).toBe(`rdme/${pkg.version}`); + expect(headers['user-agent'].shift()).toBe(`rdme/${pkg.version}`); + expect(headers['x-readme-source'].shift()).toBe('cli'); + expect(headers['x-github-repository']).toBeUndefined(); + expect(headers['x-github-run-attempt']).toBeUndefined(); + expect(headers['x-github-run-id']).toBeUndefined(); + expect(headers['x-github-run-number']).toBeUndefined(); + expect(headers['x-github-sha']).toBeUndefined(); mock.done(); }); @@ -57,12 +81,18 @@ describe('#fetch()', () => { const mock = getApiNock() .get('/api/v1/doesnt-need-auth') .reply(200, function () { - return this.req.headers['user-agent']; + return this.req.headers; }); - const userAgent = await fetch(`${config.get('host')}/api/v1/doesnt-need-auth`).then(handleRes); + const headers = await fetch(`${config.get('host')}/api/v1/doesnt-need-auth`).then(handleRes); - expect(userAgent.shift()).toBe(`rdme/${pkg.version}`); + expect(headers['user-agent'].shift()).toBe(`rdme/${pkg.version}`); + expect(headers['x-readme-source'].shift()).toBe('cli'); + expect(headers['x-github-repository']).toBeUndefined(); + expect(headers['x-github-run-attempt']).toBeUndefined(); + expect(headers['x-github-run-id']).toBeUndefined(); + expect(headers['x-github-run-number']).toBeUndefined(); + expect(headers['x-github-sha']).toBeUndefined(); mock.done(); }); }); diff --git a/src/cmds/openapi.js b/src/cmds/openapi.js index 3db39a003..d9862d4db 100644 --- a/src/cmds/openapi.js +++ b/src/cmds/openapi.js @@ -138,7 +138,6 @@ module.exports = class OpenAPICommand { const options = { headers: cleanHeaders(key, { 'x-readme-version': versionCleaned, - 'x-readme-source': 'cli', Accept: 'application/json', }), body: formData, diff --git a/src/lib/fetch.js b/src/lib/fetch.js index 45a0a0d6b..69f747bf2 100644 --- a/src/lib/fetch.js +++ b/src/lib/fetch.js @@ -4,18 +4,33 @@ const pkg = require('../../package.json'); const APIError = require('./apiError'); /** - * Wrapper for the `fetch` API so we can add an rdme user agent to all API requests. + * Small env check to determine if we're in a GitHub Actions environment + * @link https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables + */ +function isGHA() { + return process.env.GITHUB_ACTIONS === 'true'; +} + +/** + * Wrapper for the `fetch` API so we can add rdme-specific headers to all API requests. * */ -module.exports = (url, options = {}) => { - if (!options.headers) { - options.headers = { - 'User-Agent': module.exports.getUserAgent(), - }; - } else { - options.headers['User-Agent'] = module.exports.getUserAgent(); +module.exports = (url, options = { headers: {} }) => { + let source = 'cli'; + + options.headers['User-Agent'] = module.exports.getUserAgent(); + + if (isGHA()) { + source = 'cli-gh'; + options.headers['x-github-repository'] = process.env.GITHUB_REPOSITORY; + options.headers['x-github-run-attempt'] = process.env.GITHUB_RUN_ATTEMPT; + options.headers['x-github-run-id'] = process.env.GITHUB_RUN_ID; + options.headers['x-github-run-number'] = process.env.GITHUB_RUN_NUMBER; + options.headers['x-github-sha'] = process.env.GITHUB_SHA; } + options.headers['x-readme-source'] = source; + return fetch(url, options); }; @@ -25,7 +40,7 @@ module.exports = (url, options = {}) => { * */ module.exports.getUserAgent = function getUserAgent() { - const gh = process.env.GITHUB_ACTIONS === 'true' ? '-github' : ''; + const gh = isGHA() ? '-github' : ''; return `rdme${gh}/${pkg.version}`; };