68 Commits
v1.0.0 ... v1

Author SHA1 Message Date
James M. Greene
9a141972ca Merge pull request #18 from actions/dependabot/npm_and_yarn/actions/core-1.9.1
Bump @actions/core from 1.8.2 to 1.9.1
2022-08-18 18:06:10 -05:00
James M. Greene
7d9bb68583 Update distributables 2022-08-18 18:04:58 -05:00
dependabot[bot]
ec022f4ae9 Bump @actions/core from 1.8.2 to 1.9.1
Bumps [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) from 1.8.2 to 1.9.1.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core)

---
updated-dependencies:
- dependency-name: "@actions/core"
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-18 19:59:15 +00:00
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
62 changed files with 2039 additions and 511 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: branches:
- main - main
permissions:
contents: write
jobs: jobs:
draft-release: draft-release:
runs-on: ubuntu-latest runs-on: ubuntu-latest

View File

@@ -6,20 +6,29 @@ on:
- main - main
pull_request: 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: jobs:
test: test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v3
- name: Set Node.JS - name: Setup Node.JS
uses: actions/setup-node@v3 uses: actions/setup-node@v3
with: with:
node-version: 16.x node-version: 16.x
cache: 'npm'
- name: Install dependencies - name: Install dependencies
run: npm ci run: npm ci
- name: Run tests - name: Run tests
run: npm test run: npm test

View File

