Skip to content

Commit

Permalink
Merge pull request #15 from actions/ssg-config-file-input
Browse files Browse the repository at this point in the history
Add support for specifying the SSG configuration file path
  • Loading branch information
JamesMGreene authored Aug 10, 2022
2 parents 404d23c + f5b4063 commit 15f519f
Show file tree
Hide file tree
Showing 25 changed files with 502 additions and 66 deletions.
5 changes: 4 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ runs:
main: 'dist/index.js'
inputs:
static_site_generator:
description: 'Optional static site generator to attempt to configure (nuxt, next or gatsby)'
description: 'Optional static site generator to attempt to configure: "nuxt", "next", or "gatsby"'
required: false
generator_config_file:
description: 'Optional file path to static site generator configuration file'
required: false
token:
description: 'GitHub token'
Expand Down
51 changes: 35 additions & 16 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14584,14 +14584,32 @@ class ConfigParser {
// Return the configuration object or null.
findConfigurationObject(ast) {
// Try to find a default export
var defaultExport = ast.body.find(
node => node.type === 'ExportDefaultDeclaration' && node.declaration.type === 'ObjectExpression'
)
if (defaultExport) {
core.info('Found configuration object in default export declaration')
var defaultExport = ast.body.find(node => node.type === 'ExportDefaultDeclaration')

// Direct default export
if (defaultExport && defaultExport.declaration.type === 'ObjectExpression') {
core.info('Found configuration object in direct default export declaration')
return defaultExport.declaration
}

// Indirect default export
else if (defaultExport && defaultExport.declaration.type === 'Identifier') {
const identifierName = defaultExport.declaration.name
const identifierDefinition = ast.body.find(
node =>
node.type === 'VariableDeclaration' &&
node.declarations.length == 1 &&
node.declarations[0].type === 'VariableDeclarator' &&
node.declarations[0].id.type === 'Identifier' &&
node.declarations[0].id.name === identifierName &&
node.declarations[0].init.type === 'ObjectExpression'
)
if (identifierDefinition) {
core.info('Found configuration object in indirect default export declaration')
return identifierDefinition.declarations[0].init
}
}

// Try to find a module export
var moduleExport = ast.body.find(
node =>
Expand Down Expand Up @@ -14699,7 +14717,7 @@ class ConfigParser {
var depth = 0
const properties = propertyName.split('.')
var lastNode = configurationObject
while (1) {
while (true) {
// Find the node for the current property
var propertyNode = this.findProperty(lastNode, properties[depth])

Expand Down Expand Up @@ -14801,6 +14819,7 @@ function getRequiredVars() {
repositoryNwo: process.env.GITHUB_REPOSITORY,
githubToken: core.getInput('token'),
staticSiteGenerator: core.getInput('static_site_generator'),
generatorConfigFile: core.getInput('generator_config_file'),
enablement: core.getInput('enablement') !== 'false'
}
}
Expand Down Expand Up @@ -14845,13 +14864,13 @@ module.exports = outputPagesBaseUrl
const core = __nccwpck_require__(2186)
const { ConfigParser } = __nccwpck_require__(8395)

// Return the settings to be passed to a {ConfigParser} for a given
// static site generator and a Pages path value to inject
function getConfigParserSettings(staticSiteGenerator, path) {
// Return the settings to be passed to a {ConfigParser} for a given static site generator,
// optional configuration file path, and a Pages path value to inject
function getConfigParserSettings({ staticSiteGenerator, generatorConfigFile, path }) {
switch (staticSiteGenerator) {
case 'nuxt':
return {
configurationFile: './nuxt.config.js',
configurationFile: generatorConfigFile || './nuxt.config.js',
blankConfigurationFile: __nccwpck_require__.ab + "nuxt.js",
properties: {
// Configure a base path on the router
Expand All @@ -14869,7 +14888,7 @@ function getConfigParserSettings(staticSiteGenerator, path) {
}

return {
configurationFile: './next.config.js',
configurationFile: generatorConfigFile || './next.config.js',
blankConfigurationFile: __nccwpck_require__.ab + "next.js",
properties: {
// Configure a base path
Expand All @@ -14882,7 +14901,7 @@ function getConfigParserSettings(staticSiteGenerator, path) {
}
case 'gatsby':
return {
configurationFile: './gatsby-config.js',
configurationFile: generatorConfigFile || './gatsby-config.js',
blankConfigurationFile: __nccwpck_require__.ab + "gatsby.js",
properties: {
// Configure a path prefix
Expand All @@ -14895,10 +14914,10 @@ function getConfigParserSettings(staticSiteGenerator, path) {
}

// Inject Pages configuration in a given static site generator's configuration file
function setPagesPath({ staticSiteGenerator, path }) {
function setPagesPath({ staticSiteGenerator, generatorConfigFile, path }) {
try {
// Parse the configuration file and try to inject the Pages configuration in it
const settings = getConfigParserSettings(staticSiteGenerator, path)
const settings = getConfigParserSettings({ staticSiteGenerator, generatorConfigFile, path })
new ConfigParser(settings).injectAll()
} catch (error) {
// Logging
Expand Down Expand Up @@ -16401,13 +16420,13 @@ const outputPagesBaseUrl = __nccwpck_require__(7527)

async function main() {
try {
const { repositoryNwo, githubToken, enablement, staticSiteGenerator } = getContext()
const { repositoryNwo, githubToken, enablement, staticSiteGenerator, generatorConfigFile } = getContext()

const pageObject = await findOrCreatePagesSite({ repositoryNwo, githubToken, enablement })
const siteUrl = new URL(pageObject.html_url)

if (staticSiteGenerator) {
setPagesPath({ staticSiteGenerator, path: siteUrl.pathname })
setPagesPath({ staticSiteGenerator, generatorConfigFile, path: siteUrl.pathname })
}
outputPagesBaseUrl(siteUrl)
} catch (error) {
Expand Down
2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

30 changes: 24 additions & 6 deletions src/config-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,32 @@ class ConfigParser {
// Return the configuration object or null.
findConfigurationObject(ast) {
// Try to find a default export
var defaultExport = ast.body.find(
node => node.type === 'ExportDefaultDeclaration' && node.declaration.type === 'ObjectExpression'
)
if (defaultExport) {
core.info('Found configuration object in default export declaration')
var defaultExport = ast.body.find(node => node.type === 'ExportDefaultDeclaration')

// Direct default export
if (defaultExport && defaultExport.declaration.type === 'ObjectExpression') {
core.info('Found configuration object in direct default export declaration')
return defaultExport.declaration
}

// Indirect default export
else if (defaultExport && defaultExport.declaration.type === 'Identifier') {
const identifierName = defaultExport.declaration.name
const identifierDefinition = ast.body.find(
node =>
node.type === 'VariableDeclaration' &&
node.declarations.length == 1 &&
node.declarations[0].type === 'VariableDeclarator' &&
node.declarations[0].id.type === 'Identifier' &&
node.declarations[0].id.name === identifierName &&
node.declarations[0].init.type === 'ObjectExpression'
)
if (identifierDefinition) {
core.info('Found configuration object in indirect default export declaration')
return identifierDefinition.declarations[0].init
}
}

// Try to find a module export
var moduleExport = ast.body.find(
node =>
Expand Down Expand Up @@ -171,7 +189,7 @@ class ConfigParser {
var depth = 0
const properties = propertyName.split('.')
var lastNode = configurationObject
while (1) {
while (true) {
// Find the node for the current property
var propertyNode = this.findProperty(lastNode, properties[depth])

Expand Down
38 changes: 36 additions & 2 deletions src/config-parser.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const fs = require('fs')
const core = require('@actions/core')

const { ConfigParser } = require('./config-parser')
const { getTempFolder, compareFiles } = require('./test-helpers')
Expand All @@ -11,7 +12,6 @@ const cases = [
//
// Default export
//

{
property: 'property',
source: `export default {}`,
Expand Down Expand Up @@ -89,6 +89,30 @@ const cases = [
expected: `export default { a2: false, a1: { a2: "value", a3: [12]}}`
},

//
// Indirect default export
//
{
property: 'property',
source: `const config = {}; export default config`,
expected: `const config = { property: "value"}; export default config`
},
{
property: 'property',
source: `var config = {}; export default config`,
expected: `var config = { property: "value"}; export default config`
},
{
property: 'a.b.c',
source: `var config = {}; export default config`,
expected: `var config = { a: { b: { c: "value"}}}; export default config`
},
{
property: 'a.b.c',
source: `var config = { a: { b: [], c: "hello"}}; export default config`,
expected: `var config = { a: { b: { c: "value"}, c: "hello"}}; export default config`
},

//
// Direct module exports
//
Expand Down Expand Up @@ -134,8 +158,18 @@ const cases = [
]

describe('config-parser', () => {
beforeEach(() => {
jest.restoreAllMocks()

// Mock error/warning/info/debug to silence their output
jest.spyOn(core, 'error').mockImplementation(jest.fn())
jest.spyOn(core, 'warning').mockImplementation(jest.fn())
jest.spyOn(core, 'info').mockImplementation(jest.fn())
jest.spyOn(core, 'debug').mockImplementation(jest.fn())
})

cases.forEach(({ property, source, expected }, index) => {
it(`Inject path properly for case #${index}`, () => {
it(`injects path properly for case #${index}`, () => {
// Write the source file
const sourceFile = `${tempFolder}/source.js`
fs.writeFileSync(sourceFile, source, { encoding: 'utf8' })
Expand Down
1 change: 1 addition & 0 deletions src/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ function getRequiredVars() {
repositoryNwo: process.env.GITHUB_REPOSITORY,
githubToken: core.getInput('token'),
staticSiteGenerator: core.getInput('static_site_generator'),
generatorConfigFile: core.getInput('generator_config_file'),
enablement: core.getInput('enablement') !== 'false'
}
}
Expand Down
7 changes: 7 additions & 0 deletions src/fixtures/gatsby/default.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
siteMetadata: {
title: `My Gatsby Site`,
siteUrl: `https://www.yourdomain.tld`,
},
plugins: [],
}
8 changes: 8 additions & 0 deletions src/fixtures/gatsby/default.expected.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
pathPrefix: "/docs/",
siteMetadata: {
title: `My Gatsby Site`,
siteUrl: `https://www.yourdomain.tld`,
},
plugins: [],
}
8 changes: 8 additions & 0 deletions src/fixtures/gatsby/default.expected.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export default {
pathPrefix: "/docs/",
siteMetadata: {
title: `My Gatsby Site`,
siteUrl: `https://www.yourdomain.tld`,
},
plugins: [],
}
7 changes: 7 additions & 0 deletions src/fixtures/gatsby/default.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default {
siteMetadata: {
title: `My Gatsby Site`,
siteUrl: `https://www.yourdomain.tld`,
},
plugins: [],
}
7 changes: 7 additions & 0 deletions src/fixtures/next/default.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
}

module.exports = nextConfig
9 changes: 9 additions & 0 deletions src/fixtures/next/default.expected.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {images: {unoptimized: true}},
basePath: '/docs',
reactStrictMode: true,
swcMinify: true
}

module.exports = nextConfig
9 changes: 9 additions & 0 deletions src/fixtures/next/default.expected.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {images: {unoptimized: true}},
basePath: '/docs',
reactStrictMode: true,
swcMinify: true
}

export default nextConfig
7 changes: 7 additions & 0 deletions src/fixtures/next/default.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
}

export default nextConfig
15 changes: 15 additions & 0 deletions src/fixtures/nuxt/async.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const getAllDynamicRoute = async function() {
const routes = await (async () => {
return ['/posts/hello-world', '/posts/hello-again'];
})();
return routes;
};

module.exports = {
mode: 'universal',
generate: {
async routes () {
return getAllDynamicRoute();
}
}
};
17 changes: 17 additions & 0 deletions src/fixtures/nuxt/async.expected.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const getAllDynamicRoute = async function() {
const routes = await (async () => {
return ['/posts/hello-world', '/posts/hello-again'];
})();
return routes;
};

module.exports = {
target: 'static',
router: {base: '/docs/'},
mode: 'universal',
generate: {
async routes () {
return getAllDynamicRoute();
}
}
};
17 changes: 17 additions & 0 deletions src/fixtures/nuxt/async.expected.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const getAllDynamicRoute = async function() {
const routes = await (async () => {
return ['/posts/hello-world', '/posts/hello-again'];
})();
return routes;
};

export default {
target: 'static',
router: {base: '/docs/'},
mode: 'universal',
generate: {
async routes () {
return getAllDynamicRoute();
}
}
};
15 changes: 15 additions & 0 deletions src/fixtures/nuxt/async.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const getAllDynamicRoute = async function() {
const routes = await (async () => {
return ['/posts/hello-world', '/posts/hello-again'];
})();
return routes;
};

export default {
mode: 'universal',
generate: {
async routes () {
return getAllDynamicRoute();
}
}
};
Loading

0 comments on commit 15f519f

Please sign in to comment.