Skip to content
This repository has been archived by the owner on Dec 8, 2023. It is now read-only.

Commit

Permalink
feat: Add quickstart related back end code
Browse files Browse the repository at this point in the history
* cron workflow to pull and commit quickstarts
* js script to pull and write quickstarts and related test files
* related gatsby plugins
* add script alias to package.json for fetching quickstarts
  • Loading branch information
aswanson-nr committed Jan 20, 2022
1 parent 7886bfc commit d3b1e31
Show file tree
Hide file tree
Showing 6 changed files with 495 additions and 14 deletions.
103 changes: 103 additions & 0 deletions .github/workflows/fetch-quickstarts.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
name: Fetch Quickstarts

on:
workflow_dispatch:
schedule:
- cron: '0 1,5,9,13,17,21 * * *' # Every 4 hours staggered by 1 hour

env:
BOT_NAME: nr-opensource-bot
BOT_EMAIL: [email protected]
NODE_OPTIONS: '--max-old-space-size=4096'

jobs:
fetch-quickstarts:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v2
with:
ref: main

- name: Setup node.js
uses: actions/setup-node@v1
with:
node-version: 16

- name: Cache dependencies
id: yarn-cache
uses: actions/cache@v2
with:
path: '**/node_modules'
key: ${{ runner.os }}-node-modules-${{ hashFiles('**/yarn.lock') }}

- name: Install dependencies
if: steps.yarn-cache.outputs.cache-hit != 'true'
run: yarn install --frozen-lockfile

- name: Fetch quickstarts
run: yarn run fetch-quickstarts
env:
NR_API_URL: 'https://api.newrelic.com/graphql'
NR_API_TOKEN: ${{ secrets.NR_API_TOKEN }}

- name: Temporarily disable branch protection
id: disable-branch-protection
uses: actions/github-script@v1
with:
github-token: ${{ secrets.OPENSOURCE_BOT_TOKEN }}
previews: luke-cage-preview
script: |
const result = await github.repos.updateBranchProtection({
owner: context.repo.owner,
repo: context.repo.repo,
branch: 'main',
required_status_checks: null,
restrictions: null,
enforce_admins: null,
required_pull_request_reviews: null
})
console.log("Result:", result)
- name: Commit changes
id: commit-changes
run: |
git config --local user.email "${{ env.BOT_EMAIL }}"
git config --local user.name "${{ env.BOT_NAME }}"
git add ./src/data/quickstarts.json
git diff-index --quiet HEAD ./src/data/quickstarts.json || git commit -m 'chore(quickstarts): updated quickstarts'
echo "::set-output name=commit::true"
- name: Push Commit
if: steps.commit-changes.outputs.commit == 'true'
uses: ad-m/[email protected]
with:
github_token: ${{ secrets.OPENSOURCE_BOT_TOKEN }}
branch: main

- name: Re-enable branch protection
id: enable-branch-protection
if: always()
uses: actions/github-script@v1
with:
github-token: ${{ secrets.OPENSOURCE_BOT_TOKEN }}
previews: luke-cage-preview
script: |
const result = await github.repos.updateBranchProtection({
owner: context.repo.owner,
repo: context.repo.repo,
branch: 'main',
required_status_checks: {
strict: false,
contexts: [
'Gatsby Build Service - instant-observability-website'
]
},
restrictions: null,
enforce_admins: true,
required_pull_request_reviews: {
dismiss_stale_reviews: true,
required_approving_review_count: 1
}
})
console.log("Result:", result)
33 changes: 28 additions & 5 deletions gatsby-config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,31 @@
module.exports = {
siteMetadata: {
siteUrl: `https://www.yourdomain.tld`,
siteMetadata: {
siteUrl: `https://www.yourdomain.tld`,
},
plugins: [
{
resolve: "gatsby-source-filesystem",
options: {
name: "quickstarts",
path: `${__dirname}/src/data/quickstarts.json`,
},
},
plugins: [
{
resolve: "gatsby-transformer-json",
options: {
// If we need to source json files other than the i18n/nav, we should
// consider making this dynamic. See the docs for ways to do this.
//
// https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-transformer-json
typeName: "Quickstarts",
},
},
{
resolve: "gatsby-plugin-gatsby-cloud",
options: {
allPageHeaders: ["Referrer-Policy: no-referrer-when-downgrade"],
},
},
],
};

]
}
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,14 @@
"start": "gatsby develop",
"build": "gatsby build",
"serve": "gatsby serve",
"clean": "gatsby clean"
"clean": "gatsby clean",
"fetch-quickstarts": "node ./scripts/actions/fetch-quickstarts.js"
},
"dependencies": {
"gatsby": "^4.5.3",
"gatsby-plugin-gatsby-cloud": "^4.5.2",
"gatsby-source-filesystem": "^4.5.2",
"gatsby-transformer-json": "^4.5.0",
"react": "^17.0.1",
"react-dom": "^17.0.1"
}
Expand Down
121 changes: 121 additions & 0 deletions scripts/actions/__tests__/fetch-quickstarts.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
'use strict';

