Skip to content

Commit 73b26c0

Browse files
committed
Add script to setup gh pages
Fix #22
1 parent 457b0ff commit 73b26c0

File tree

4 files changed

+138
-16
lines changed

4 files changed

+138
-16
lines changed

.github/workflows/deploy-gh.yml

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: Deploy Github Pages
33
on:
44
push:
55
branches:
6-
- 'main'
6+
- 'feature/deployment'
77

88
env:
99
PUBLIC_URL: ${{ vars.PUBLIC_URL }}
@@ -26,27 +26,30 @@ jobs:
2626
uses: actions/checkout@v4
2727

2828
- name: Use Node.js
29-
uses: actions/setup-node@v3
29+
uses: actions/setup-node@v4
3030
with:
3131
node-version-file: '.nvmrc'
3232

3333
- name: Cache node_modules
34-
uses: actions/cache@v3
34+
uses: actions/cache@v4
3535
id: cache-node-modules
3636
with:
3737
path: node_modules
38-
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package.json') }}
38+
key: ${{ runner.os }}-build-${{ hashFiles('**/package.json') }}
3939

4040
- name: Cache dist
41-
uses: actions/cache@v3
41+
uses: actions/cache@v4
4242
id: cache-dist
4343
with:
4444
path: packages/client/dist
45-
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ github.sha }}
45+
key: ${{ runner.os }}-build-${{ github.sha }}
4646

4747
- name: Install
4848
run: npm install
4949

50+
- name: Setup SPA on Github Pages
51+
run: node packages/client/tasks/setup-gh-pages.mjs
52+
5053
- name: Build
5154
run: npm run all:build
5255

@@ -59,14 +62,11 @@ jobs:
5962
uses: actions/checkout@v4
6063

6164
- name: Restore dist cache
62-
uses: actions/cache@v3
65+
uses: actions/cache@v4
6366
id: cache-dist
6467
with:
6568
path: packages/client/dist
66-
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ github.sha }}
67-
68-
- name: Copy index as 400 file for github pages
69-
run: cp packages/client/dist/index.html packages/client/dist/400.html
69+
key: ${{ runner.os }}-build-${{ github.sha }}
7070

7171
- name: Deploy 🚀
7272
uses: JamesIves/github-pages-deploy-action@v4

packages/client/posthtml.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ module.exports = {
2828
locals: {
2929
appTitle: process.env.APP_TITLE,
3030
appDescription: process.env.APP_DESCRIPTION,
31-
baseurl: process.env.PUBLIC_URL || ''
31+
baseurl: process.env.PUBLIC_URL || '/'
3232
}
3333
}
3434
}

packages/client/tasks/build.mjs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ async function copyFiles() {
3434
log.info('📦 Copied static files to dist.');
3535
}
3636

