65 Commits

Author SHA1 Message Date
James M. Greene
f71d3d08f0 Merge pull request #16 from AndrewLester/ssg-sveltekit
Add SvelteKit as an option for static_site_generator setting
2022-08-17 14:42:52 -05:00
James M. Greene
9ff7f29195 Update dist map 2022-08-17 14:41:47 -05:00
James M. Greene
9b7553ef7f Change environment variable data type to explicit string 2022-08-17 14:34:23 -05:00
AndrewLester
42451665cc Run prepare script 2022-08-10 16:28:32 -04:00
AndrewLester
adc528a6d8 Export GITHUB_PAGES env variable 2022-08-10 16:28:32 -04:00
AndrewLester
789c331a21 Support new features from #15 2022-08-10 16:28:32 -04:00
AndrewLester
ff1182a56a Add SvelteKit to action yml 2022-08-10 16:28:32 -04:00
AndrewLester
c872edcdfb Update config parser to support export default with identifier and add SvelteKit code
Co-authored-by: NatoBoram <natoboram@users.noreply.github.com>
2022-08-10 16:28:31 -04:00
James M. Greene
c61e34fb27 Merge pull request #12 from actions/better-docs
Improve a few contribution notes in the README
2022-08-10 14:19:56 -05:00
James M. Greene
a220556ffe Merge branch 'main' into better-docs 2022-08-10 14:10:38 -05:00
James M. Greene
491169de17 Revise release procedure 2022-08-10 14:10:15 -05:00
James M. Greene
f19391002a Merge pull request #17 from actions/marketplace-action-rename
Rename to include "GitHub" in "GitHub Pages" for Marketplace
2022-08-10 13:58:37 -05:00
James M. Greene
742be05113 Update action.yml 2022-08-10 12:52:41 -05:00
James M. Greene
90b7c04b80 Merge branch 'main' into better-docs 2022-08-10 10:00:39 -05:00
James M. Greene
15f519fab9 Merge pull request #15 from actions/ssg-config-file-input
Add support for specifying the SSG configuration file path
2022-08-10 09:18:00 -05:00
James M. Greene
f5b4063a62 Update distributables properly 2022-08-10 09:02:07 -05:00
James M. Greene
d06799dbbe Fix typo in dist 2022-08-10 08:57:37 -05:00
James M. Greene
fad78054b6 Fix typo in src 2022-08-10 08:56:12 -05:00
James M. Greene
64fa685553 Rebuild distributables 2022-08-09 11:23:03 -05:00
James M. Greene
891eba7f6e Update src/config-parser.js
Co-authored-by: Yoann Chaudet <yoannchaudet@github.com>
2022-08-09 11:22:14 -05:00
James M. Greene
9f6ed02477 Tweak the title and description in README 2022-08-08 11:15:41 -05:00
James M. Greene
68595d0746 Update distributables 2022-08-05 17:47:09 -05:00
James M. Greene
4f27d51853 Add support for indirect default export declarations 2022-08-05 17:44:40 -05:00
James M. Greene
1395534a78 Hoist important arrays to top-level constants 2022-08-05 17:37:00 -05:00
James M. Greene
7c3932ff89 Add support for specifying the target generator config file 2022-08-05 17:35:23 -05:00
James M. Greene
404d23c4a6 Merge pull request #13 from actions/prettier
Prettier formatting
2022-08-05 17:29:38 -05:00
James M. Greene
06406d74b2 Merge branch 'main' into prettier 2022-08-05 17:28:54 -05:00
James M. Greene
cc95980c79 Merge pull request #14 from actions/workflow-audit
Workflow audit
2022-08-05 17:28:32 -05:00
James M. Greene
4f84ed2a14 Add concurrency settings to PR-based workflows 2022-08-05 15:54:53 -05:00
James M. Greene
f19d25133d Ensure minimal permissions are explicit on all workflows 2022-08-05 15:54:15 -05:00
James M. Greene
f24e879a69 Add concurrency and permissions to workflow 2022-08-05 15:44:58 -05:00
James M. Greene
da85ca493f Update fixtures with Prettier formatting 2022-08-05 15:40:25 -05:00
James M. Greene
d949e1515f Rename Prettier config file extension for consistency 2022-08-05 15:39:17 -05:00
James M. Greene
c69bbc2c2c Fix one expected test fixture given Prettier configuration 2022-08-05 15:35:48 -05:00
James M. Greene
8441c1b1dc Improve a few contribution notes in the README 2022-08-05 15:29:09 -05:00
James M. Greene
4036d0f035 Add a workflow to verify Prettier formatting 2022-08-05 15:28:22 -05:00
James M. Greene
5c1535b807 Update all source files to match expected Prettier formatting 2022-08-05 15:26:05 -05:00
James M. Greene
e22fa7ebed Merge pull request #11 from actions/improve-action-manifest
Improve Actions manifest
2022-08-05 13:40:43 -05:00
James M. Greene
635cafe472 Use single quotes everywhere for consistency in Actions manifest 2022-08-05 13:29:15 -05:00
James M. Greene
7c6340377c Add author to Action manifest 2022-08-05 13:28:40 -05:00
James M. Greene
542786ddbc Improve and shorten description for Marketplace publication 2022-08-05 13:27:44 -05:00
James M. Greene
c4a801b850 Merge pull request #9 from actions/dist-check-workflow
Add workflow to verify distributables are built
2022-08-05 13:10:05 -05:00
James M. Greene
fcc627b194 Merge branch 'main' into dist-check-workflow 2022-08-05 13:09:06 -05:00
James M. Greene
2fc7b604aa Add explicit permissions to workflow 2022-08-05 13:08:52 -05:00
James M. Greene
bcfa2c863c Merge pull request #8 from actions/cleanup-test-workflow
Cleanup formatting of test workflow
2022-08-05 13:07:40 -05:00
James M. Greene
c95cb0d322 Merge pull request #7 from actions/pkg-metadata
Correct a few metadata field values in the `package.json`
2022-08-05 13:07:25 -05:00
James M. Greene
d2f9056bbc Merge pull request #6 from actions/optional-enablement
Make Pages enablement (and write permissions) optional
2022-08-05 13:06:58 -05:00
James M. Greene
b619d6bb2a Make certain the env var isn't present during testing 2022-08-05 12:59:28 -05:00
James M. Greene
1f779755f8 Readd distributables 2022-08-05 12:13:48 -05:00
James M. Greene
bce63914b1 Incorporate the spirit of changes from https://github.com/actions/configure-pages/pull/10 2022-08-05 12:13:23 -05:00
James M. Greene
0a94d4c3bb Merge branch 'main' into optional-enablement 2022-08-05 12:05:17 -05:00
Mingzi
d868d5fe4e Merge pull request #10 from actions/fix-hard-coded-api-endpoint
Fix hardcoded api endpoint
2022-08-05 09:55:37 -07:00
yimysty
d8dd1327a1 fix hardcoded api endpoint 2022-08-05 09:52:17 -07:00
James M. Greene
2a2b0fadb6 Remove diff of 'pre' since this Action doesn't have that directory 2022-08-03 21:47:18 -05:00
James M. Greene
e2ea66d572 Revise comment 2022-08-03 21:46:57 -05:00
James M. Greene
55225928a1 Add workflow to verify distributables are built 2022-08-03 18:30:55 -05:00
James M. Greene
62a7d4f2dc Cleanup formatting of test workflow 2022-08-03 18:30:19 -05:00
James M. Greene
929a1c7425 Correct a few metadata field values in the package.json 2022-08-03 18:24:31 -05:00
James M. Greene
17536ca11a Update organization name in tests 2022-08-03 18:19:57 -05:00
James M. Greene
d801b818b5 Update dist 2022-08-03 18:10:24 -05:00
James M. Greene
fc0fb71264 Delete old modules 2022-08-03 18:10:04 -05:00
James M. Greene
af945d6133 Update index.js to utilize new modules 2022-08-03 18:09:46 -05:00
James M. Greene
b2561d383d Add dedicated Actions-outputs module 2022-08-03 18:09:04 -05:00
James M. Greene
bb42d7b1cb Add new API client to consolidate REST API calls 2022-08-03 18:08:29 -05:00
James M. Greene
0455a16aca Allow a user to manually opt-out of Pages site enablement 2022-08-02 20:45:01 -05:00
60 changed files with 1264 additions and 498 deletions