const fs = require('fs');
const fetch = require('node-fetch');
const fetchQuickstarts = require('../fetch-quickstarts');

jest.mock('node-fetch');
jest.mock('fs');

describe('Action: Fetch Observability Packs', () => {
const fakeAPIURL = 'fakeapi.com/graphql';
const fakeToken = 'fake_token';
const fakeGqlQuery = 'fake_gql_query';

afterEach(() => {
jest.resetAllMocks();
});

test('writes observability packs to file', async () => {
const apiReturnValue = {
data: {
docs: {
openInstallation: {
quickstartSearch: {
results: {
quickstarts: [
{
test: 'test',
},
],
},
},
},
},
},
};
fetch.mockResolvedValueOnce({
ok: true,
json: jest.fn(() => Promise.resolve(apiReturnValue)),
});

await fetchQuickstarts(fakeGqlQuery, fakeAPIURL, fakeToken);
expect(fs.writeFileSync.mock.calls.length).toBe(1);
expect(fs.writeFileSync.mock.calls[0][0]).toStrictEqual(
'./src/data/quickstarts.json'
);
expect(fs.writeFileSync.mock.calls[0][1]).toStrictEqual(
JSON.stringify([{ test: 'test' }], null, 2)
);
});

test('does not write file when graphql errors are returned', async () => {
const apiReturnValue = {
errors: {
testError: 'error',
},
data: {
docs: {
openInstallation: {
quickstartSearch: {
results: {
quickstarts: [
{
test: 'test',
},
],
},
},
},
},
},
};
fetch.mockResolvedValueOnce({
json: jest.fn(() => Promise.resolve(apiReturnValue)),
ok: true,
});

await fetchQuickstarts(fakeGqlQuery, fakeAPIURL, fakeToken);
expect(fs.writeFileSync).not.toHaveBeenCalled();
});

test('does not write file when graphql response is malformed', async () => {
const apiReturnValue = {
data: {
docs: {
quickstartSearch: {
results: {
quickstarts: [
{
test: 'test',
},
],
},
},
},
},
};
fetch.mockResolvedValueOnce({
json: jest.fn(() => Promise.resolve(apiReturnValue)),
ok: true,
});

await fetchQuickstarts(fakeGqlQuery, fakeAPIURL, fakeToken);
expect(fs.writeFileSync).not.toHaveBeenCalled();
});

test('does not write file when a network error occurs', async () => {
fetch.mockImplementation(() => Promise.reject());
await fetchQuickstarts(fakeGqlQuery, fakeAPIURL, fakeToken);
expect(fs.writeFileSync).not.toHaveBeenCalled();
});

test('does not write file when a non-200 status is returned from the API', async () => {
fetch.mockResolvedValueOnce({
status: 500,
ok: false,
});
await fetchQuickstarts(fakeGqlQuery, fakeAPIURL, fakeToken);
expect(fs.writeFileSync).not.toHaveBeenCalled();
});
});
Loading

0 comments on commit d3b1e31

Please sign in to comment.