Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(GHA): add req header containing file URL #735

Merged
merged 23 commits into from
Feb 1, 2023
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
d423839
feat(GHA): add req header containing file URL
kanadgupta Jan 26, 2023
21cef06
test: fix coverage for ci.name
kanadgupta Jan 26, 2023
5e922a0
chore: add eslint rule for importing `ci-info`
kanadgupta Jan 26, 2023
75a840a
chore: add smol jsdoc
kanadgupta Jan 26, 2023
13520ab
chore: another JSdoc
kanadgupta Jan 26, 2023
a83cf3b
Merge branch 'main' into file-url-header
kanadgupta Jan 31, 2023
3ba7b07
chore: fix whitespace
kanadgupta Jan 31, 2023
7798272
refactor: separate GHA runner setup/teardown
kanadgupta Jan 31, 2023
2ed922e
Merge branch 'main' into file-url-header
kanadgupta Jan 31, 2023
4141381
Merge branch 'main' into file-url-header
kanadgupta Jan 31, 2023
0a123ef
chore: rename variable
kanadgupta Jan 31, 2023
73602b8
chore: misc JSDocs
kanadgupta Jan 31, 2023
7ae4fc0
chore: include sanitized headers in debug logs
kanadgupta Jan 31, 2023
01836a8
fix: normalize relative file paths
kanadgupta Feb 1, 2023
9488d67
test: a buttload of tests
kanadgupta Feb 1, 2023
66ce036
test: consolidate some CI tests
kanadgupta Feb 1, 2023
6be8a62
chore: fix a JSDoc
kanadgupta Feb 1, 2023
97ded5f
revert: restore a test to its original place
kanadgupta Feb 1, 2023
eafd73d
chore: try different approach to GHA env vars
kanadgupta Feb 1, 2023
daa5801
refactor: use shorthand
kanadgupta Feb 1, 2023
05d5f0c
Merge branch 'main' into file-url-header
kanadgupta Feb 1, 2023
3093bca
fix: better approach to normalizing file path
kanadgupta Feb 1, 2023
f464053
chore: fix JSDoc
kanadgupta Feb 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@
"name": "node-fetch",
"importNames": ["default"],
"message": "Avoid using `node-fetch` directly and instead use the fetch wrapper located in `lib/fetch.ts`. See CONTRIBUTING.md for more information."
},
{
"name": "ci-info",
"message": "The `ci-info` package is difficult to test because misleading results will appear when running tests in the GitHub Actions runner. Instead of importing this package directly, create a wrapper function in `lib/isCI.ts` and import that instead."
}
]
}
Expand Down
139 changes: 133 additions & 6 deletions __tests__/cmds/docs/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import configstore from '../../../src/lib/configstore';
import getAPIMock, { getAPIMockWithVersionHeader } from '../../helpers/get-api-mock';
import { after, before } from '../../helpers/get-gha-setup';
import hashFileContents from '../../helpers/hash-file-contents';
import { after as afterGHAEnv, before as beforeGHAEnv } from '../../helpers/setup-gha-env';

const docs = new DocsCommand();
const guides = new GuidesCommand();
Expand Down Expand Up @@ -68,12 +69,6 @@ describe('rdme docs', () => {
jest.resetAllMocks();
});

it('should error in CI if no API key provided', async () => {
process.env.TEST_RDME_CI = 'true';
await expect(docs.run({})).rejects.toStrictEqual(new Error('No project API key provided. Please use `--key`.'));
delete process.env.TEST_RDME_CI;
});

it('should error if no path provided', async () => {
const versionMock = getAPIMock().get(`/api/v1/version/${version}`).basicAuth({ user: key }).reply(200, { version });

Expand Down Expand Up @@ -623,6 +618,138 @@ describe('rdme docs', () => {
versionMock.done();
});
});