52
.github/workflows/check-dist.yml vendored Normal file
View File

@@ -0,0 +1,52 @@
# When you reference this Action with `uses:` in a workflow,
# `dist/index.js` is the code that will run.
# For our project, we generate this file using `ncc`.
# We need to make sure the checked-in `dist/index.js` actually matches what we expect it to be.
name: Check dist/
on:
push:
branches:
- main
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
workflow_dispatch:
permissions:
contents: read
# This allows a subsequently queued workflow run to interrupt previous runs
concurrency:
group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
cancel-in-progress: true
jobs:
check-dist:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: 16.x
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Rebuild the dist/ directory
run: npm run prepare
- name: Compare the expected and actual dist/ directories
run: |
if [ "$(git diff --ignore-space-at-eol dist/ | wc -l)" -gt "0" ]; then
echo "Detected uncommitted changes after build in dist folder. See status below:"
git diff
exit 1
fi

34
.github/workflows/check-formatting.yml vendored Normal file
View File

@@ -0,0 +1,34 @@
name: Checking formatting
on:
push:
branches:
- main
pull_request:
permissions:
contents: read
# This allows a subsequently queued workflow run to interrupt previous runs
concurrency:
group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
cancel-in-progress: true
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Node.JS
uses: actions/setup-node@v3
with:
node-version: 16.x
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Verify formatting
run: npm run format:check

View File

@@ -4,6 +4,9 @@ on:
branches:
- main
permissions:
contents: write
jobs:
draft-release:
runs-on: ubuntu-latest

View File

@@ -6,20 +6,29 @@ on:
- main
pull_request:
permissions:
contents: read
# This allows a subsequently queued workflow run to interrupt previous runs
concurrency:
group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
cancel-in-progress: true
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Checkout
uses: actions/checkout@v3
- name: Set Node.JS
uses: actions/setup-node@v3
with:
node-version: 16.x
- name: Setup Node.JS
uses: actions/setup-node@v3
with:
node-version: 16.x
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test

View File

@@ -1,10 +1,10 @@
# Prettier (formatter) configuration
---
printWidth: 80
printWidth: 120
tabWidth: 2
useTabs: false
semi: false
singleQuote: true
trailingComma: none
bracketSpacing: false
bracketSpacing: true
arrowParens: avoid

View File