@@ -1,10 +1,10 @@
# Prettier (formatter) configuration # Prettier (formatter) configuration
--- ---
printWidth: 80 printWidth: 120
tabWidth: 2 tabWidth: 2
useTabs: false useTabs: false
semi: false semi: false
singleQuote: true singleQuote: true
trailingComma: none trailingComma: none
bracketSpacing: false bracketSpacing: true
arrowParens: avoid 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 # 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: 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 3. After publishing the release, the [`release` workflow][release] will automatically run to create/update the corresponding the major version tag such as `v0`.
git tag v0.1.0
git push origin v0.1.0
```
3. Publish the draft release (the major tag such as `v0` will be created/updated by the [`release` workflow][release]) ⚠️ Environment approval is required. Check the [Release workflow run list][release-workflow-runs].
⚠️ Environment approval is required.
# License # License
@@ -31,5 +26,7 @@ The scripts and documentation in this project are released under the [MIT Licens
<!-- references --> <!-- references -->
[starter-workflows]: https://github.com/actions/starter-workflows/tree/main/pages [starter-workflows]: https://github.com/actions/starter-workflows/tree/main/pages
[release-list]: /releases
[draft-release]: .github/workflows/draft-release.yml [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" name: 'Configure GitHub 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." description: 'A GitHub Action to enable Pages, extract various metadata about a site, and configure some supported static site generators.'
author: 'GitHub'
runs: runs:
using: "node16" using: 'node16'
main: "dist/index.js" main: 'dist/index.js'
inputs: inputs:
static_site_generator: 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 required: false
token: token:
description: "GitHub token" description: 'GitHub token'
default: ${{ github.token }} default: ${{ github.token }}
required: true required: true
enablement:
description: 'Should a Pages site be enabled for the repository if not so already?'
default: 'true'
required: false
outputs: outputs:
base_url: base_url:
description: 'GitHub Pages site full base URL. Examples: "https://octocat.github.io/my-repo/", "https://octocat.github.io/", "https://www.example.com/"' description: 'GitHub Pages site full base URL. Examples: "https://octocat.github.io/my-repo/", "https://octocat.github.io/", "https://www.example.com/"'

1040
dist/index.js vendored

File diff suppressed because it is too large Load Diff

2
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

13
dist/licenses.txt vendored
View File

@@ -608,3 +608,16 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
uuid
MIT
The MIT License (MIT)
Copyright (c) 2010-2020 Robert Kieffer and other contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

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

33
package-lock.json generated
View File

@@ -9,7 +9,7 @@
"version": "1.0.0", "version": "1.0.0",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/core": "^1.8.2", "@actions/core": "^1.9.1",
"axios": "^0.27.2", "axios": "^0.27.2",
"axios-retry": "^3.2.5", "axios-retry": "^3.2.5",
"espree": "^9.3.2", "espree": "^9.3.2",
@@ -22,11 +22,12 @@
} }
}, },
"node_modules/@actions/core": { "node_modules/@actions/core": {
"version": "1.8.2", "version": "1.9.1",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.8.2.tgz", "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz",
"integrity": "sha512-FXcBL7nyik8K5ODeCKlxi+vts7torOkoDAKfeh61EAkAy1HAvwn9uVzZBY0f15YcQTcZZ2/iSGBFHEuioZWfDA==", "integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==",
"dependencies": { "dependencies": {
"@actions/http-client": "^2.0.1" "@actions/http-client": "^2.0.1",
"uuid": "^8.3.2"
} }
}, },
"node_modules/@actions/http-client": { "node_modules/@actions/http-client": {
@@ -3476,6 +3477,14 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/v8-to-istanbul": { "node_modules/v8-to-istanbul": {
"version": "9.0.0", "version": "9.0.0",
"resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.0.tgz", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.0.tgz",
@@ -3595,11 +3604,12 @@
}, },
"dependencies": { "dependencies": {
"@actions/core": { "@actions/core": {
"version": "1.8.2", "version": "1.9.1",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.8.2.tgz", "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz",
"integrity": "sha512-FXcBL7nyik8K5ODeCKlxi+vts7torOkoDAKfeh61EAkAy1HAvwn9uVzZBY0f15YcQTcZZ2/iSGBFHEuioZWfDA==", "integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==",
"requires": { "requires": {
"@actions/http-client": "^2.0.1" "@actions/http-client": "^2.0.1",
"uuid": "^8.3.2"
} }
}, },
"@actions/http-client": { "@actions/http-client": {
@@ -6207,6 +6217,11 @@
"integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
"dev": true "dev": true
}, },
"uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
},
"v8-to-istanbul": { "v8-to-istanbul": {
"version": "9.0.0", "version": "9.0.0",
"resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.0.tgz", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.0.tgz",

View File

@@ -1,24 +1,27 @@
{ {
"private": true,
"name": "configure-pages", "name": "configure-pages",
"version": "1.0.0", "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.", "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": "src/index.js", "main": "./dist/index.js",
"scripts": { "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" "test": "jest"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/paper-spa/configure-pages.git" "url": "git+https://github.com/actions/configure-pages.git"
}, },
"author": "GitHub", "author": "GitHub",
"license": "MIT", "license": "MIT",
"bugs": { "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": { "dependencies": {
"@actions/core": "^1.8.2", "@actions/core": "^1.9.1",
"axios": "^0.27.2", "axios": "^0.27.2",
"axios-retry": "^3.2.5", "axios-retry": "^3.2.5",
"espree": "^9.3.2", "espree": "^9.3.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 // Ctor
// - configurationFile: path to the configuration file // - configurationFile: path to the configuration file
// - blankConfigurationFile: a blank configuration file to use if non was previously found // - blankConfigurationFile: a blank configuration file to use if non was previously found
constructor({configurationFile, blankConfigurationFile, properties}) { constructor({ configurationFile, blankConfigurationFile, properties }) {
// Save field // Save field
this.configurationFile = configurationFile this.configurationFile = configurationFile
this.properties = properties this.properties = properties
@@ -56,16 +56,32 @@ class ConfigParser {
// Return the configuration object or null. // Return the configuration object or null.
findConfigurationObject(ast) { findConfigurationObject(ast) {
// Try to find a default export // Try to find a default export
var defaultExport = ast.body.find( var defaultExport = ast.body.find(node => node.type === 'ExportDefaultDeclaration')
node =>
node.type === 'ExportDefaultDeclaration' && // Direct default export
node.declaration.type === 'ObjectExpression' if (defaultExport && defaultExport.declaration.type === 'ObjectExpression') {
) core.info('Found configuration object in direct default export declaration')
if (defaultExport) {
core.info('Found configuration object in default export declaration')
return defaultExport.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 // Try to find a module export
var moduleExport = ast.body.find( var moduleExport = ast.body.find(
node => node =>
@@ -80,19 +96,13 @@ class ConfigParser {
) )
// Direct module export // Direct module export
if ( if (moduleExport && moduleExport.expression.right.type === 'ObjectExpression') {
moduleExport &&
moduleExport.expression.right.type === 'ObjectExpression'
) {
core.info('Found configuration object in direct module export') core.info('Found configuration object in direct module export')
return moduleExport.expression.right return moduleExport.expression.right
} }
// Indirect module export // Indirect module export
else if ( else if (moduleExport && moduleExport.expression.right.type === 'Identifier') {
moduleExport &&
moduleExport.expression.right.type === 'Identifier'
) {
const identifierName = moduleExport && moduleExport.expression.right.name const identifierName = moduleExport && moduleExport.expression.right.name
const identifierDefinition = ast.body.find( const identifierDefinition = ast.body.find(
node => node =>
@@ -120,9 +130,7 @@ class ConfigParser {
// Try to find a property matching a given name // Try to find a property matching a given name
const property = const property =
object.type === 'ObjectExpression' && object.type === 'ObjectExpression' &&
object.properties.find( object.properties.find(node => node.key.type === 'Identifier' && node.key.name === name)
node => node.key.type === 'Identifier' && node.key.name === name
)
// Return the property's value (if found) or null // Return the property's value (if found) or null
if (property) { if (property) {
@@ -142,9 +150,7 @@ class ConfigParser {
return `${properties[startIndex]}: ${JSON.stringify(propertyValue)}` return `${properties[startIndex]}: ${JSON.stringify(propertyValue)}`
} else { } else {
return ( return (
`${properties[startIndex]}: {` + `${properties[startIndex]}: {` + this.getPropertyDeclaration(properties, startIndex + 1, propertyValue) + '}'
this.getPropertyDeclaration(properties, startIndex + 1, propertyValue) +
'}'
) )
} }
} }
@@ -183,7 +189,7 @@ class ConfigParser {
var depth = 0 var depth = 0
const properties = propertyName.split('.') const properties = propertyName.split('.')
var lastNode = configurationObject var lastNode = configurationObject
while (1) { while (true) {
// Find the node for the current property // Find the node for the current property
var propertyNode = this.findProperty(lastNode, properties[depth]) var propertyNode = this.findProperty(lastNode, properties[depth])
@@ -222,11 +228,7 @@ class ConfigParser {
// Create nested properties in the configuration file // Create nested properties in the configuration file
else { else {
// Build the declaration to inject // Build the declaration to inject
const declaration = this.getPropertyDeclaration( const declaration = this.getPropertyDeclaration(properties, depth, propertyValue)
properties,
depth,
propertyValue
)
// The last node identified is an object expression, so do the assignment // The last node identified is an object expression, so do the assignment
if (lastNode.type === 'ObjectExpression') { 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 fs = require('fs')
const core = require('@actions/core')
const {ConfigParser} = require('./config-parser') const { ConfigParser } = require('./config-parser')
const {getTempFolder, compareFiles} = require('./test-helpers') const { getTempFolder, compareFiles } = require('./test-helpers')
// Get the temp folder // Get the temp folder
const tempFolder = getTempFolder() const tempFolder = getTempFolder()
@@ -11,7 +12,6 @@ const cases = [
// //
// Default export // Default export
// //
{ {
property: 'property', property: 'property',
source: `export default {}`, source: `export default {}`,
@@ -89,6 +89,30 @@ const cases = [
expected: `export default { a2: false, a1: { a2: "value", a3: [12]}}` 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 // Direct module exports
// //
@@ -134,15 +158,25 @@ const cases = [
] ]
describe('config-parser', () => { describe('config-parser', () => {
cases.forEach(({property, source, expected}, index) => { beforeEach(() => {
it(`Inject path properly for case #${index}`, () => { 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 // Write the source file
const sourceFile = `${tempFolder}/source.js` const sourceFile = `${tempFolder}/source.js`
fs.writeFileSync(sourceFile, source, {encoding: 'utf8'}) fs.writeFileSync(sourceFile, source, { encoding: 'utf8' })
// Write the expected file // Write the expected file
const expectedFile = `${tempFolder}/expected.js` const expectedFile = `${tempFolder}/expected.js`
fs.writeFileSync(expectedFile, expected, {encoding: 'utf8'}) fs.writeFileSync(expectedFile, expected, { encoding: 'utf8' })
// Update the settings and do the injection // Update the settings and do the injection
new ConfigParser({ new ConfigParser({

View File

@@ -5,7 +5,9 @@ function getRequiredVars() {
return { return {
repositoryNwo: process.env.GITHUB_REPOSITORY, repositoryNwo: process.env.GITHUB_REPOSITORY,
githubToken: core.getInput('token'), 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 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 // 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 = { module.exports = {
pathPrefix: "/docs/", pathPrefix: '/docs/',
siteMetadata: { siteMetadata: {
title: `My Gatsby Site`, 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 = { module.exports = {
siteMetadata: { siteMetadata: {
title: `My Gatsby Site`, 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 // Default Pages configuration for Next
const nextConfig = { const nextConfig = { experimental: { images: { unoptimized: true } }, basePath: '/docs' }
experimental: {images: {unoptimized: true}},
basePath: '/docs'
}
module.exports = nextConfig 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} */ /** @type {import('next').NextConfig} */
const nextConfig = { const nextConfig = {
experimental: {images: {unoptimized: true}}, experimental: { images: { unoptimized: true } },
basePath: '/docs', basePath: '/docs',
reactStrictMode: true, reactStrictMode: true,
swcMinify: 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} */ /** @type {import('next').NextConfig} */
const nextConfig = { const nextConfig = {
reactStrictMode: true, 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 () => { const routes = await (async () => {
return ['/posts/hello-world', '/posts/hello-again']; return ['/posts/hello-world', '/posts/hello-again']
})(); })()
return routes; return routes
}; }
export default { export default {
target: 'static', target: 'static',
router: {base: '/docs/'}, router: { base: '/docs/' },
mode: 'universal', mode: 'universal',
generate: { generate: {
async routes () { async routes() {
return getAllDynamicRoute(); 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 () => { const routes = await (async () => {
return ['/posts/hello-world', '/posts/hello-again']; return ['/posts/hello-world', '/posts/hello-again']
})(); })()
return routes; return routes
}; }
export default { export default {
mode: 'universal', mode: 'universal',
generate: { generate: {
async routes () { async routes() {
return getAllDynamicRoute(); 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 // 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 { export default {
// Disable server-side rendering: https://go.nuxtjs.dev/ssr-mode // Disable server-side rendering: https://go.nuxtjs.dev/ssr-mode
target: 'static', target: 'static',
router: { base: "/docs/" }, router: { base: '/docs/' },
ssr: false, ssr: false,
// Global page headers: https://go.nuxtjs.dev/config-head // Global page headers: https://go.nuxtjs.dev/config-head
@@ -16,31 +16,24 @@ export default {
{ hid: 'description', name: 'description', content: '' }, { hid: 'description', name: 'description', content: '' },
{ name: 'format-detection', content: 'telephone=no' } { name: 'format-detection', content: 'telephone=no' }
], ],
link: [ link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }]
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
]
}, },
// Global CSS: https://go.nuxtjs.dev/config-css // Global CSS: https://go.nuxtjs.dev/config-css
css: [ css: [],
],
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins // Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [ plugins: [],
],
// Auto import components: https://go.nuxtjs.dev/config-components // Auto import components: https://go.nuxtjs.dev/config-components
components: true, components: true,
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules // Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
buildModules: [ buildModules: [],
],
// Modules: https://go.nuxtjs.dev/config-modules // Modules: https://go.nuxtjs.dev/config-modules
modules: [ modules: [],
],
// Build Configuration: https://go.nuxtjs.dev/config-build // 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: '' }, { hid: 'description', name: 'description', content: '' },
{ name: 'format-detection', content: 'telephone=no' } { name: 'format-detection', content: 'telephone=no' }
], ],
link: [ link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }]
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
]
}, },
// Global CSS: https://go.nuxtjs.dev/config-css // Global CSS: https://go.nuxtjs.dev/config-css
css: [ css: [],
],
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins // Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [ plugins: [],
],
// Auto import components: https://go.nuxtjs.dev/config-components // Auto import components: https://go.nuxtjs.dev/config-components
components: true, components: true,
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules // Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
buildModules: [ buildModules: [],
],
// Modules: https://go.nuxtjs.dev/config-modules // Modules: https://go.nuxtjs.dev/config-modules
modules: [ modules: [],
],
// Build Configuration: https://go.nuxtjs.dev/config-build // 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 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 // 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() { async function main() {
try { try {
const context = getContext() const { repositoryNwo, githubToken, enablement, staticSiteGenerator, generatorConfigFile } = getContext()
await enablePages(context)
await getPagesBaseUrl(context) 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) { } catch (error) {
core.setFailed(error) core.setFailed(error)
process.exit(1) 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 core = require('@actions/core')
const axios = require('axios')
const getPagesBaseUrl = require('./get-pages-base-url') const outputPagesBaseUrl = require('./output-pages-base-url')
describe('getPagesBaseUrl', () => {
const GITHUB_REPOSITORY = 'paper-spa/is-awesome'
const GITHUB_TOKEN = 'gha-token'
describe('outputPagesBaseUrl', () => {
beforeEach(() => { beforeEach(() => {
jest.restoreAllMocks() jest.restoreAllMocks()
@@ -25,22 +21,10 @@ describe('getPagesBaseUrl', () => {
it('gets expected outputs for profile site', async () => { it('gets expected outputs for profile site', async () => {
const baseUrl = 'https://octocat.github.io/' const baseUrl = 'https://octocat.github.io/'
jest outputPagesBaseUrl(new URL(baseUrl))
.spyOn(axios, 'get')
.mockImplementationOnce(() =>
Promise.resolve({data: {html_url: baseUrl}})
)
await getPagesBaseUrl({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN
})
expect(core.setOutput).toHaveBeenCalledWith('base_url', baseUrl) expect(core.setOutput).toHaveBeenCalledWith('base_url', baseUrl)
expect(core.setOutput).toHaveBeenCalledWith( expect(core.setOutput).toHaveBeenCalledWith('origin', 'https://octocat.github.io')
'origin',
'https://octocat.github.io'
)
expect(core.setOutput).toHaveBeenCalledWith('host', 'octocat.github.io') expect(core.setOutput).toHaveBeenCalledWith('host', 'octocat.github.io')
expect(core.setOutput).toHaveBeenCalledWith('base_path', '/') expect(core.setOutput).toHaveBeenCalledWith('base_path', '/')
}) })
@@ -48,22 +32,10 @@ describe('getPagesBaseUrl', () => {
it('gets expected outputs for project site', async () => { it('gets expected outputs for project site', async () => {
const baseUrl = 'https://octocat.github.io/my-repo/' const baseUrl = 'https://octocat.github.io/my-repo/'
jest outputPagesBaseUrl(new URL(baseUrl))
.spyOn(axios, 'get')
.mockImplementationOnce(() =>
Promise.resolve({data: {html_url: baseUrl}})
)
await getPagesBaseUrl({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN
})
expect(core.setOutput).toHaveBeenCalledWith('base_url', baseUrl) expect(core.setOutput).toHaveBeenCalledWith('base_url', baseUrl)
expect(core.setOutput).toHaveBeenCalledWith( expect(core.setOutput).toHaveBeenCalledWith('origin', 'https://octocat.github.io')
'origin',
'https://octocat.github.io'
)
expect(core.setOutput).toHaveBeenCalledWith('host', 'octocat.github.io') expect(core.setOutput).toHaveBeenCalledWith('host', 'octocat.github.io')
expect(core.setOutput).toHaveBeenCalledWith('base_path', '/my-repo/') 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 () => { it('gets expected outputs for site with custom domain name', async () => {
const baseUrl = 'https://www.example.com/' const baseUrl = 'https://www.example.com/'
jest outputPagesBaseUrl(new URL(baseUrl))
.spyOn(axios, 'get')
.mockImplementationOnce(() =>
Promise.resolve({data: {html_url: baseUrl}})
)
await getPagesBaseUrl({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN
})
expect(core.setOutput).toHaveBeenCalledWith('base_url', baseUrl) expect(core.setOutput).toHaveBeenCalledWith('base_url', baseUrl)
expect(core.setOutput).toHaveBeenCalledWith( expect(core.setOutput).toHaveBeenCalledWith('origin', 'https://www.example.com')
'origin',
'https://www.example.com'
)
expect(core.setOutput).toHaveBeenCalledWith('host', 'www.example.com') expect(core.setOutput).toHaveBeenCalledWith('host', 'www.example.com')
expect(core.setOutput).toHaveBeenCalledWith('base_path', '/') expect(core.setOutput).toHaveBeenCalledWith('base_path', '/')
}) })

View File

@@ -1,13 +1,13 @@
const core = require('@actions/core') 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 // Return the settings to be passed to a {ConfigParser} for a given static site generator,
// static site generator and a Pages path value to inject // optional configuration file path, and a Pages path value to inject
function getConfigParserSettings(staticSiteGenerator, path) { function getConfigParserSettings({ staticSiteGenerator, generatorConfigFile, path }) {
switch (staticSiteGenerator) { switch (staticSiteGenerator) {
case 'nuxt': case 'nuxt':
return { return {
configurationFile: './nuxt.config.js', configurationFile: generatorConfigFile || './nuxt.config.js',
blankConfigurationFile: `${__dirname}/blank-configurations/nuxt.js`, blankConfigurationFile: `${__dirname}/blank-configurations/nuxt.js`,
properties: { properties: {
// Configure a base path on the router // Configure a base path on the router
@@ -25,7 +25,7 @@ function getConfigParserSettings(staticSiteGenerator, path) {
} }
return { return {
configurationFile: './next.config.js', configurationFile: generatorConfigFile || './next.config.js',
blankConfigurationFile: `${__dirname}/blank-configurations/next.js`, blankConfigurationFile: `${__dirname}/blank-configurations/next.js`,
properties: { properties: {
// Configure a base path // Configure a base path
@@ -38,23 +38,37 @@ function getConfigParserSettings(staticSiteGenerator, path) {
} }
case 'gatsby': case 'gatsby':
return { return {
configurationFile: './gatsby-config.js', configurationFile: generatorConfigFile || './gatsby-config.js',
blankConfigurationFile: `${__dirname}/blank-configurations/gatsby.js`, blankConfigurationFile: `${__dirname}/blank-configurations/gatsby.js`,
properties: { properties: {
// Configure a path prefix // Configure a path prefix
pathPrefix: path 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: default:
throw `Unsupported static site generator: ${staticSiteGenerator}` throw `Unsupported static site generator: ${staticSiteGenerator}`
} }
} }
// Inject Pages configuration in a given static site generator's configuration file // Inject Pages configuration in a given static site generator's configuration file
function setPagesPath({staticSiteGenerator, path}) { function setPagesPath({ staticSiteGenerator, generatorConfigFile, path }) {
try { try {
// Parse the configuration file and try to inject the Pages configuration in it // 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() new ConfigParser(settings).injectAll()
} catch (error) { } catch (error) {
// Logging // 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 fs = require('fs')
const path = require('path') const path = require('path')
const core = require('@actions/core')
const {getConfigParserSettings} = require('./set-pages-path') const { getConfigParserSettings } = require('./set-pages-path')
const {ConfigParser} = require('./config-parser') const { ConfigParser } = require('./config-parser')
const {getTempFolder, compareFiles} = require('./test-helpers') const { getTempFolder, compareFiles } = require('./test-helpers')
// Get the temp folder // Get the temp folder
const tempFolder = getTempFolder() const tempFolder = getTempFolder()
const SUPPORTED_GENERATORS = ['next', 'nuxt', 'gatsby', 'sveltekit']
const SUPPORTED_FILE_EXTENSIONS = ['.js', '.cjs', '.mjs']
// Test suite // Test suite
describe('configParser', () => { 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 // 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 // Folder containing the fixtures for a given static site generator
const fixtureFolder = `${__dirname}/fixtures/${staticSiteGenerator}` const fixtureFolder = `${__dirname}/fixtures/${staticSiteGenerator}`
// Iterate over the fixtures // Get fixture files, excluding expected results
fs.readdirSync(fixtureFolder).forEach(configurationFile => { const configurationFiles = fs.readdirSync(fixtureFolder).filter(filename => !filename.includes('.expected.'))
// Ignore expectation
if (configurationFile.endsWith('.expected.js')) {
return
}
it(`Inject path properly for ${staticSiteGenerator} in ${configurationFile}`, async () => { // Iterate over the fixtures, outputting to default configuration file path
// Get settings for the static site generator const defaultFileExtension = '.js'
const settings = getConfigParserSettings(staticSiteGenerator, '/docs/') 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 // Get settings for the static site generator
const fixtureSourceFile = `${fixtureFolder}/${configurationFile}` const settings = getConfigParserSettings({ staticSiteGenerator, path: '/docs/' })
const fixtureTargetFile = `${tempFolder}/${configurationFile}` // Update the settings
if (configurationFile != 'blank.js') { settings.configurationFile = fixtureTargetFile
fs.copyFileSync(fixtureSourceFile, fixtureTargetFile) // Do the injection
} else if (fs.existsSync(fixtureTargetFile)) { new ConfigParser(settings).injectAll()
fs.rmSync(fixtureTargetFile)
}
// Update the settings and do the injection // Read the expected file
settings.configurationFile = fixtureTargetFile const expectedFile = `${fixtureFolder}/${path.basename(
new ConfigParser(settings).injectAll() configurationFile,
defaultFileExtension
)}.expected${defaultFileExtension}`
// Read the expected file // Compare the actual and expected files
const expectedFile = `${fixtureFolder}/${path.basename( compareFiles(settings.configurationFile, expectedFile)
configurationFile, })
'.js'
)}.expected.js`
// 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() { function getTempFolder() {
const tmpFolder = `${__dirname}/fixtures/tmp` const tmpFolder = `${__dirname}/fixtures/tmp`
if (!fs.existsSync(tmpFolder)) { if (!fs.existsSync(tmpFolder)) {
fs.mkdirSync(tmpFolder, {recursive: true}) fs.mkdirSync(tmpFolder, { recursive: true })
} }
return tmpFolder return tmpFolder
} }
@@ -14,19 +14,21 @@ function getTempFolder() {
// Read a JavaScript file and return it formatted // Read a JavaScript file and return it formatted
function formatFile(file) { function formatFile(file) {
const fileContent = fs.readFileSync(file, 'utf8') const fileContent = fs.readFileSync(file, 'utf8')
return prettier.format(fileContent, { return prettier
parser: 'espree', .format(fileContent, {
parser: 'espree',
// Prettier options // Prettier options
printWidth: 80, printWidth: 120,
tabWidth: 2, tabWidth: 2,
useTabs: false, useTabs: false,
semi: false, semi: false,
singleQuote: true, singleQuote: true,
trailingComma: 'none', trailingComma: 'none',
bracketSpacing: false, bracketSpacing: true,
arrowParens: 'avoid' arrowParens: 'avoid'
}).trim() })
.trim()
} }
// Compare two JavaScript files // Compare two JavaScript files
@@ -34,4 +36,4 @@ function compareFiles(actualFile, expectedFile) {
assert.equal(formatFile(actualFile), formatFile(expectedFile)) assert.equal(formatFile(actualFile), formatFile(expectedFile))
} }
module.exports = {getTempFolder, formatFile, compareFiles} module.exports = { getTempFolder, formatFile, compareFiles }