describe('command execution in GitHub Actions runner', () => {
beforeEach(() => beforeGHAEnv());

afterEach(() => afterGHAEnv());

it('should error in CI if no API key provided', () => {
return expect(docs.run({})).rejects.toStrictEqual(new Error('No project API key provided. Please use `--key`.'));
});

it('should sync new docs directory with correct headers', async () => {
const slug = 'new-doc';
const id = '1234';
const doc = frontMatter(fs.readFileSync(path.join(fullFixturesDir, `/new-docs/${slug}.md`)));
const hash = hashFileContents(fs.readFileSync(path.join(fullFixturesDir, `/new-docs/${slug}.md`)));

const getMock = getAPIMockWithVersionHeader(version)
.get(`/api/v1/docs/${slug}`)
.basicAuth({ user: key })
.reply(404, {
error: 'DOC_NOTFOUND',
message: `The doc with the slug '${slug}' couldn't be found`,
suggestion: '...a suggestion to resolve the issue...',
help: 'If you need help, email [email protected] and mention log "fake-metrics-uuid".',
});

const postMock = getAPIMock({
'x-rdme-ci': 'GitHub Actions (test)',
'x-readme-source': 'cli-gh',
'x-readme-source-url':
'https://github.com/octocat/Hello-World/blob/ffac537e6cbbf934b08745a378932722df287a53/__tests__/__fixtures__/docs/new-docs/new-doc.md',
'x-readme-version': version,
})
.post('/api/v1/docs', { slug, body: doc.content, ...doc.data, lastUpdatedHash: hash })
.basicAuth({ user: key })
.reply(201, { slug, _id: id, body: doc.content, ...doc.data, lastUpdatedHash: hash });

const versionMock = getAPIMock()
.get(`/api/v1/version/${version}`)
.basicAuth({ user: key })
.reply(200, { version });

await expect(docs.run({ filePath: `./__tests__/${fixturesBaseDir}/new-docs`, key, version })).resolves.toBe(
`🌱 successfully created 'new-doc' (ID: 1234) with contents from __tests__/${fixturesBaseDir}/new-docs/new-doc.md`
);

getMock.done();
postMock.done();
versionMock.done();
});

it('should sync existing docs directory with correct headers', () => {
let fileContents = fs.readFileSync(path.join(fullFixturesDir, '/existing-docs/simple-doc.md'));
const simpleDoc = {
slug: 'simple-doc',
doc: frontMatter(fileContents),
hash: hashFileContents(fileContents),
};

fileContents = fs.readFileSync(path.join(fullFixturesDir, '/existing-docs/subdir/another-doc.md'));
const anotherDoc = {
slug: 'another-doc',
doc: frontMatter(fileContents),
hash: hashFileContents(fileContents),
};

expect.assertions(1);

const getMocks = getAPIMockWithVersionHeader(version)
.get('/api/v1/docs/simple-doc')
.basicAuth({ user: key })
.reply(200, { category, slug: simpleDoc.slug, lastUpdatedHash: 'anOldHash' })
.get('/api/v1/docs/another-doc')
.basicAuth({ user: key })
.reply(200, { category, slug: anotherDoc.slug, lastUpdatedHash: 'anOldHash' });

const firstUpdateMock = getAPIMock({
'x-rdme-ci': 'GitHub Actions (test)',
'x-readme-source': 'cli-gh',
'x-readme-source-url':
'https://github.com/octocat/Hello-World/blob/ffac537e6cbbf934b08745a378932722df287a53/__tests__/__fixtures__/docs/existing-docs/simple-doc.md',
'x-readme-version': version,
})
.put('/api/v1/docs/simple-doc', {
body: simpleDoc.doc.content,
lastUpdatedHash: simpleDoc.hash,
...simpleDoc.doc.data,
})
.basicAuth({ user: key })
.reply(200, {
category,
slug: simpleDoc.slug,
body: simpleDoc.doc.content,
});

const secondUpdateMock = getAPIMock({
'x-rdme-ci': 'GitHub Actions (test)',
'x-readme-source': 'cli-gh',
'x-readme-source-url':
'https://github.com/octocat/Hello-World/blob/ffac537e6cbbf934b08745a378932722df287a53/__tests__/__fixtures__/docs/existing-docs/subdir/another-doc.md',
'x-readme-version': version,
})
.put('/api/v1/docs/another-doc', {
body: anotherDoc.doc.content,
lastUpdatedHash: anotherDoc.hash,
...anotherDoc.doc.data,
})
.basicAuth({ user: key })
.reply(200, { category, slug: anotherDoc.slug, body: anotherDoc.doc.content });

const versionMock = getAPIMock()
.get(`/api/v1/version/${version}`)
.basicAuth({ user: key })
.reply(200, { version });

return docs.run({ filePath: `__tests__/${fixturesBaseDir}/existing-docs`, key, version }).then(updatedDocs => {
// All docs should have been updated because their hashes from the GET request were different from what they
// are currently.
expect(updatedDocs).toBe(
[
`✏️ successfully updated 'simple-doc' with contents from __tests__/${fixturesBaseDir}/existing-docs/simple-doc.md`,
`✏️ successfully updated 'another-doc' with contents from __tests__/${fixturesBaseDir}/existing-docs/subdir/another-doc.md`,
].join('\n')
);

getMocks.done();
firstUpdateMock.done();
secondUpdateMock.done();
versionMock.done();
});
});
});
});

