Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Build and Deploy to GitHub Pages

on:
push:
branches: [main]
pull_request:
branches: [main]

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write

# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: "pages"
cancel-in-progress: false

jobs:
# Build job
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
cache-dependency-path: "build/package-lock.json"

- name: Install dependencies
run: |
cd build
npm ci

- name: Build site
run: |
node build/build.js

- name: Setup Pages
uses: actions/configure-pages@v4

- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./docs

# Deployment job
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/main'
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
*/node_modules
*/__pycache__
*/__pycache__

# Built files that's generated by the build script, deployed via GitHub Actions
docs/
80 changes: 53 additions & 27 deletions build/build.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { minify } from 'minify';
import tryToCatch from 'try-to-catch';
import fse from 'fs-extra';
import path from 'path';
import { minify } from "minify";
import tryToCatch from "try-to-catch";
import fse from "fs-extra";
import path from "path";

function getFilesWithExtension(root, directory, extension, ignoreUnderscored) {
const target = root + directory;
if (!fse.existsSync(target)) { // Check if the directory exists
if (!fse.existsSync(target)) {
// Check if the directory exists
console.log(`(error) \x1b[91mdirectory "${target}" does not exist!\x1b[0m`);
throw new Error("FAILED");
}
Expand All @@ -16,12 +17,11 @@ function getFilesWithExtension(root, directory, extension, ignoreUnderscored) {
// Filter files by the extension
const filtered = files.filter((file) => {
const ext = path.extname(file).toLowerCase();
if (ignoreUnderscored && file.startsWith('_')) return false;
if (ignoreUnderscored && file.startsWith("_")) return false;
return ext === extension.toLowerCase();
});


const result = filtered.map(file => directory + file);
const result = filtered.map((file) => directory + file);
return result;
}

Expand All @@ -30,16 +30,20 @@ async function calculateFileSize(fileList) {
let totalSize = 0;

for (const filePath of fileList) {
const stats = await fse.stat(filePath);

if (stats.isFile()) {
totalSize += stats.size;
// Check if file exists before trying to stat it
if (fse.existsSync(filePath)) {
const stats = await fse.stat(filePath);
if (stats.isFile()) {
totalSize += stats.size;
}
}
}

return totalSize;
} catch (error) {
console.log("(error) \x1b[91mfailed while calculating size:\x1b[0m\n" + error.message);
console.log(
"(error) \x1b[91mfailed while calculating size:\x1b[0m\n" + error.message
);
throw new Error("FAILED");
}
}
Expand All @@ -53,7 +57,9 @@ async function grabAndMinify(file) {

const [error, data] = await tryToCatch(minify, file, options);
if (error) {
console.log("(error) \x1b[91merror occured while minifying:\x1b[0m\n" + error.message);
console.log(
"(error) \x1b[91merror occured while minifying:\x1b[0m\n" + error.message
);
throw new Error("FAILED");
}
return data;
Expand All @@ -67,21 +73,26 @@ async function main() {
src = "../";
dest = "../docs/";
}

const htmlFiles = getFilesWithExtension(src, "", ".html", true);
const cssFiles = getFilesWithExtension(src, "css/", ".css");
const jsFiles = getFilesWithExtension(src, "js/", ".js");

const files = [...htmlFiles, ...cssFiles, ...jsFiles];
const srcFiles = files.map(file => src + file);
const destFiles = files.map(file => dest + file);
const prevTotal = await calculateFileSize(destFiles) / 1000;
const srcFiles = files.map((file) => src + file);
const destFiles = files.map((file) => dest + file);

const prevTotal = (await calculateFileSize(destFiles)) / 1000;

console.log(`(setup) clearing ${dest} folder and contents`);
fse.rmSync(dest, { recursive: true, force: true });
fse.mkdirSync(dest);

// Will always be 0.
if (prevTotal === 0) {
console.log(`(info) starting fresh build - no previous files found`);
}

const dirs = ["js", "css"];
for (let i = 0; i < dirs.length; i++) {
console.log(`(setup) creating empty ${dest + dirs[i]} folder`);
Expand All @@ -103,18 +114,33 @@ async function main() {
console.log(`\n(recursive copy) ${src + "assets"} --> ${dest + "assets"}`);
fse.copySync(src + "assets", dest + "assets", { overwrite: true });

const srcTotal = await calculateFileSize(srcFiles) / 1000;
const destTotal = await calculateFileSize(destFiles) / 1000;
const srcTotal = (await calculateFileSize(srcFiles)) / 1000;
const destTotal = (await calculateFileSize(destFiles)) / 1000;

console.log(`\n(result) raw size: \x1b[93m${srcTotal}\x1b[0m kb`);
console.log(`(result) minified size: \x1b[93m${destTotal}\x1b[0m kb`);
console.log(`(result) compressed by \x1b[92m${Math.round((1 - (destTotal / srcTotal)) * 100)}%\x1b[0m\n`);

console.log(
`(result) compressed by \x1b[92m${Math.round(
(1 - destTotal / srcTotal) * 100
)}%\x1b[0m\n`
);

const sizeChange = Math.round((destTotal - prevTotal) * 100) / 100;
console.log(`\n(result) previous size: \x1b[93m${prevTotal}\x1b[0m kb`);
const resultColor = sizeChange > 0 ? "\x1b[91m+" : sizeChange < 0 ? "\x1b[92m" : "~";
console.log(`(result) build size change: ${resultColor}${sizeChange}\x1b[0m kb`);

// Will always be 0.
if (prevTotal === 0) {
console.log(
`(result) fresh build completed - final size: \x1b[93m${destTotal}\x1b[0m kb`
);
} else {
const resultColor =
sizeChange > 0 ? "\x1b[91m+" : sizeChange < 0 ? "\x1b[92m" : "~";
console.log(
`(result) build size change: ${resultColor}${sizeChange}\x1b[0m kb`
);
}
}

console.log("\n>>> Starting minification of GeoSMART site...\n");
main();
main();
Loading