37-
async function parcelServe() {
38-
const publicUrl = process.env.PUBLIC_URL || '';
37+
async function parcelBuild() {
38+
const publicUrl = process.env.PUBLIC_URL || '/';
3939

40-
if (publicUrl) {
40+
if (publicUrl && publicUrl !== '/') {
4141
log.warn(`🌍 Building using public URL: ${publicUrl}`);
4242
} else {
4343
log.warn(`🌍 Building without public URL`);
@@ -66,8 +66,9 @@ async function parcelServe() {
6666
log.info(`✨ Built ${bundles.length} bundles in ${buildTime}ms!`);
6767
} catch (err) {
6868
log.warn(err.diagnostics);
69+
process.exit(1);
6970
}
7071
}
7172

7273
copyFiles();
73-
parcelServe();
74+
parcelBuild();
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/* global process */
2+
import path from 'path';
3+
import { fileURLToPath } from 'url';
4+
import fs from 'fs-extra';
5+
import log from 'fancy-log';
6+
7+
// Adapted into a script from: https://github.com/rafgraph/spa-github-pages/tree/gh-pages
8+
9+
const __filename = fileURLToPath(import.meta.url);
10+
const __dirname = path.dirname(__filename);
11+
12+
const baseUrl = process.env.PUBLIC_URL || '';
13+
14+
const pathIndex = path.join(__dirname, '../src/index.html');
15+
const path404 = path.join(__dirname, '../static/404.html');
16+
17+
async function main() {
18+
log.info('📦 Setting up single page apps on GitHub Pages.');
19+
20+
const has404 = await fs.pathExists(path404);
21+
22+
if (has404) {
23+
log.warn('📦 Found custom 404.html. Skipping setup.');
24+
process.exit(0);
25+
}
26+
27+
if (!baseUrl) {
28+
log.warn(
29+
'📦 Public URL not set. Assuming the app is deployed to the root.'
30+
);
31+
}
32+
33+
let segments = 0;
34+
if (baseUrl) {
35+
try {
36+
segments = new URL(baseUrl).pathname.split('/').length - 1;
37+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
38+
} catch (error) {
39+
// no-op
40+
}
41+
log.info(`📦 Using ${baseUrl} with ${segments} path segments.`);
42+
}
43+
44+
const templateScript = `<!-- Start Single Page Apps for GitHub Pages -->
45+
<script type="text/javascript">
46+
// Single Page Apps for GitHub Pages
47+
// MIT License
48+
// https://github.com/rafgraph/spa-github-pages
49+
// This script checks to see if a redirect is present in the query string,
50+
// converts it back into the correct url and adds it to the
51+
// browser's history using window.history.replaceState(...),
52+
// which won't cause the browser to attempt to load the new url.
53+
// When the single page app is loaded further down in this file,
54+
// the correct url will be waiting in the browser's history for
55+
// the single page app to route accordingly.
56+
(function(l) {
57+
if (l.search[1] === '/' ) {
58+
var decoded = l.search.slice(1).split('&').map(function(s) {
59+
return s.replace(/~and~/g, '&')
60+
}).join('?');
61+
window.history.replaceState(null, null,
62+
l.pathname.slice(0, -1) + decoded + l.hash
63+
);
64+
}
65+
}(window.location))
66+
</script>
67+
<!-- End Single Page Apps for GitHub Pages -->`;
68+
69+
// Write to index head.
70+
const index = await fs.readFile(pathIndex, 'utf8');
71+
const newIndex = index.replace('<head>', `<head>\n${templateScript}`);
72+
await fs.writeFile(pathIndex, newIndex);
73+
74+
const template404 = `<!DOCTYPE html>
75+
<html>
76+
<head>
77+
<meta charset="utf-8">
78+
<title>Single Page Apps for GitHub Pages</title>
79+
<script type="text/javascript">
80+
// Single Page Apps for GitHub Pages
81+
// MIT License
82+
// https://github.com/rafgraph/spa-github-pages
83+
// This script takes the current url and converts the path and query
84+
// string into just a query string, and then redirects the browser
85+
// to the new url with only a query string and hash fragment,
86+
// e.g. https://www.foo.tld/one/two?a=b&c=d#qwe, becomes
87+
// https://www.foo.tld/?/one/two&a=b~and~c=d#qwe
88+
// Note: this 404.html file must be at least 512 bytes for it to work
89+
// with Internet Explorer (it is currently > 512 bytes)
90+
91+
// If you're creating a Project Pages site and NOT using a custom domain,
92+
// then set pathSegmentsToKeep to 1 (enterprise users may need to set it to > 1).
93+
// This way the code will only replace the route part of the path, and not
94+
// the real directory in which the app resides, for example:
95+
// https://username.github.io/repo-name/one/two?a=b&c=d#qwe becomes
96+
// https://username.github.io/repo-name/?/one/two&a=b~and~c=d#qwe
97+
// Otherwise, leave pathSegmentsToKeep as 0.
98+
var pathSegmentsToKeep = ${segments};
99+
100+
var l = window.location;
101+
l.replace(
102+
l.protocol + '//' + l.hostname + (l.port ? ':' + l.port : '') +
103+
l.pathname.split('/').slice(0, 1 + pathSegmentsToKeep).join('/') + '/?/' +
104+
l.pathname.slice(1).split('/').slice(pathSegmentsToKeep).join('/').replace(/&/g, '~and~') +
105+
(l.search ? '&' + l.search.slice(1).replace(/&/g, '~and~') : '') +
106+
l.hash
107+
);
108+
109+
</script>
110+
</head>
111+
<body>
112+
</body>
113+
</html>`;
114+
115+
// Write to 404.html.
116+
await fs.writeFile(path404, template404);
117+
118+
log.info('✅ GitHub Pages setup complete.');
119+
}
120+
121+
main();

0 commit comments

Comments
 (0)