@@ -1,8 +1,8 @@
# Configure-Pages
# configure-pages
An action to enable Pages and extract various metadata about a site. It can also be used to configure various static site generators we support as [starter workflows][starter-workflows].
A GitHub Action to enable Pages and extract various metadata about a site. It can also be used to configure various static site generators we support as [starter workflows][starter-workflows].
See [`set-pages-path.js`](./src/set-pages-path.js) for more details on how we configure static site generators to work "out of the box" with GitHub Pages.
See [`set-pages-path.js`](src/set-pages-path.js) for more details on how we configure static site generators to work "out of the box" with GitHub Pages.
# Usage
@@ -12,18 +12,13 @@ See [action.yml](action.yml) and the [Pages starter workflows][starter-workflows
In order to release a new version of this Action:
1. Locate the semantic version of the upcoming release (a draft is maintained by the [`draft-release` workflow][draft-release])
1. Locate the semantic version of the [upcoming release][release-list] (a draft is maintained by the [`draft-release` workflow][draft-release]).
2. Push a matching tag, for instance for `v0.1.0`:
2. Publish the draft release from the `main` branch with semantic version as the tag name, _with_ the checkbox to publish to the GitHub Marketplace checked. :ballot_box_with_check:
```bash
git tag v0.1.0
git push origin v0.1.0
```
3. After publishing the release, the [`release` workflow][release] will automatically run to create/update the corresponding the major version tag such as `v0`.
3. Publish the draft release (the major tag such as `v0` will be created/updated by the [`release` workflow][release])
⚠️ Environment approval is required.
⚠️ Environment approval is required. Check the [Release workflow run list][release-workflow-runs].
# License
@@ -31,5 +26,7 @@ The scripts and documentation in this project are released under the [MIT Licens
<!-- references -->
[starter-workflows]: https://github.com/actions/starter-workflows/tree/main/pages
[release-list]: /releases
[draft-release]: .github/workflows/draft-release.yml
[release]: .github/workflows/release.yml
[release]: .github/workflows/release.yml
[release-workflow-runs]: /actions/workflows/release.yml

View File

@@ -1,16 +1,24 @@
name: "Configure Pages"
description: "An action to enable Pages and extract various metadata about a site. It can also be used to configure various static site generators we support as starter workflows."
name: 'Configure GitHub Pages'
description: 'A GitHub Action to enable Pages, extract various metadata about a site, and configure some supported static site generators.'
author: 'GitHub'
runs:
using: "node16"
main: "dist/index.js"
using: 'node16'
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", "gatsby", or "sveltekit"'
required: false
generator_config_file:
description: 'Optional file path to static site generator configuration file'
required: false
token:
description: "GitHub token"
description: 'GitHub token'
default: ${{ github.token }}
required: true
enablement:
description: 'Should a Pages site be enabled for the repository if not so already?'
default: 'true'
required: false
outputs:
base_url:
description: 'GitHub Pages site full base URL. Examples: "https://octocat.github.io/my-repo/", "https://octocat.github.io/", "https://www.example.com/"'

300
dist/index.js vendored
View File

@@ -14423,6 +14423,104 @@ if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) {
exports.debug = debug; // for test
/***/ }),
/***/ 9432:
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
const axios = __nccwpck_require__(6545)
const core = __nccwpck_require__(2186)
function getApiBaseUrl() {
return process.env.GITHUB_API_URL || 'https://api.github.com'
}
async function enablePagesSite({ repositoryNwo, githubToken }) {
const pagesEndpoint = `${getApiBaseUrl()}/repos/${repositoryNwo}/pages`
try {
const response = await axios.post(
pagesEndpoint,
{ build_type: 'workflow' },
{
headers: {
Accept: 'application/vnd.github.v3+json',
Authorization: `Bearer ${githubToken}`,
'Content-type': 'application/json'
}
}
)
const pageObject = response.data
return pageObject
} catch (error) {
if (error.response && error.response.status === 409) {
return null
}
throw error
}
}
async function getPagesSite({ repositoryNwo, githubToken }) {
try {
const pagesEndpoint = `${getApiBaseUrl()}/repos/${repositoryNwo}/pages`
const response = await axios.get(pagesEndpoint, {
headers: {
Accept: 'application/vnd.github.v3+json',
Authorization: `Bearer ${githubToken}`
}
})
const pageObject = response.data
return pageObject
} catch (error) {
throw error
}
}
async function findOrCreatePagesSite({ repositoryNwo, githubToken, enablement = true }) {
let pageObject
// Try to find an existing Pages site first
try {
pageObject = await getPagesSite({ repositoryNwo, githubToken })
} catch (error) {
if (!enablement) {
core.error('Get Pages site failed', error)
throw error
}
core.warning('Get Pages site failed', error)
}
if (!pageObject && enablement) {
// Create a new Pages site if one doesn't exist
try {
pageObject = await enablePagesSite({ repositoryNwo, githubToken })
} catch (error) {
core.error('Create Pages site failed', error)
throw error
}
// This somehow implies that the Pages site was already created but initially failed to be retrieved.
// Try one more time for this extreme edge case!
if (pageObject == null) {
try {
pageObject = await getPagesSite({ repositoryNwo, githubToken })
} catch (error) {
core.error('Get Pages site still failed', error)
throw error
}
}
}
return pageObject
}
module.exports = { findOrCreatePagesSite, enablePagesSite, getPagesSite, getApiBaseUrl }
/***/ }),
/***/ 8395:
@@ -14461,7 +14559,7 @@ class ConfigParser {
// Ctor
// - configurationFile: path to the configuration file
// - blankConfigurationFile: a blank configuration file to use if non was previously found
constructor({configurationFile, blankConfigurationFile, properties}) {
constructor({ configurationFile, blankConfigurationFile, properties }) {
// Save field
this.configurationFile = configurationFile
this.properties = properties
@@ -14486,16 +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 =>
@@ -14510,19 +14624,13 @@ class ConfigParser {
)
// Direct module export
if (
moduleExport &&
moduleExport.expression.right.type === 'ObjectExpression'
) {
if (moduleExport && moduleExport.expression.right.type === 'ObjectExpression') {
core.info('Found configuration object in direct module export')
return moduleExport.expression.right
}
// Indirect module export
else if (
moduleExport &&
moduleExport.expression.right.type === 'Identifier'
) {
else if (moduleExport && moduleExport.expression.right.type === 'Identifier') {
const identifierName = moduleExport && moduleExport.expression.right.name
const identifierDefinition = ast.body.find(
node =>
@@ -14550,9 +14658,7 @@ class ConfigParser {
// Try to find a property matching a given name
const property =
object.type === 'ObjectExpression' &&
object.properties.find(
node => node.key.type === 'Identifier' && node.key.name === name
)
object.properties.find(node => node.key.type === 'Identifier' && node.key.name === name)
// Return the property's value (if found) or null
if (property) {
@@ -14572,9 +14678,7 @@ class ConfigParser {
return `${properties[startIndex]}: ${JSON.stringify(propertyValue)}`
} else {
return (
`${properties[startIndex]}: {` +
this.getPropertyDeclaration(properties, startIndex + 1, propertyValue) +
'}'
`${properties[startIndex]}: {` + this.getPropertyDeclaration(properties, startIndex + 1, propertyValue) + '}'
)
}
}
@@ -14613,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])
@@ -14652,11 +14756,7 @@ class ConfigParser {
// Create nested properties in the configuration file
else {
// Build the declaration to inject
const declaration = this.getPropertyDeclaration(
properties,
depth,
propertyValue
)
const declaration = this.getPropertyDeclaration(properties, depth, propertyValue)
// The last node identified is an object expression, so do the assignment
if (lastNode.type === 'ObjectExpression') {
@@ -14703,7 +14803,7 @@ class ConfigParser {
}
}
module.exports = {ConfigParser}
module.exports = { ConfigParser }
/***/ }),
@@ -14718,7 +14818,9 @@ function getRequiredVars() {
return {
repositoryNwo: process.env.GITHUB_REPOSITORY,
githubToken: core.getInput('token'),
staticSiteGenerator: core.getInput('static_site_generator')
staticSiteGenerator: core.getInput('static_site_generator'),
generatorConfigFile: core.getInput('generator_config_file'),
enablement: core.getInput('enablement') !== 'false'
}
}
@@ -14734,90 +14836,24 @@ function getContext() {
return requiredVars
}
module.exports = {getContext}
module.exports = { getContext }
/***/ }),
/***/ 5424:
/***/ 7527:
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
const core = __nccwpck_require__(2186)
const axios = __nccwpck_require__(6545)
async function enablePages({repositoryNwo, githubToken}) {
const pagesEndpoint = `https://api.github.com/repos/${repositoryNwo}/pages`
try {
const response = await axios.post(
pagesEndpoint,
{build_type: 'workflow'},
{
headers: {
Accept: 'application/vnd.github.v3+json',
Authorization: `Bearer ${githubToken}`,
'Content-type': 'application/json'
}
}
)
core.info('Created pages site')
} catch (error) {
if (error.response && error.response.status === 409) {
core.info('Pages site exists')
return
}
core.error("Couldn't create pages site", error)
throw error
}
function outputPagesBaseUrl(siteUrl) {
core.setOutput('base_url', siteUrl.href)
core.setOutput('origin', siteUrl.origin)
core.setOutput('host', siteUrl.host)
core.setOutput('base_path', siteUrl.pathname)
}
module.exports = enablePages
/***/ }),
/***/ 9965:
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
const core = __nccwpck_require__(2186)
const axios = __nccwpck_require__(6545)
const {setPagesPath} = __nccwpck_require__(4770)
async function getPagesBaseUrl({
repositoryNwo,
githubToken,
staticSiteGenerator
}) {
try {
const pagesEndpoint = `https://api.github.com/repos/${repositoryNwo}/pages`
core.info(`Get the Base URL to the page with endpoint ${pagesEndpoint}`)
const response = await axios.get(pagesEndpoint, {
headers: {
Accept: 'application/vnd.github.v3+json',
Authorization: `Bearer ${githubToken}`
}
})
pageObject = response.data
core.info(JSON.stringify(pageObject))
const siteUrl = new URL(pageObject.html_url)
if (staticSiteGenerator) {
setPagesPath({staticSiteGenerator, path: siteUrl.pathname})
}
core.setOutput('base_url', siteUrl.href)
core.setOutput('origin', siteUrl.origin)
core.setOutput('host', siteUrl.host)
core.setOutput('base_path', siteUrl.pathname)
} catch (error) {
core.error('Get on the Page failed', error)
throw error
}
}
module.exports = getPagesBaseUrl
module.exports = outputPagesBaseUrl
/***/ }),
@@ -14826,15 +14862,15 @@ module.exports = getPagesBaseUrl
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
const core = __nccwpck_require__(2186)
const {ConfigParser} = __nccwpck_require__(8395)
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
@@ -14852,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
@@ -14865,23 +14901,37 @@ 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
pathPrefix: path
}
}
case 'sveltekit':
// SvelteKit does not want a trailing slash
if (path.endsWith('/')) {
path = path.slice(0, -1)
}
return {
configurationFile: generatorConfigFile || './svelte.config.js',
blankConfigurationFile: __nccwpck_require__.ab + "sveltekit.js",
properties: {
// Configure a base path
'kit.paths.base': path
}
}
default:
throw `Unsupported static site generator: ${staticSiteGenerator}`
}
}
// 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
@@ -14892,7 +14942,7 @@ function setPagesPath({staticSiteGenerator, path}) {
}
}
module.exports = {getConfigParserSettings, setPagesPath}
module.exports = { getConfigParserSettings, setPagesPath }
/***/ }),
@@ -16375,17 +16425,25 @@ var __webpack_exports__ = {};
(() => {
const core = __nccwpck_require__(2186)
const enablePages = __nccwpck_require__(5424)
const getPagesBaseUrl = __nccwpck_require__(9965)
// All variables we need from the runtime are loaded here
const {getContext} = __nccwpck_require__(1319)
const { getContext } = __nccwpck_require__(1319)
const { findOrCreatePagesSite } = __nccwpck_require__(9432)
const { setPagesPath } = __nccwpck_require__(4770)
const outputPagesBaseUrl = __nccwpck_require__(7527)
async function main() {
try {
const context = getContext()
await enablePages(context)
await getPagesBaseUrl(context)
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, generatorConfigFile, path: siteUrl.pathname })
}
outputPagesBaseUrl(siteUrl)
core.exportVariable('GITHUB_PAGES', 'true')
} catch (error) {
core.setFailed(error)
process.exit(1)

2
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

8
dist/sveltekit.js vendored Normal file
View File

@@ -0,0 +1,8 @@
// Default Pages configuration for SvelteKit
import adapter from '@sveltejs/adapter-auto'
export default {
kit: {
adapter: adapter()
}
}

View File

@@ -1,22 +1,25 @@
{
"private": true,
"name": "configure-pages",
"version": "1.0.0",
"description": "An action to enable Pages and extract various metadata about a site. It can also be used to configure various static site generators we support as starter workflows.",
"main": "src/index.js",
"description": "A GitHub Action to enable Pages and extract various metadata about a site. It can also be used to configure various static site generators we support as starter workflows.",
"main": "./dist/index.js",
"scripts": {
"prepare": "ncc build src/index.js -o dist --source-map --license licenses.txt",
"format": "prettier --write 'src/**/*.js'",
"format:check": "prettier --check 'src/**/*.js'",
"prepare": "npm run format && ncc build src/index.js -o dist --source-map --license licenses.txt",
"test": "jest"
},
"repository": {
"type": "git",
"url": "git+https://github.com/paper-spa/configure-pages.git"
"url": "git+https://github.com/actions/configure-pages.git"
},
"author": "GitHub",
"license": "MIT",
"bugs": {
"url": "https://github.com/paper-spa/configure-pages/issues"
"url": "https://github.com/actions/configure-pages/issues"
},
"homepage": "https://github.com/paper-spa/configure-pages#readme",
"homepage": "https://github.com/actions/configure-pages#readme",
"dependencies": {
"@actions/core": "^1.8.2",
"axios": "^0.27.2",

91
src/api-client.js Normal file
View File

@@ -0,0 +1,91 @@
const axios = require('axios')
const core = require('@actions/core')
function getApiBaseUrl() {
return process.env.GITHUB_API_URL || 'https://api.github.com'
}
async function enablePagesSite({ repositoryNwo, githubToken }) {
const pagesEndpoint = `${getApiBaseUrl()}/repos/${repositoryNwo}/pages`
try {
const response = await axios.post(
pagesEndpoint,
{ build_type: 'workflow' },
{
headers: {
Accept: 'application/vnd.github.v3+json',
Authorization: `Bearer ${githubToken}`,
'Content-type': 'application/json'
}
}
)
const pageObject = response.data
return pageObject
} catch (error) {
if (error.response && error.response.status === 409) {
return null
}
throw error
}
}
async function getPagesSite({ repositoryNwo, githubToken }) {
try {
const pagesEndpoint = `${getApiBaseUrl()}/repos/${repositoryNwo}/pages`
const response = await axios.get(pagesEndpoint, {
headers: {
Accept: 'application/vnd.github.v3+json',
Authorization: `Bearer ${githubToken}`
}
})
const pageObject = response.data
return pageObject
} catch (error) {
throw error
}
}
async function findOrCreatePagesSite({ repositoryNwo, githubToken, enablement = true }) {
let pageObject
// Try to find an existing Pages site first
try {
pageObject = await getPagesSite({ repositoryNwo, githubToken })
} catch (error) {
if (!enablement) {
core.error('Get Pages site failed', error)
throw error
}
core.warning('Get Pages site failed', error)
}
if (!pageObject && enablement) {
// Create a new Pages site if one doesn't exist
try {
pageObject = await enablePagesSite({ repositoryNwo, githubToken })
} catch (error) {
core.error('Create Pages site failed', error)
throw error
}
// This somehow implies that the Pages site was already created but initially failed to be retrieved.
// Try one more time for this extreme edge case!
if (pageObject == null) {
try {
pageObject = await getPagesSite({ repositoryNwo, githubToken })
} catch (error) {
core.error('Get Pages site still failed', error)
throw error
}
}
}
return pageObject
}
module.exports = { findOrCreatePagesSite, enablePagesSite, getPagesSite, getApiBaseUrl }

215
src/api-client.test.js Normal file
View File

@@ -0,0 +1,215 @@
const core = require('@actions/core')
const axios = require('axios')
const apiClient = require('./api-client')
describe('apiClient', () => {
const GITHUB_REPOSITORY = 'actions/is-awesome'
const GITHUB_TOKEN = 'gha-token'
const PAGE_OBJECT = { html_url: 'https://actions.github.io/is-awesome/' }
beforeEach(() => {
jest.restoreAllMocks()
// Mock error/warning/info/debug
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())
})
describe('getApiBaseUrl', () => {
it('returns GITHUB_API_URL environment variable when set', async () => {
const expectedBaseUrl = 'https://api.ghe.com'
process.env.GITHUB_API_URL = expectedBaseUrl
const result = apiClient.getApiBaseUrl()
delete process.env.GITHUB_API_URL
expect(result).toEqual(expectedBaseUrl)
})
it('defaults to GitHub API if GITHUB_API_URL environment variable is empty', async () => {
process.env.GITHUB_API_URL = ''
const result = apiClient.getApiBaseUrl()
delete process.env.GITHUB_API_URL
expect(result).toEqual('https://api.github.com')
})
it('defaults to GitHub API if GITHUB_API_URL environment variable is not set', async () => {
delete process.env.GITHUB_API_URL
const result = apiClient.getApiBaseUrl()
expect(result).toEqual('https://api.github.com')
})
})
describe('enablePagesSite', () => {
it('makes a request to create a page', async () => {
jest.spyOn(axios, 'post').mockImplementationOnce(() => Promise.resolve({ status: 201, data: PAGE_OBJECT }))
const result = await apiClient.enablePagesSite({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN
})
expect(result).toEqual(PAGE_OBJECT)
})
it('handles a 409 response when the page already exists', async () => {
jest.spyOn(axios, 'post').mockImplementationOnce(() => Promise.reject({ response: { status: 409 } }))
// Simply assert that no error is raised
const result = await apiClient.enablePagesSite({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN
})
expect(result).toBe(null)
})
it('re-raises errors on failure status codes', async () => {
jest.spyOn(axios, 'post').mockImplementationOnce(() => Promise.reject({ response: { status: 404 } }))
let erred = false
try {
await apiClient.enablePagesSite({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN
})
} catch (error) {
erred = true
expect(error.response.status).toEqual(404)
}
expect(erred).toBe(true)
})
})
describe('getPagesSite', () => {
it('makes a request to get a page', async () => {
const PAGE_OBJECT = { html_url: 'https://actions.github.io/is-awesome/' }
jest.spyOn(axios, 'get').mockImplementationOnce(() => Promise.resolve({ status: 200, data: PAGE_OBJECT }))
const result = await apiClient.getPagesSite({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN
})
expect(result).toEqual(PAGE_OBJECT)
})
it('re-raises errors on failure status codes', async () => {
jest.spyOn(axios, 'get').mockImplementationOnce(() => Promise.reject({ response: { status: 404 } }))
let erred = false
try {
await apiClient.getPagesSite({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN
})
} catch (error) {
erred = true
expect(error.response.status).toEqual(404)
}
expect(erred).toBe(true)
})
})
describe('findOrCreatePagesSite', () => {
it('does not make a request to create a page if it already exists', async () => {
const PAGE_OBJECT = { html_url: 'https://actions.github.io/is-awesome/' }
jest.spyOn(axios, 'get').mockImplementationOnce(() => Promise.resolve({ status: 200, data: PAGE_OBJECT }))
jest.spyOn(axios, 'post').mockImplementationOnce(() => Promise.reject({ response: { status: 404 } }))
const result = await apiClient.findOrCreatePagesSite({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN
})
expect(result).toEqual(PAGE_OBJECT)
expect(axios.get).toHaveBeenCalledTimes(1)
expect(axios.post).toHaveBeenCalledTimes(0)
})
it('makes request to create a page by default if it does not exist', async () => {
const PAGE_OBJECT = { html_url: 'https://actions.github.io/is-awesome/' }
jest.spyOn(axios, 'get').mockImplementationOnce(() => Promise.reject({ response: { status: 404 } }))
jest.spyOn(axios, 'post').mockImplementationOnce(() => Promise.resolve({ status: 201, data: PAGE_OBJECT }))
const result = await apiClient.findOrCreatePagesSite({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN
})
expect(result).toEqual(PAGE_OBJECT)
expect(axios.get).toHaveBeenCalledTimes(1)
expect(axios.post).toHaveBeenCalledTimes(1)
})
it('makes a request to create a page when explicitly enabled if it does not exist', async () => {
const PAGE_OBJECT = { html_url: 'https://actions.github.io/is-awesome/' }
jest.spyOn(axios, 'get').mockImplementationOnce(() => Promise.reject({ response: { status: 404 } }))
jest.spyOn(axios, 'post').mockImplementationOnce(() => Promise.resolve({ status: 201, data: PAGE_OBJECT }))
const result = await apiClient.findOrCreatePagesSite({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN,
enablement: true
})
expect(result).toEqual(PAGE_OBJECT)
expect(axios.get).toHaveBeenCalledTimes(1)
expect(axios.post).toHaveBeenCalledTimes(1)
})
it('does not make a request to create a page when explicitly disabled even if it does not exist', async () => {
jest.spyOn(axios, 'get').mockImplementationOnce(() => Promise.reject({ response: { status: 404 } }))
jest.spyOn(axios, 'post').mockImplementationOnce(() => Promise.reject({ response: { status: 500 } })) // just so they both aren't 404
let erred = false
try {
await apiClient.findOrCreatePagesSite({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN,
enablement: false
})
} catch (error) {
erred = true
// re-raised error
expect(error.response.status).toEqual(404)
}
expect(erred).toBe(true)
expect(axios.get).toHaveBeenCalledTimes(1)
expect(axios.post).toHaveBeenCalledTimes(0)
})
it('does not make a second request to get page if create fails for reason other than existence', async () => {
jest.spyOn(axios, 'get').mockImplementationOnce(() => Promise.reject({ response: { status: 404 } }))
jest.spyOn(axios, 'post').mockImplementationOnce(() => Promise.reject({ response: { status: 500 } })) // just so they both aren't 404
let erred = false
try {
await apiClient.findOrCreatePagesSite({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN
})
} catch (error) {
erred = true
// re-raised error
expect(error.response.status).toEqual(500)
}
expect(erred).toBe(true)
expect(axios.get).toHaveBeenCalledTimes(1)
expect(axios.post).toHaveBeenCalledTimes(1)
})
it('makes second request to get page if create fails because of existence', async () => {
const PAGE_OBJECT = { html_url: 'https://actions.github.io/is-awesome/' }
jest
.spyOn(axios, 'get')
.mockImplementationOnce(() => Promise.reject({ response: { status: 404 } }))
.mockImplementationOnce(() => Promise.resolve({ status: 200, data: PAGE_OBJECT }))
jest.spyOn(axios, 'post').mockImplementationOnce(() => Promise.reject({ response: { status: 409 } }))
const result = await apiClient.findOrCreatePagesSite({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN
})
expect(result).toEqual(PAGE_OBJECT)
expect(axios.get).toHaveBeenCalledTimes(2)
expect(axios.post).toHaveBeenCalledTimes(1)
})
})
})

View File

@@ -0,0 +1,8 @@
// Default Pages configuration for SvelteKit
import adapter from '@sveltejs/adapter-auto'
export default {
kit: {
adapter: adapter()
}
}

View File

@@ -31,7 +31,7 @@ class ConfigParser {
// Ctor
// - configurationFile: path to the configuration file
// - blankConfigurationFile: a blank configuration file to use if non was previously found
constructor({configurationFile, blankConfigurationFile, properties}) {
constructor({ configurationFile, blankConfigurationFile, properties }) {
// Save field
this.configurationFile = configurationFile
this.properties = properties
@@ -56,16 +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 =>
@@ -80,19 +96,13 @@ class ConfigParser {
)
// Direct module export
if (
moduleExport &&
moduleExport.expression.right.type === 'ObjectExpression'
) {
if (moduleExport && moduleExport.expression.right.type === 'ObjectExpression') {
core.info('Found configuration object in direct module export')
return moduleExport.expression.right
}
// Indirect module export
else if (
moduleExport &&
moduleExport.expression.right.type === 'Identifier'
) {
else if (moduleExport && moduleExport.expression.right.type === 'Identifier') {
const identifierName = moduleExport && moduleExport.expression.right.name
const identifierDefinition = ast.body.find(
node =>
@@ -120,9 +130,7 @@ class ConfigParser {
// Try to find a property matching a given name
const property =
object.type === 'ObjectExpression' &&
object.properties.find(
node => node.key.type === 'Identifier' && node.key.name === name
)
object.properties.find(node => node.key.type === 'Identifier' && node.key.name === name)
// Return the property's value (if found) or null
if (property) {
@@ -142,9 +150,7 @@ class ConfigParser {
return `${properties[startIndex]}: ${JSON.stringify(propertyValue)}`
} else {
return (
`${properties[startIndex]}: {` +
this.getPropertyDeclaration(properties, startIndex + 1, propertyValue) +
'}'
`${properties[startIndex]}: {` + this.getPropertyDeclaration(properties, startIndex + 1, propertyValue) + '}'
)
}
}
@@ -183,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])
@@ -222,11 +228,7 @@ class ConfigParser {
// Create nested properties in the configuration file
else {
// Build the declaration to inject
const declaration = this.getPropertyDeclaration(
properties,
depth,
propertyValue
)
const declaration = this.getPropertyDeclaration(properties, depth, propertyValue)
// The last node identified is an object expression, so do the assignment
if (lastNode.type === 'ObjectExpression') {
@@ -273,4 +275,4 @@ class ConfigParser {
}
}
module.exports = {ConfigParser}
module.exports = { ConfigParser }

View File

@@ -1,7 +1,8 @@
const fs = require('fs')
const core = require('@actions/core')
const {ConfigParser} = require('./config-parser')
const {getTempFolder, compareFiles} = require('./test-helpers')
const { ConfigParser } = require('./config-parser')
const { getTempFolder, compareFiles } = require('./test-helpers')
// Get the temp folder
const tempFolder = getTempFolder()
@@ -11,7 +12,6 @@ const cases = [
//
// Default export
//
{
property: 'property',
source: `export default {}`,
@@ -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
//
@@ -134,15 +158,25 @@ const cases = [
]
describe('config-parser', () => {
cases.forEach(({property, source, expected}, index) => {
it(`Inject path properly for case #${index}`, () => {
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(`injects path properly for case #${index}`, () => {
// Write the source file
const sourceFile = `${tempFolder}/source.js`
fs.writeFileSync(sourceFile, source, {encoding: 'utf8'})
fs.writeFileSync(sourceFile, source, { encoding: 'utf8' })
// Write the expected file
const expectedFile = `${tempFolder}/expected.js`
fs.writeFileSync(expectedFile, expected, {encoding: 'utf8'})
fs.writeFileSync(expectedFile, expected, { encoding: 'utf8' })
// Update the settings and do the injection
new ConfigParser({

View File

@@ -5,7 +5,9 @@ function getRequiredVars() {
return {
repositoryNwo: process.env.GITHUB_REPOSITORY,
githubToken: core.getInput('token'),
staticSiteGenerator: core.getInput('static_site_generator')
staticSiteGenerator: core.getInput('static_site_generator'),
generatorConfigFile: core.getInput('generator_config_file'),
enablement: core.getInput('enablement') !== 'false'
}
}
@@ -21,4 +23,4 @@ function getContext() {
return requiredVars
}
module.exports = {getContext}
module.exports = { getContext }

View File

@@ -1,31 +0,0 @@
const core = require('@actions/core')
const axios = require('axios')
async function enablePages({repositoryNwo, githubToken}) {
const pagesEndpoint = `https://api.github.com/repos/${repositoryNwo}/pages`
try {
const response = await axios.post(
pagesEndpoint,
{build_type: 'workflow'},
{
headers: {
Accept: 'application/vnd.github.v3+json',
Authorization: `Bearer ${githubToken}`,
'Content-type': 'application/json'
}
}
)
core.info('Created pages site')
} catch (error) {
if (error.response && error.response.status === 409) {
core.info('Pages site exists')
return
}
core.error("Couldn't create pages site", error)
throw error
}
}
module.exports = enablePages

View File

@@ -1,55 +0,0 @@
const core = require('@actions/core')
const axios = require('axios')
const enablePages = require('./enable-pages')
describe('enablePages', () => {
const GITHUB_REPOSITORY = 'paper-spa/is-awesome'
const GITHUB_TOKEN = 'gha-token'
beforeEach(() => {
jest.restoreAllMocks()
// Mock error/warning/info/debug
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())
})
it('makes a request to create a page', async () => {
jest.spyOn(axios, 'post').mockImplementationOnce(() => Promise.resolve({}))
await enablePages({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN
})
})
it('handles a 409 response when the page already exists', async () => {
jest
.spyOn(axios, 'post')
.mockImplementationOnce(() => Promise.reject({response: {status: 409}}))
// Simply assert that no error is raised
await enablePages({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN
})
})
it('re-raises errors on failure status codes', async () => {
jest
.spyOn(axios, 'post')
.mockImplementationOnce(() => Promise.reject({response: {status: 404}}))
try {
await enablePages({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN
})
} catch (error) {
expect(error.response.status).toEqual(404)
}
})
})

View File

@@ -1,2 +1,2 @@
// Default Pages configuration for Gatsby
module.exports = { pathPrefix: "/docs/" }
module.exports = { pathPrefix: '/docs/' }

View File

@@ -1 +1 @@
// This file is not read by the test suite
// This file is not read by the test suite

View File

@@ -0,0 +1,7 @@
module.exports = {
siteMetadata: {
title: `My Gatsby Site`,
siteUrl: `https://www.yourdomain.tld`,
},
plugins: [],
}

View File

@@ -0,0 +1,8 @@
module.exports = {
pathPrefix: "/docs/",
siteMetadata: {
title: `My Gatsby Site`,
siteUrl: `https://www.yourdomain.tld`,
},
plugins: [],
}

View File

@@ -1,8 +1,8 @@
module.exports = {
pathPrefix: "/docs/",
pathPrefix: '/docs/',
siteMetadata: {
title: `My Gatsby Site`,
siteUrl: `https://www.yourdomain.tld`,
siteUrl: `https://www.yourdomain.tld`
},
plugins: [],
}
plugins: []
}

View File

@@ -0,0 +1,8 @@
export default {
pathPrefix: "/docs/",
siteMetadata: {
title: `My Gatsby Site`,
siteUrl: `https://www.yourdomain.tld`,
},
plugins: [],
}

View File

@@ -1,7 +1,7 @@
module.exports = {
siteMetadata: {
title: `My Gatsby Site`,
siteUrl: `https://www.yourdomain.tld`,
siteUrl: `https://www.yourdomain.tld`
},
plugins: [],
}
plugins: []
}

View File

@@ -0,0 +1,7 @@
export default {
siteMetadata: {
title: `My Gatsby Site`,
siteUrl: `https://www.yourdomain.tld`,
},
plugins: [],
}

View File

@@ -1,6 +1,3 @@
// Default Pages configuration for Next
const nextConfig = {
experimental: {images: {unoptimized: true}},
basePath: '/docs'
}
const nextConfig = { experimental: { images: { unoptimized: true } }, basePath: '/docs' }
module.exports = nextConfig

View File

@@ -1 +1 @@
// This file is not read by the test suite
// This file is not read by the test suite

View File

@@ -0,0 +1,7 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
}
module.exports = nextConfig

View File

@@ -0,0 +1,9 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {images: {unoptimized: true}},
basePath: '/docs',
reactStrictMode: true,
swcMinify: true
}
module.exports = nextConfig

View File

@@ -1,6 +1,6 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {images: {unoptimized: true}},
experimental: { images: { unoptimized: true } },
basePath: '/docs',
reactStrictMode: true,
swcMinify: true

View File

@@ -0,0 +1,9 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {images: {unoptimized: true}},
basePath: '/docs',
reactStrictMode: true,
swcMinify: true
}
export default nextConfig

View File

@@ -1,7 +1,7 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
swcMinify: true
}
module.exports = nextConfig
module.exports = nextConfig

View File

@@ -0,0 +1,7 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
}
export default nextConfig

View File

@@ -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();
}
}
};

View File

@@ -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();
}
}
};

View File

@@ -1,17 +1,17 @@
const getAllDynamicRoute = async function() {
const getAllDynamicRoute = async function () {
const routes = await (async () => {
return ['/posts/hello-world', '/posts/hello-again'];
})();
return routes;
};
return ['/posts/hello-world', '/posts/hello-again']
})()
return routes
}
export default {
target: 'static',
router: {base: '/docs/'},
router: { base: '/docs/' },
mode: 'universal',
generate: {
async routes () {
return getAllDynamicRoute();
async routes() {
return getAllDynamicRoute()
}
}
};
}

View File

@@ -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();
}
}
};

View File

@@ -1,15 +1,15 @@
const getAllDynamicRoute = async function() {
const getAllDynamicRoute = async function () {
const routes = await (async () => {
return ['/posts/hello-world', '/posts/hello-again'];
})();
return routes;
};
return ['/posts/hello-world', '/posts/hello-again']
})()
return routes
}
export default {
mode: 'universal',
generate: {
async routes () {
return getAllDynamicRoute();
async routes() {
return getAllDynamicRoute()
}
}
};
}

View File

@@ -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();
}
}
};

