Skip to content

Commit

Permalink
feat(starter showcase): gh data sourcing and screenshot generation (#…
Browse files Browse the repository at this point in the history
…8320)

* (#7730): add starters.yml

* (#7730): Re-form and move github metadata sourcing, add dotenv

* (#7730): Change data in view to draw appropriately from starter yml

* (#7730): create starter pages referencing yaml

* (#7730): Convert starter data in view from markdown to yml

* (#7730): Rm references to old starter data

* (#7730): Delete old static starter showcase data

* (#7730): Update broken starter demo link

* (#7730): Remove hanging references to deleted data

* (#7730): Prioritize stars for v1

* (#7730): Manage DX if gh token not supplied for starter data sourcing; break on build

* (#7730): Change how owner and repo are parsed from GitHub url; Rm UI messaging if gh data empty

* (#7730): Code formatting tweak

* (#7730): Rename files away from showcase wording

* (#7730): Minor consistency issue with merged updates

* (#7730): Re-delete generated starter data readded by merged prettier run

* (#7730): remove archived project with broken demo

* [www] change github env token name

* [www] fix merge weirdness between old pr and fks reorg

closes #7730
  • Loading branch information
amberleyromo authored and jlengstorf committed Sep 28, 2018
1 parent 5ad1bb5 commit 1ae7568
Show file tree
Hide file tree
Showing 198 changed files with 1,226 additions and 12,041 deletions.
742 changes: 742 additions & 0 deletions docs/starters.yml

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions www/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,6 @@ node_modules
/yarn.lock
src/cache
/package-lock.json

# Env variables
.env.development
14 changes: 14 additions & 0 deletions www/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,17 @@ Run locally with

- `yarn install`
- `yarn run develop`

## Working with the starter showcase

To develop on the starter showcase, you'll need to supply a GitHub personal access token.

1. Create a personal access token in your GitHub [Developer settings](https://github.com/settings/tokens).
2. In the new token's settings, grant that token the "public_repo" scope.
3. Create a file in the root of `www` called `.env.development`, and add the token to that file like so:

```
GITHUB_API_TOKEN=YOUR_TOKEN_HERE
```

The `.env.development` file is ignored by git. Your token should never be committed.
22 changes: 6 additions & 16 deletions www/gatsby-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,6 @@ module.exports = {
path: `${__dirname}/../packages/`,
},
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: `StarterShowcaseImages`,
path: `${__dirname}/src/data/StarterShowcase/generatedScreenshots`,
},
},
// need to have the img processing first? https://github.com/gatsbyjs/gatsby/issues/5196
{
resolve: `gatsby-source-filesystem`,
options: {
name: `StarterShowcaseData`,
path: `${__dirname}/src/data/StarterShowcase/startersData`,
},
},
{
resolve: `gatsby-plugin-typography`,
options: {
Expand Down Expand Up @@ -183,7 +168,12 @@ module.exports = {
endpoint: `https://gatsbyjs.us17.list-manage.com/subscribe/post?u=1dc33f19eb115f7ebe4afe5ee&id=f366064ba7`,
},
},
`gatsby-transformer-screenshot`,
{
resolve: `gatsby-transformer-screenshot`,
options: {
nodeTypes: [`StartersYaml`],
},
},
`gatsby-plugin-subfont`,
// {
// resolve: `gatsby-plugin-guess-js`,
Expand Down
215 changes: 145 additions & 70 deletions www/gatsby-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,28 @@ const fs = require(`fs-extra`)
const slash = require(`slash`)
const slugify = require(`slugify`)
const url = require(`url`)
const getpkgjson = require(`get-package-json-from-github`)
const parseGHUrl = require("parse-github-url")
const { GraphQLClient } = require("graphql-request")

require(`dotenv`).config({
path: `.env.${process.env.NODE_ENV}`,
})

if (process.env.NODE_ENV === "production" && !process.env.GITHUB_API_TOKEN) {
throw new Error(
`A GitHub token is required to build the site. Check the README.`
)
}

// used to gather repo data on starters
const githubApiClient = process.env.GITHUB_API_TOKEN
? new GraphQLClient(`https://api.github.com/graphql`, {
headers: {
authorization: `Bearer ${process.env.GITHUB_API_TOKEN}`,
},
})
: null

const localPackages = `../packages`
const localPackagesArr = []
Expand Down Expand Up @@ -111,10 +133,6 @@ exports.createPages = ({ graphql, actions }) => {
fields {
slug
package
starterShowcase {
slug
stub
}
}
frontmatter {
title
Expand Down Expand Up @@ -153,6 +171,21 @@ exports.createPages = ({ graphql, actions }) => {
}
}
}
allStartersYaml {
edges {
node {
id
fields {
starterShowcase {
slug
stub
}
}
url
repo
}
}
}
allNpmPackage {
edges {
node {
Expand Down Expand Up @@ -236,27 +269,30 @@ exports.createPages = ({ graphql, actions }) => {
})
})

// Create starters.
const starters = _.filter(result.data.allMarkdownRemark.edges, edge => {
// Create starter pages.
const starters = _.filter(result.data.allStartersYaml.edges, edge => {
const slug = _.get(edge, `node.fields.starterShowcase.slug`)
if (!slug) return null
else return edge
if (!slug) {
return null
} else {
return edge
}
})

const starterTemplate = path.resolve(
`src/templates/template-starter-showcase.js`
)

starters.forEach((edge, index) => {
createPage({
path: `/starters${edge.node.fields.starterShowcase.slug}`, // required
path: `/starters${edge.node.fields.starterShowcase.slug}`,
component: slash(starterTemplate),
context: {
slug: edge.node.fields.starterShowcase.slug,
stub: edge.node.fields.starterShowcase.stub,
},
})
})
// END Create starters.

// Create contributor pages.
result.data.allAuthorYaml.edges.forEach(edge => {
Expand Down Expand Up @@ -387,13 +423,6 @@ exports.onCreateNode = ({ node, actions, getNode, getNodes }) => {
})
createNodeField({ node, name: `package`, value: true })
}
if (
// starter showcase
fileNode.sourceInstanceName === `StarterShowcaseData` &&
parsedFilePath.name !== `README`
) {
createNodesForStarterShowcase({ node, getNode, getNodes, actions })
} // end starter showcase
if (slug) {
createNodeField({ node, name: `anchor`, value: slugToAnchor(slug) })
createNodeField({ node, name: `slug`, value: slug })
Expand All @@ -408,6 +437,105 @@ exports.onCreateNode = ({ node, actions, getNode, getNodes }) => {
const cleaned = parsed.hostname + parsed.pathname
slug = `/showcase/${slugify(cleaned)}`
createNodeField({ node, name: `slug`, value: slug })
} else if (node.internal.type === `StartersYaml` && node.repo) {
// To develop on the starter showcase, you'll need a GitHub
// personal access token. Check the `www` README for details.
// Default fields are to avoid graphql errors.
const { owner, name: repoStub } = parseGHUrl(node.repo)
const defaultFields = {
slug: ``,
stub: ``,
name: ``,
description: ``,
stars: 0,
lastUpdated: ``,
owner: ``,
githubFullName: ``,
allDependencies: [],
gatsbyDependencies: [],
miscDependencies: [],
}

if (!process.env.GITHUB_API_TOKEN) {
return createNodeField({
node,
name: `starterShowcase`,
value: {
...defaultFields,
},
})
}

Promise.all([
getpkgjson(node.repo),
githubApiClient.request(`
query {
repository(owner:"${owner}", name:"${repoStub}") {
name
stargazers {
totalCount
}
createdAt
updatedAt
owner {
login
}
nameWithOwner
}
}
`),
])
.then(results => {
const [pkgjson, githubData] = results
const {
stargazers: { totalCount: stars },
updatedAt: lastUpdated,
owner: { login: owner },
name,
nameWithOwner: githubFullName,
} = githubData.repository

const { dependencies = [], devDependencies = [] } = pkgjson
const allDependencies = Object.entries(dependencies).concat(
Object.entries(devDependencies)
)
const starterShowcaseFields = {
slug: `/${repoStub}/`,
stub: repoStub,
name,
description: pkgjson.description,
stars,
lastUpdated,
owner,
githubFullName,
allDependencies,
gatsbyDependencies: allDependencies
.filter(
([key, _]) => ![`gatsby-cli`, `gatsby-link`].includes(key) // remove stuff everyone has
)
.filter(([key, _]) => key.includes(`gatsby`)),
miscDependencies: allDependencies.filter(
([key, _]) => !key.includes(`gatsby`)
),
}
createNodeField({
node,
name: `starterShowcase`,
value: starterShowcaseFields,
})
})
.catch(err => {
console.log(
`\nError getting repo data. Your GitHub token may be invalid`
)
return createNodeField({
node,
name: `starterShowcase`,
value: {
...defaultFields,
},
})
})
}

// Community/Creators Pages
Expand Down Expand Up @@ -440,59 +568,6 @@ exports.onPostBuild = () => {
)
}

// Starter Showcase related code
const { createFilePath } = require(`gatsby-source-filesystem`)
const gitFolder = `./src/data/StarterShowcase/generatedGithubData`
function createNodesForStarterShowcase({ node, getNode, getNodes, actions }) {
const { createNodeField, createParentChildLink } = actions
if (node.internal.type === `MarkdownRemark`) {
const slug = createFilePath({
node,
getNode,
basePath: `startersData`,
})
// preprocessing
const stub = slug.replace(/\//gi, ``)
var fromPath = path.join(gitFolder, `${stub}.json`)
var data = fs.readFileSync(fromPath, `utf8`)
const ghdata = JSON.parse(data)
if (ghdata.repository && ghdata.repository.url)
ghdata.repository = ghdata.repository.url // flatten a potential object into a string. weird quirk.
const { repoMetadata, dependencies = [], devDependencies = [] } = ghdata
const allDependencies = Object.entries(dependencies).concat(
Object.entries(devDependencies)
)
// make an object to stick into a Field
const starterShowcaseFields = {
slug,
stub,
date: new Date(node.frontmatter.date),
githubData: ghdata,
// nice-to-have destructures of githubData
description: ghdata.description,
stars: repoMetadata.stargazers_count,
lastUpdated: repoMetadata.created_at,
owner: repoMetadata.owner,
githubFullName: repoMetadata.full_name,
allDependencies,
gatsbyDependencies: allDependencies
.filter(
([key, _]) => ![`gatsby-cli`, `gatsby-link`].includes(key) // remove stuff everyone has
)
.filter(([key, _]) => key.includes(`gatsby`)),
miscDependencies: allDependencies.filter(
([key, _]) => !key.includes(`gatsby`)
),
}
createNodeField({
node,
name: `starterShowcase`,
value: starterShowcaseFields,
})
}
}
// End Starter Showcase related code

// limited logging for debug purposes
let limitlogcount = 0
function log(max) {
Expand Down
2 changes: 2 additions & 0 deletions www/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"author": "Kyle Mathews <[email protected]>",
"dependencies": {
"bluebird": "^3.5.1",
"dotenv": "^6.0.0",
"email-validator": "^1.1.1",
"fuse.js": "^3.2.0",
"gatsby": "^2.0.11",
Expand Down Expand Up @@ -53,6 +54,7 @@
"mitt": "^1.1.3",
"mousetrap": "^1.6.1",
"parse-filepath": "^1.0.2",
"parse-github-url": "^1.0.2",
"prismjs": "^1.14.0",
"qs": "^6.5.2",
"query-string": "^6.1.0",
Expand Down
33 changes: 0 additions & 33 deletions www/src/data/StarterShowcase/README.md

This file was deleted.

Loading

0 comments on commit 1ae7568

Please sign in to comment.