describe('rdme guides', () => {
Expand Down
110 changes: 104 additions & 6 deletions __tests__/cmds/docs/single.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import DocsCommand from '../../../src/cmds/docs';
import APIError from '../../../src/lib/apiError';
import getAPIMock, { getAPIMockWithVersionHeader } from '../../helpers/get-api-mock';
import hashFileContents from '../../helpers/hash-file-contents';
import { after as afterGHAEnv, before as beforeGHAEnv } from '../../helpers/setup-gha-env';

const docs = new DocsCommand();

Expand All @@ -32,12 +33,6 @@ describe('rdme docs (single)', () => {
consoleInfoSpy.mockRestore();
});

it('should error in CI if no API key provided', async () => {
process.env.TEST_RDME_CI = 'true';
await expect(docs.run({})).rejects.toStrictEqual(new Error('No project API key provided. Please use `--key`.'));
delete process.env.TEST_RDME_CI;
});

it('should error if no file path provided', async () => {
const versionMock = getAPIMock().get(`/api/v1/version/${version}`).basicAuth({ user: key }).reply(200, { version });

Expand Down Expand Up @@ -347,4 +342,107 @@ describe('rdme docs (single)', () => {
});
});
});

describe('command execution in GitHub Actions runner', () => {
beforeEach(() => beforeGHAEnv());

afterEach(() => afterGHAEnv());

it('should error in CI if no API key provided', () => {
return expect(docs.run({})).rejects.toStrictEqual(new Error('No project API key provided. Please use `--key`.'));
});

it('should sync new doc with correct headers', async () => {
const slug = 'new-doc';
const id = '1234';
const doc = frontMatter(fs.readFileSync(path.join(fullFixturesDir, `/new-docs/${slug}.md`)));
const hash = hashFileContents(fs.readFileSync(path.join(fullFixturesDir, `/new-docs/${slug}.md`)));

const getMock = getAPIMockWithVersionHeader(version)
.get(`/api/v1/docs/${slug}`)
.basicAuth({ user: key })
.reply(404, {
error: 'DOC_NOTFOUND',
message: `The doc with the slug '${slug}' couldn't be found`,
suggestion: '...a suggestion to resolve the issue...',
help: 'If you need help, email [email protected] and mention log "fake-metrics-uuid".',
});

const postMock = getAPIMock({
'x-rdme-ci': 'GitHub Actions (test)',
'x-readme-source': 'cli-gh',
'x-readme-source-url':
'https://github.com/octocat/Hello-World/blob/ffac537e6cbbf934b08745a378932722df287a53/__tests__/__fixtures__/docs/new-docs/new-doc.md',
'x-readme-version': version,
})
.post('/api/v1/docs', { slug, body: doc.content, ...doc.data, lastUpdatedHash: hash })
.basicAuth({ user: key })
.reply(201, { slug, _id: id, body: doc.content, ...doc.data, lastUpdatedHash: hash });

const versionMock = getAPIMock()
.get(`/api/v1/version/${version}`)
.basicAuth({ user: key })
.reply(200, { version });

await expect(
docs.run({ filePath: `./__tests__/${fixturesBaseDir}/new-docs/new-doc.md`, key, version })
).resolves.toBe(
`🌱 successfully created 'new-doc' (ID: 1234) with contents from ./__tests__/${fixturesBaseDir}/new-docs/new-doc.md`
);

getMock.done();
postMock.done();
versionMock.done();
});

it('should sync existing doc with correct headers', () => {
const fileContents = fs.readFileSync(path.join(fullFixturesDir, '/existing-docs/simple-doc.md'));
const simpleDoc = {
slug: 'simple-doc',
doc: frontMatter(fileContents),
hash: hashFileContents(fileContents),
};

const getMock = getAPIMockWithVersionHeader(version)
.get('/api/v1/docs/simple-doc')
.basicAuth({ user: key })
.reply(200, { category, slug: simpleDoc.slug, lastUpdatedHash: 'anOldHash' });

const updateMock = getAPIMock({
'x-rdme-ci': 'GitHub Actions (test)',
'x-readme-source': 'cli-gh',
'x-readme-source-url':
'https://github.com/octocat/Hello-World/blob/ffac537e6cbbf934b08745a378932722df287a53/__tests__/__fixtures__/docs/existing-docs/simple-doc.md',
'x-readme-version': version,
})
.put('/api/v1/docs/simple-doc', {
body: simpleDoc.doc.content,
lastUpdatedHash: simpleDoc.hash,
...simpleDoc.doc.data,
})
.basicAuth({ user: key })
.reply(200, {
category,
slug: simpleDoc.slug,
body: simpleDoc.doc.content,
});

const versionMock = getAPIMock()
.get(`/api/v1/version/${version}`)
.basicAuth({ user: key })
.reply(200, { version });

return docs
.run({ filePath: `__tests__/${fixturesBaseDir}/existing-docs/simple-doc.md`, key, version })
.then(updatedDocs => {
expect(updatedDocs).toBe(
`✏️ successfully updated 'simple-doc' with contents from __tests__/${fixturesBaseDir}/existing-docs/simple-doc.md`
);

getMock.done();
updateMock.done();
versionMock.done();
});
});
});
});
Loading