View File

@@ -1,2 +1,2 @@
// Default Pages configuration for Nuxt
export default {target: 'static', router: {base: '/docs/'}}
export default { target: 'static', router: { base: '/docs/' } }

View File

@@ -1 +1 @@
// This file is not read by the test suite
// This file is not read by the test suite

View File

@@ -0,0 +1,44 @@
module.exports = {
// Disable server-side rendering: https://go.nuxtjs.dev/ssr-mode
ssr: false,
// Global page headers: https://go.nuxtjs.dev/config-head
head: {
title: 'nuxt',
htmlAttrs: {
lang: 'en'
},
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: '' },
{ name: 'format-detection', content: 'telephone=no' }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
]
},
// Global CSS: https://go.nuxtjs.dev/config-css
css: [
],
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [
],
// Auto import components: https://go.nuxtjs.dev/config-components
components: true,
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
buildModules: [
],
// Modules: https://go.nuxtjs.dev/config-modules
modules: [
],
// Build Configuration: https://go.nuxtjs.dev/config-build
build: {
}
}

View File

@@ -0,0 +1,46 @@
module.exports = {
// Disable server-side rendering: https://go.nuxtjs.dev/ssr-mode
target: 'static',
router: { base: "/docs/" },
ssr: false,
// Global page headers: https://go.nuxtjs.dev/config-head
head: {
title: 'nuxt',
htmlAttrs: {
lang: 'en'
},
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: '' },
{ name: 'format-detection', content: 'telephone=no' }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
]
},
// Global CSS: https://go.nuxtjs.dev/config-css
css: [
],
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [
],
// Auto import components: https://go.nuxtjs.dev/config-components
components: true,
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
buildModules: [
],
// Modules: https://go.nuxtjs.dev/config-modules
modules: [
],
// Build Configuration: https://go.nuxtjs.dev/config-build
build: {
}
}

