Add Sass build pipeline and production deploy script
- Move hand-authored CSS into src/scss/styles.scss, compiled to the tracked styles.css via `npm run build` (sass, no source maps). - Add package.json/package-lock.json with dev tooling: sass, and a `dev` script running php + sass --watch + browser-sync together. - Add scripts/build-dist.js (npm run dist): assembles an allowlisted, production-only copy of the site into dist/ (gitignored) for pushing to hosting — excludes node_modules, src/, package files, and the live db/fitz.sqlite while including config.php. - .gitignore: ignore node_modules/, styles.css.map, and dist/. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
cd4c6c1969
commit
2145094e55
6 files changed
+6708
-1992
No files matched your search
@@ -16,3 +16,10 @@ db/fitz.sqlite-shm
|
||||
.hintrc
|
||||
dev.sh
|
||||
.claude/
|
||||
|
||||
# Node development dependencies and Sass source maps
|
||||
node_modules/
|
||||
styles.css.map
|
||||
|
||||
# Generated deploy folder (npm run dist) — includes config.php, never commit
|
||||
dist/
|
||||
Generated
+2430
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "theoldfitz",
|
||||
"version": "1.0.0",
|
||||
"description": "The Old Fitz Public House website",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
"dev": "concurrently --kill-others-on-fail \"npm:dev:php\" \"npm:dev:sass\" \"npm:dev:browser\"",
|
||||
"dev:php": "php -S localhost:8000",
|
||||
"dev:sass": "sass --watch --source-map src/scss/styles.scss:styles.css",
|
||||
"dev:browser": "browser-sync start --proxy http://localhost:8000 --files \"*.php,admin/**/*.php,inc/**/*.php,main.js,styles.css\" --no-open",
|
||||
"build": "sass --no-source-map src/scss/styles.scss:styles.css",
|
||||
"dist": "npm run build && node scripts/build-dist.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://gitea.home.daviddyer.me/david/the-old-fitz.git"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"type": "commonjs",
|
||||
"devDependencies": {
|
||||
"browser-sync": "^3.0.4",
|
||||
"concurrently": "^10.0.5",
|
||||
"sass": "^1.103.1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env node
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Assembles a clean, production-only copy of the site into dist/.
|
||||
*
|
||||
* This is an allowlist by design: only the files and folders listed below
|
||||
* are copied. Dev-only stuff (node_modules/, src/, package*.json, .git/,
|
||||
* .claude/, docker-compose.yaml, dev.sh, .hintrc, config.example.php, the
|
||||
* live db/fitz.sqlite, ...) never ends up in dist/ — including anything
|
||||
* added later, since it has to be added here explicitly first.
|
||||
*
|
||||
* Run with: npm run dist
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const ROOT = path.resolve(__dirname, '..');
|
||||
const DIST = path.join(ROOT, 'dist');
|
||||
|
||||
const FILES = [
|
||||
'index.php',
|
||||
'menu.php',
|
||||
'main.js',
|
||||
'styles.css',
|
||||
'robots.txt',
|
||||
'config.php', // holds the live FB_PAGE_ACCESS_TOKEN — see README before sharing dist/ anywhere but the server
|
||||
];
|
||||
|
||||
const DIRS = ['admin', 'assets', 'inc'];
|
||||
|
||||
function copyDir(src, dest) {
|
||||
fs.cpSync(src, dest, {
|
||||
recursive: true,
|
||||
filter: (source) => path.basename(source) !== '.DS_Store',
|
||||
});
|
||||
}
|
||||
|
||||
// Fresh start every run so a file removed from the source tree doesn't
|
||||
// linger in dist/ from a previous build.
|
||||
fs.rmSync(DIST, { recursive: true, force: true });
|
||||
fs.mkdirSync(DIST, { recursive: true });
|
||||
|
||||
const missing = [];
|
||||
|
||||
for (const file of FILES) {
|
||||
const src = path.join(ROOT, file);
|
||||
if (!fs.existsSync(src)) {
|
||||
missing.push(file);
|
||||
continue;
|
||||
}
|
||||
fs.copyFileSync(src, path.join(DIST, file));
|
||||
}
|
||||
|
||||
for (const dir of DIRS) {
|
||||
const src = path.join(ROOT, dir);
|
||||
if (!fs.existsSync(src)) {
|
||||
missing.push(dir + '/');
|
||||
continue;
|
||||
}
|
||||
copyDir(src, path.join(DIST, dir));
|
||||
}
|
||||
|
||||
// db/ ships with just .htaccess (denies direct web access to the sqlite
|
||||
// file) — never the live fitz.sqlite itself. inc/db.php creates the
|
||||
// schema on first run if the file isn't there, so shipping the dev
|
||||
// database would just overwrite whatever is already live on the server.
|
||||
const dbHtaccess = path.join(ROOT, 'db', '.htaccess');
|
||||
if (fs.existsSync(dbHtaccess)) {
|
||||
fs.mkdirSync(path.join(DIST, 'db'), { recursive: true });
|
||||
fs.copyFileSync(dbHtaccess, path.join(DIST, 'db', '.htaccess'));
|
||||
} else {
|
||||
missing.push('db/.htaccess');
|
||||
}
|
||||
|
||||
if (missing.length) {
|
||||
console.warn('Warning: expected but not found, skipped:\n ' + missing.join('\n '));
|
||||
}
|
||||
|
||||
console.log(`Deploy folder built at ${path.relative(ROOT, DIST)}/`);
|
||||
File diff suppressed because it is too large.
Load diff
+1985
-1992
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user