Skip to content

Commit

Permalink
feat: add wrapper for GitHub Actions (#437)
Browse files Browse the repository at this point in the history
* feat: add initial github action config

* ci: add gh action test

* test: refactor test to check for exact UA match

* feat: dynamically set user agent based on env

* chore: temporarily skip test suite

Our test bed is a bit broken right now and I should fix this up, but I just want to see how the GitHub Action test runs for the time being 😬

* chore: silence npm i logs

* ci: restore tests, move action test to separate workflow file

* Update action.yml

* chore: update param names, job names

* fix: attempt to get npm install working properly

* chore: update loglevel

* chore: ok updating log level AGAIN

Once we add a debug option, I'll also update this line to reflect that!

* chore: set working directory instead

Docs: https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsworking-directory

* test: attempt to get CI working again

* test: how about this?

* refactor: consolidate user-agent logic

* refactor: move path to `working_directory`

This way our logs look a little cleaner!

* chore: typo

* chore: remove unnecessary quotes

* chore: oops

* chore: does this look any cleaner?

* fix: try this

* revert: eh nvm

* chore: removing quotes in one last place

* revert: move this back

So interesting thing I discovered in this test run: https://github.com/kanadgupta/metrotransit-nextrip-oas/runs/5163683403?check_suite_focus=true#step:3:18

Even though this will look a bit messier in the user's action logs, this is the only way to ensure that the command runs in the user's GitHub repo :sad:

* ci: update test workflow to test it with another repo

* ci: will this work?

* ci: add a token that hopefully works

* chore: consolidate CI

* refactor: consolidate nock logic

* chore: small formatting tweaks

* ci: add upload step

* fix: see if chalk prints colors nicely with this env var

* chore: update workflow docs a bit
  • Loading branch information
kanadgupta authored Feb 15, 2022
1 parent 9cbcaef commit f0b9d11
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 21 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on: [push]

jobs:
build:
name: Test Suite
runs-on: ubuntu-latest
strategy:
matrix:
Expand All @@ -22,3 +23,30 @@ jobs:

- name: Run tests
run: npm test

action:
name: GitHub Action Dry Run
runs-on: ubuntu-latest
steps:
- name: Checkout GitHub Action
uses: actions/[email protected]
with:
path: rdme-repo

- name: Checkout external repo containing OpenAPI file
uses: actions/[email protected]
with:
path: oas-examples-repo
repository: readmeio/oas-examples
token: ${{ secrets.OAS_EXAMPLES_READ }}

- name: Run `validate` command
uses: ./rdme-repo/
with:
rdme: validate oas-examples-repo/3.1/json/petstore.json

# Docs: https://rdme-test.readme.io
- name: Run `openapi` command
uses: ./rdme-repo/
with:
rdme: openapi oas-examples-repo/3.1/json/petstore.json --key=${{ secrets.RDME_TEST_PROJECT_API_KEY }} --id=${{ secrets.RDME_TEST_PROJECT_API_SETTING }}
9 changes: 2 additions & 7 deletions __tests__/cmds/docs.test.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
const nock = require('nock');
const chalk = require('chalk');
const config = require('config');
const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
const frontMatter = require('gray-matter');

const APIError = require('../../src/lib/apiError');
const getApiNock = require('../get-api-nock');
const { userAgent } = require('../get-api-nock');

const DocsCommand = require('../../src/cmds/docs');
const DocsEditCommand = require('../../src/cmds/docs/edit');
Expand All @@ -23,11 +21,8 @@ const category = 'CATEGORY_ID';
const apiSetting = 'API_SETTING_ID';

function getNockWithVersionHeader(v) {
return nock(config.get('host'), {
reqheaders: {
'x-readme-version': v,
'User-Agent': userAgent,
},
return getApiNock({
'x-readme-version': v,
});
}

Expand Down
13 changes: 5 additions & 8 deletions __tests__/get-api-nock.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
const nock = require('nock');
const config = require('config');
const pkg = require('../package.json');

const userAgent = `rdme/${pkg.version}`;
const nock = require('nock');
const { getUserAgent } = require('../src/lib/fetch');

module.exports = function () {
module.exports = function (reqHeaders = {}) {
return nock(config.get('host'), {
reqheaders: {
'User-Agent': userAgent,
'User-Agent': getUserAgent(),
...reqHeaders,
},
});
};

module.exports.userAgent = userAgent;
34 changes: 32 additions & 2 deletions __tests__/lib/fetch.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,38 @@ const config = require('config');
const fetch = require('../../src/lib/fetch');
const { cleanHeaders, handleRes } = require('../../src/lib/fetch');
const getApiNock = require('../get-api-nock');
const pkg = require('../../package.json');

describe('#fetch()', () => {
describe('GitHub Actions environment', () => {
beforeEach(() => {
process.env.GITHUB_ACTIONS = 'true';
});

afterEach(() => {
delete process.env.GITHUB_ACTIONS;
});

it('should use correct user-agent 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'];
});

const userAgent = await fetch(`${config.get('host')}/api/v1`, {
method: 'get',
headers: cleanHeaders(key),
}).then(handleRes);

expect(userAgent.shift()).toBe(`rdme-github/${pkg.version}`);
mock.done();
});
});

it('should wrap all requests with a rdme User-Agent', async () => {
const key = 'API_KEY';

Expand All @@ -19,7 +49,7 @@ describe('#fetch()', () => {
headers: cleanHeaders(key),
}).then(handleRes);

expect(userAgent.shift()).toMatch(/rdme\/\d+.\d+.\d+/);
expect(userAgent.shift()).toBe(`rdme/${pkg.version}`);
mock.done();
});

Expand All @@ -32,7 +62,7 @@ describe('#fetch()', () => {

const userAgent = await fetch(`${config.get('host')}/api/v1/doesnt-need-auth`).then(handleRes);

expect(userAgent.shift()).toMatch(/rdme\/\d+.\d+.\d+/);
expect(userAgent.shift()).toBe(`rdme/${pkg.version}`);
mock.done();
});
});
Expand Down
28 changes: 28 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: rdme
author: ReadMe
branding:
color: blue
icon: book-open
description: Update your ReadMe developer hubs in a CI environment.
inputs:
rdme:
description: Command to pass into rdme
required: true
runs:
using: composite
steps:
# This is so we can guarantee a version of npm that supports lockfile@2
- name: setup node
uses: actions/setup-node@v2
with:
node-version: 16
# When we add debug support, we should make this a conditional step, see RM-3545
- name: Install rdme deps
run: npm install --production --silent
shell: bash
working-directory: ${{ github.action_path }}
- name: Execute rdme command
run: ${{ github.action_path }}/bin/rdme ${{ inputs.rdme }}
shell: bash
env:
FORCE_COLOR: '1'
16 changes: 12 additions & 4 deletions src/lib/fetch.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,27 @@ const APIError = require('./apiError');
*
*/
module.exports = (url, options = {}) => {
const userAgent = `rdme/${pkg.version}`;

if (!options.headers) {
options.headers = {
'User-Agent': userAgent,
'User-Agent': module.exports.getUserAgent(),
};
} else {
options.headers['User-Agent'] = userAgent;
options.headers['User-Agent'] = module.exports.getUserAgent();
}

return fetch(url, options);
};

/**
* Getter function for a string to be used in the user-agent header
* based on the current environment.
*
*/
module.exports.getUserAgent = function getUserAgent() {
const gh = process.env.GITHUB_ACTIONS === 'true' ? '-github' : '';
return `rdme${gh}/${pkg.version}`;
};

/**
* Small handler for transforming responses from our API into JSON and if there's errors, throwing
* an APIError exception.
Expand Down

0 comments on commit f0b9d11

Please sign in to comment.