View File

@@ -1,7 +1,7 @@
export default {
// Disable server-side rendering: https://go.nuxtjs.dev/ssr-mode
target: 'static',
router: { base: "/docs/" },
router: { base: '/docs/' },
ssr: false,
// Global page headers: https://go.nuxtjs.dev/config-head
@@ -16,31 +16,24 @@ export default {
{ hid: 'description', name: 'description', content: '' },
{ name: 'format-detection', content: 'telephone=no' }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
]
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }]
},
// Global CSS: https://go.nuxtjs.dev/config-css
css: [
],
css: [],
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [
],
plugins: [],
// Auto import components: https://go.nuxtjs.dev/config-components
components: true,
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
buildModules: [
],
buildModules: [],
// Modules: https://go.nuxtjs.dev/config-modules
modules: [
],
modules: [],
// Build Configuration: https://go.nuxtjs.dev/config-build
build: {
}
}
build: {}
}

View File

@@ -0,0 +1,46 @@
export default {
// Disable server-side rendering: https://go.nuxtjs.dev/ssr-mode
target: 'static',
router: { base: "/docs/" },
ssr: false,
// Global page headers: https://go.nuxtjs.dev/config-head
head: {
title: 'nuxt',
htmlAttrs: {
lang: 'en'
},
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: '' },
{ name: 'format-detection', content: 'telephone=no' }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
]
},
// Global CSS: https://go.nuxtjs.dev/config-css
css: [
],
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [
],
// Auto import components: https://go.nuxtjs.dev/config-components
components: true,
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
buildModules: [
],
// Modules: https://go.nuxtjs.dev/config-modules
modules: [
],
// Build Configuration: https://go.nuxtjs.dev/config-build
build: {
}
}

