diff --git a/gatsby-node.js b/gatsby-node.js index 1e0b4008af..c43b85acb5 100644 --- a/gatsby-node.js +++ b/gatsby-node.js @@ -13,6 +13,7 @@ exports.createSchemaCustomization = api => exports.sourceNodes = api => callOnModels(models, 'sourceNodes', api) exports.onCreateNode = api => callOnModels(models, 'onCreateNode', api) exports.createPages = api => callOnModels(models, 'createPages', api) +exports.createResolvers = api => callOnModels(models, 'createResolvers', api) exports.onPostBuild = api => callOnModels(models, 'onPostBuild', api) exports.onCreatePage = ({ page, actions }) => { diff --git a/package.json b/package.json index baa08c8c64..9e844905e6 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "develop": "gatsby develop", "dev": "gatsby develop", "build": "gatsby build", - "start": "./scripts/clear-cloudflare-cache.js; node ./src/server/index.js", + "start": "./src/server/index.js", "heroku-postbuild": "./scripts/deploy-with-s3.js", "test": "jest", "format-staged": "pretty-quick --staged --no-restage --bail", diff --git a/scripts/clear-cloudflare-cache.js b/scripts/clear-cloudflare-cache.js index 83aa71bf13..e38514c460 100755 --- a/scripts/clear-cloudflare-cache.js +++ b/scripts/clear-cloudflare-cache.js @@ -1,13 +1,13 @@ -#!/usr/bin/env node -/* global process */ - -// This script runs just before the app starts. If we are running the -// production heroku app (the only one with the below env variables) -// the cache gets cleared. +// This script is run inside the S3 deploy script, after everything else, to +// clear the CloudFlare cache of stale page data programmatically. // // To clear the cache yourself, you can use the button in the -// cloudflare dashboard ("Caching tab > Purge everything"), or run -// this script with the required environment variables: +// cloudflare dashboard ("Caching tab > Purge everything") +// +// This module requires three environment variables to run: +// +// - CONTEXT: The exported function will immediately return without doing +// anything if this variable is not set to "production" // // - CLOUDFLARE_TOKEN: a token with the "Zone.Cache Purge" permission. // You can generate this token in "My Profile > API Tokens" @@ -17,9 +17,23 @@ const fetch = require('isomorphic-fetch') -const { CLOUDFLARE_TOKEN, CLOUDFLARE_ZONE_ID, CONTEXT } = process.env +module.exports = async function () { + const { CLOUDFLARE_TOKEN, CLOUDFLARE_ZONE_ID, CONTEXT } = process.env + + if (CONTEXT !== 'production') { + console.log( + 'Skipping CloudFlare cache purge because CONTEXT is not set to production.' + ) + return + } + + if (!(CLOUDFLARE_TOKEN && CLOUDFLARE_ZONE_ID)) { + console.error( + 'Skipping CloudFlare cache purge because CLOUDFLARE_TOKEN and/or CLOUDFLARE_ZONE_ID are not set.' + ) + return + } -async function main() { const res = await fetch( `https://api.cloudflare.com/client/v4/zones/${CLOUDFLARE_ZONE_ID}/purge_cache`, { @@ -34,26 +48,21 @@ async function main() { } ) - const body = await res.text() - - if (!res.ok) { - throw new Error('Error response received from CloudFlare: ' + body) - } - - console.log('Cleared cache successfully') -} + const body = await res.json() -if (CONTEXT === 'production') { - if (!(CLOUDFLARE_TOKEN && CLOUDFLARE_ZONE_ID)) { - console.error( - 'scripts/clear-cloudflare-cache.js: ' + - 'need CLOUDFLARE_TOKEN and CLOUDFLARE_ZONE_ID environment variables.' + if (!res.ok || !body.success) { + throw new Error( + 'CloudFlare cache clear failed! ' + + JSON.stringify( + { + status: res.status, + errors: body.errors + }, + undefined, + 2 + ) ) - process.exit(1) } - main().catch(e => { - console.error(e) - process.exit(1) - }) + console.log('Cleared CloudFlare cache successfully') } diff --git a/scripts/deploy-with-s3.js b/scripts/deploy-with-s3.js index c9489e4c78..3dc199f17d 100755 --- a/scripts/deploy-with-s3.js +++ b/scripts/deploy-with-s3.js @@ -5,6 +5,7 @@ const path = require('path') const PRODUCTION_PREFIX = 'dvc-org-prod' const { DEPLOY_OPTIONS } = process.env +const clearCloudflareCache = require('./clear-cloudflare-cache') // Generate deploy options from a comma separated string in the DEPLOY_OPTIONS // env var. If DEPLOY_OPTIONS isn't set, use a default setting. @@ -20,7 +21,8 @@ const deployOptions = DEPLOY_OPTIONS download: true, build: true, upload: true, - clean: true + clean: true, + clearCloudflareCache: true } if (deployOptions.logSteps) { @@ -129,6 +131,10 @@ async function main() { console.log('Cleaning all local cache!') await cleanAllLocal() } + + if (deployOptions.clearCloudflareCache) { + await clearCloudflareCache() + } } main().catch(e => { diff --git a/src/gatsby/models/github/index.js b/src/gatsby/models/github/index.js index 67843de3a1..9398d821c0 100644 --- a/src/gatsby/models/github/index.js +++ b/src/gatsby/models/github/index.js @@ -5,7 +5,7 @@ gatsby-plugin-github-api. If no GITHUB_TOKEN is specified, this node will be filled with default dummy data instead of throwing like using the plugin alone does. -*/ + */ async function createStaticGithubDataNode(api, fieldData = {}) { const { @@ -36,17 +36,36 @@ async function createStaticGithubDataNode(api, fieldData = {}) { } module.exports = { - sourceNodes: createStaticGithubDataNode, - async onCreateNode(api) { - const { - node, - actions: { createParentChildLink } - } = api - if (node.internal.type !== 'GithubData') return - const child = await createStaticGithubDataNode(api, { - parent: node.id, - stars: node.rawResult.data.repository.stargazers.totalCount + async createSchemaCustomization({ actions: { createTypes }, schema }) { + createTypes( + schema.buildObjectType({ + name: 'StaticGithubData', + fields: { + stars: 'String' + } + }) + ) + }, + async createResolvers({ createResolvers }) { + createResolvers({ + Query: { + staticGithubData: { + type: 'StaticGithubData', + async resolve(source, args, context) { + const nodes = await context.nodeModel.getAllNodes({ + type: 'GithubData' + }) + const node = nodes[0] + return node + ? { + stars: node.rawResult.data.repository.stargazers.totalCount + } + : { + stars: 8888 + } + } + } + } }) - await createParentChildLink({ child, parent: node }) } }