View File

@@ -14,31 +14,24 @@ export default {
{ hid: 'description', name: 'description', content: '' },
{ name: 'format-detection', content: 'telephone=no' }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
]
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }]
},
// Global CSS: https://go.nuxtjs.dev/config-css
css: [
],
css: [],
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [
],
plugins: [],
// Auto import components: https://go.nuxtjs.dev/config-components
components: true,
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
buildModules: [
],
buildModules: [],
// Modules: https://go.nuxtjs.dev/config-modules
modules: [
],
modules: [],
// Build Configuration: https://go.nuxtjs.dev/config-build
build: {
}
}
build: {}
}

View File

@@ -0,0 +1,44 @@
export default {
// Disable server-side rendering: https://go.nuxtjs.dev/ssr-mode
ssr: false,
// Global page headers: https://go.nuxtjs.dev/config-head
head: {
title: 'nuxt',
htmlAttrs: {
lang: 'en'
},
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: '' },
{ name: 'format-detection', content: 'telephone=no' }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
]
},
// Global CSS: https://go.nuxtjs.dev/config-css
css: [
],
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [
],
// Auto import components: https://go.nuxtjs.dev/config-components
components: true,
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
buildModules: [
],
// Modules: https://go.nuxtjs.dev/config-modules
modules: [
],
// Build Configuration: https://go.nuxtjs.dev/config-build
build: {
}
}

View File

@@ -0,0 +1,9 @@
// Default Pages configuration for SvelteKit
import adapter from '@sveltejs/adapter-auto'
export default {
kit: {
paths: { base: '/docs' },
adapter: adapter()
}
}

View File

@@ -0,0 +1 @@
// This file is not read by the test suite

View File

@@ -0,0 +1,11 @@
import adapter from '@sveltejs/adapter-auto'
/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: {
paths: { base: '/docs' },
adapter: adapter()
}
}
export default config

View File

@@ -0,0 +1,10 @@
import adapter from '@sveltejs/adapter-auto'
/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: {
adapter: adapter()
}
}
export default config

View File

@@ -1,38 +0,0 @@
const core = require('@actions/core')
const axios = require('axios')
const {setPagesPath} = require('./set-pages-path')
async function getPagesBaseUrl({
repositoryNwo,
githubToken,
staticSiteGenerator
}) {
try {
const pagesEndpoint = `https://api.github.com/repos/${repositoryNwo}/pages`
core.info(`Get the Base URL to the page with endpoint ${pagesEndpoint}`)
const response = await axios.get(pagesEndpoint, {
headers: {
Accept: 'application/vnd.github.v3+json',
Authorization: `Bearer ${githubToken}`
}
})
pageObject = response.data
core.info(JSON.stringify(pageObject))
const siteUrl = new URL(pageObject.html_url)
if (staticSiteGenerator) {
setPagesPath({staticSiteGenerator, path: siteUrl.pathname})
}
core.setOutput('base_url', siteUrl.href)
core.setOutput('origin', siteUrl.origin)
core.setOutput('host', siteUrl.host)
core.setOutput('base_path', siteUrl.pathname)
} catch (error) {
core.error('Get on the Page failed', error)
throw error
}
}
module.exports = getPagesBaseUrl

View File

@@ -1,16 +1,24 @@
const core = require('@actions/core')
const enablePages = require('./enable-pages')
const getPagesBaseUrl = require('./get-pages-base-url')
// All variables we need from the runtime are loaded here
const {getContext} = require('./context')
const { getContext } = require('./context')
const { findOrCreatePagesSite } = require('./api-client')
const { setPagesPath } = require('./set-pages-path')
const outputPagesBaseUrl = require('./output-pages-base-url')
async function main() {
try {
const context = getContext()
await enablePages(context)
await getPagesBaseUrl(context)
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, generatorConfigFile, path: siteUrl.pathname })
}
outputPagesBaseUrl(siteUrl)
core.exportVariable('GITHUB_PAGES', 'true')
} catch (error) {
core.setFailed(error)
process.exit(1)

View File

@@ -0,0 +1,10 @@
const core = require('@actions/core')
function outputPagesBaseUrl(siteUrl) {
core.setOutput('base_url', siteUrl.href)
core.setOutput('origin', siteUrl.origin)
core.setOutput('host', siteUrl.host)
core.setOutput('base_path', siteUrl.pathname)
}
module.exports = outputPagesBaseUrl

View File

@@ -1,12 +1,8 @@
const core = require('@actions/core')
const axios = require('axios')
const getPagesBaseUrl = require('./get-pages-base-url')
describe('getPagesBaseUrl', () => {
const GITHUB_REPOSITORY = 'paper-spa/is-awesome'
const GITHUB_TOKEN = 'gha-token'
const outputPagesBaseUrl = require('./output-pages-base-url')
describe('outputPagesBaseUrl', () => {
beforeEach(() => {
jest.restoreAllMocks()
@@ -25,22 +21,10 @@ describe('getPagesBaseUrl', () => {
it('gets expected outputs for profile site', async () => {
const baseUrl = 'https://octocat.github.io/'
jest
.spyOn(axios, 'get')
.mockImplementationOnce(() =>
Promise.resolve({data: {html_url: baseUrl}})
)
await getPagesBaseUrl({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN
})
outputPagesBaseUrl(new URL(baseUrl))
expect(core.setOutput).toHaveBeenCalledWith('base_url', baseUrl)
expect(core.setOutput).toHaveBeenCalledWith(
'origin',
'https://octocat.github.io'
)
expect(core.setOutput).toHaveBeenCalledWith('origin', 'https://octocat.github.io')
expect(core.setOutput).toHaveBeenCalledWith('host', 'octocat.github.io')
expect(core.setOutput).toHaveBeenCalledWith('base_path', '/')
})
@@ -48,22 +32,10 @@ describe('getPagesBaseUrl', () => {
it('gets expected outputs for project site', async () => {
const baseUrl = 'https://octocat.github.io/my-repo/'
jest
.spyOn(axios, 'get')
.mockImplementationOnce(() =>
Promise.resolve({data: {html_url: baseUrl}})
)
await getPagesBaseUrl({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN
})
outputPagesBaseUrl(new URL(baseUrl))
expect(core.setOutput).toHaveBeenCalledWith('base_url', baseUrl)
expect(core.setOutput).toHaveBeenCalledWith(
'origin',
'https://octocat.github.io'
)
expect(core.setOutput).toHaveBeenCalledWith('origin', 'https://octocat.github.io')
expect(core.setOutput).toHaveBeenCalledWith('host', 'octocat.github.io')
expect(core.setOutput).toHaveBeenCalledWith('base_path', '/my-repo/')
})
@@ -71,22 +43,10 @@ describe('getPagesBaseUrl', () => {
it('gets expected outputs for site with custom domain name', async () => {
const baseUrl = 'https://www.example.com/'
jest
.spyOn(axios, 'get')
.mockImplementationOnce(() =>
Promise.resolve({data: {html_url: baseUrl}})
)
await getPagesBaseUrl({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN
})
outputPagesBaseUrl(new URL(baseUrl))
expect(core.setOutput).toHaveBeenCalledWith('base_url', baseUrl)
expect(core.setOutput).toHaveBeenCalledWith(
'origin',
'https://www.example.com'
)
expect(core.setOutput).toHaveBeenCalledWith('origin', 'https://www.example.com')
expect(core.setOutput).toHaveBeenCalledWith('host', 'www.example.com')
expect(core.setOutput).toHaveBeenCalledWith('base_path', '/')
})

View File

@@ -1,13 +1,13 @@
const core = require('@actions/core')
const {ConfigParser} = require('./config-parser')
const { ConfigParser } = require('./config-parser')
// 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: `${__dirname}/blank-configurations/nuxt.js`,
properties: {
// Configure a base path on the router
@@ -25,7 +25,7 @@ function getConfigParserSettings(staticSiteGenerator, path) {
}
return {
configurationFile: './next.config.js',
configurationFile: generatorConfigFile || './next.config.js',
blankConfigurationFile: `${__dirname}/blank-configurations/next.js`,
properties: {
// Configure a base path
@@ -38,23 +38,37 @@ function getConfigParserSettings(staticSiteGenerator, path) {
}
case 'gatsby':
return {
configurationFile: './gatsby-config.js',
configurationFile: generatorConfigFile || './gatsby-config.js',
blankConfigurationFile: `${__dirname}/blank-configurations/gatsby.js`,
properties: {
// Configure a path prefix
pathPrefix: path
}
}
case 'sveltekit':
// SvelteKit does not want a trailing slash
if (path.endsWith('/')) {
path = path.slice(0, -1)
}
return {
configurationFile: generatorConfigFile || './svelte.config.js',
blankConfigurationFile: `${__dirname}/blank-configurations/sveltekit.js`,
properties: {
// Configure a base path
'kit.paths.base': path
}
}
default:
throw `Unsupported static site generator: ${staticSiteGenerator}`
}
}
// 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
@@ -65,4 +79,4 @@ function setPagesPath({staticSiteGenerator, path}) {
}
}
module.exports = {getConfigParserSettings, setPagesPath}
module.exports = { getConfigParserSettings, setPagesPath }

View File

@@ -1,53 +1,105 @@
const fs = require('fs')
const path = require('path')
const core = require('@actions/core')
const {getConfigParserSettings} = require('./set-pages-path')
const {ConfigParser} = require('./config-parser')
const {getTempFolder, compareFiles} = require('./test-helpers')
const { getConfigParserSettings } = require('./set-pages-path')
const { ConfigParser } = require('./config-parser')
const { getTempFolder, compareFiles } = require('./test-helpers')
// Get the temp folder
const tempFolder = getTempFolder()
const SUPPORTED_GENERATORS = ['next', 'nuxt', 'gatsby', 'sveltekit']
const SUPPORTED_FILE_EXTENSIONS = ['.js', '.cjs', '.mjs']
// Test suite
describe('configParser', () => {
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())
})
// Iterate over the static site generators
;['next', 'nuxt', 'gatsby'].forEach(staticSiteGenerator => {
SUPPORTED_GENERATORS.forEach(staticSiteGenerator => {
// Folder containing the fixtures for a given static site generator
const fixtureFolder = `${__dirname}/fixtures/${staticSiteGenerator}`
// Iterate over the fixtures
fs.readdirSync(fixtureFolder).forEach(configurationFile => {
// Ignore expectation
if (configurationFile.endsWith('.expected.js')) {
return
}
// Get fixture files, excluding expected results
const configurationFiles = fs.readdirSync(fixtureFolder).filter(filename => !filename.includes('.expected.'))
it(`Inject path properly for ${staticSiteGenerator} in ${configurationFile}`, async () => {
// Get settings for the static site generator
const settings = getConfigParserSettings(staticSiteGenerator, '/docs/')
// Iterate over the fixtures, outputting to default configuration file path
const defaultFileExtension = '.js'
configurationFiles
.filter(filename => filename.endsWith(defaultFileExtension))
.forEach(configurationFile => {
it(`injects path properly for ${staticSiteGenerator} in ${configurationFile} to default configuration file`, async () => {
// Copy the source fixture to a temp file
const fixtureSourceFile = `${fixtureFolder}/${configurationFile}`
const fixtureTargetFile = `${tempFolder}/${configurationFile}`
if (configurationFile !== 'blank.js') {
fs.copyFileSync(fixtureSourceFile, fixtureTargetFile)
} else if (fs.existsSync(fixtureTargetFile)) {
fs.rmSync(fixtureTargetFile)
}
// Copy the source fixture to a temp file
const fixtureSourceFile = `${fixtureFolder}/${configurationFile}`
const fixtureTargetFile = `${tempFolder}/${configurationFile}`
if (configurationFile != 'blank.js') {
fs.copyFileSync(fixtureSourceFile, fixtureTargetFile)
} else if (fs.existsSync(fixtureTargetFile)) {
fs.rmSync(fixtureTargetFile)
}
// Get settings for the static site generator
const settings = getConfigParserSettings({ staticSiteGenerator, path: '/docs/' })
// Update the settings
settings.configurationFile = fixtureTargetFile
// Do the injection
new ConfigParser(settings).injectAll()
// Update the settings and do the injection
settings.configurationFile = fixtureTargetFile
new ConfigParser(settings).injectAll()
// Read the expected file
const expectedFile = `${fixtureFolder}/${path.basename(
configurationFile,
defaultFileExtension
)}.expected${defaultFileExtension}`
// Read the expected file
const expectedFile = `${fixtureFolder}/${path.basename(
configurationFile,
'.js'
)}.expected.js`
// Compare the actual and expected files
compareFiles(settings.configurationFile, expectedFile)
// Compare the actual and expected files
compareFiles(settings.configurationFile, expectedFile)
})
})
SUPPORTED_FILE_EXTENSIONS.forEach(fileExtension => {
// Iterate over the fixtures, outputting to specified configuration file path
configurationFiles
.filter(filename => filename.endsWith(fileExtension))
.forEach(configurationFile => {
it(`injects path properly for ${staticSiteGenerator} in ${configurationFile} to specified *${fileExtension} configuration file`, async () => {
// Copy the source fixture to a temp file
const fixtureSourceFile = `${fixtureFolder}/${configurationFile}`
const fixtureTargetFile = `${tempFolder}/${configurationFile}`
if (configurationFile !== 'blank.js') {
fs.copyFileSync(fixtureSourceFile, fixtureTargetFile)
} else if (fs.existsSync(fixtureTargetFile)) {
fs.rmSync(fixtureTargetFile)
}
// Get settings for the static site generator
const settings = getConfigParserSettings({
staticSiteGenerator,
generatorConfigFile: fixtureTargetFile,
path: '/docs/'
})
// Do the injection
new ConfigParser(settings).injectAll()
// Read the expected file
const expectedFile = `${fixtureFolder}/${path.basename(
configurationFile,
fileExtension
)}.expected${fileExtension}`
// Compare the actual and expected files
compareFiles(settings.configurationFile, expectedFile)
})
})
})
})
})

View File

@@ -6,7 +6,7 @@ const assert = require('assert')
function getTempFolder() {
const tmpFolder = `${__dirname}/fixtures/tmp`
if (!fs.existsSync(tmpFolder)) {
fs.mkdirSync(tmpFolder, {recursive: true})
fs.mkdirSync(tmpFolder, { recursive: true })
}
return tmpFolder
}
@@ -14,19 +14,21 @@ function getTempFolder() {
// Read a JavaScript file and return it formatted
function formatFile(file) {
const fileContent = fs.readFileSync(file, 'utf8')
return prettier.format(fileContent, {
parser: 'espree',
return prettier
.format(fileContent, {
parser: 'espree',
// Prettier options
printWidth: 80,
tabWidth: 2,
useTabs: false,
semi: false,
singleQuote: true,
trailingComma: 'none',
bracketSpacing: false,
arrowParens: 'avoid'
}).trim()
// Prettier options
printWidth: 120,
tabWidth: 2,
useTabs: false,
semi: false,
singleQuote: true,
trailingComma: 'none',
bracketSpacing: true,
arrowParens: 'avoid'
})
.trim()
}
// Compare two JavaScript files
@@ -34,4 +36,4 @@ function compareFiles(actualFile, expectedFile) {
assert.equal(formatFile(actualFile), formatFile(expectedFile))
}
module.exports = {getTempFolder, formatFile, compareFiles}
module.exports = { getTempFolder, formatFile, compareFiles }