Skip to content

Build & Tag (CDN Ready) #4

Build & Tag (CDN Ready)

Build & Tag (CDN Ready) #4

Workflow file for this run

name: Build & Tag (CDN Ready)
on:
workflow_dispatch:
inputs:
version:
description: "Version (e.g. 1.0.0)"
required: true
permissions:
contents: write
jobs:
tag:
runs-on: ubuntu-latest
steps:
- name: Checkout main
uses: actions/checkout@v4
with:
ref: main
fetch-depth: 0
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 22
- name: Install dependencies
run: npm install terser clean-css
- name: Build files
run: |
node <<'EOF'
import fs from "fs";
import { minify } from "terser";
import CleanCSS from "clean-css";
const VERSION = process.env.VERSION;
const repo = process.env.GITHUB_REPOSITORY;
const [owner, name] = repo.split("/");
const BASE_URL = `https://${owner}.github.io/${name}/`;
const files = fs.readdirSync(".").filter(f => {
if (fs.statSync(f).isDirectory()) return false;
if (f.startsWith(".")) return false;
return true;
});
// detect main file (framework or component)
const mainFile =
files.find(f => f === "ccm.js") ||
files.find(f => /^ccm\.[a-z0-9_]+\.mjs$/.test(f));
for (const file of files) {
const ext = file.split(".").pop();
if (!["js", "mjs", "css"].includes(ext)) continue;
let content = fs.readFileSync(file, "utf-8");
// replace local paths
content = content.replaceAll("././", BASE_URL);
let outputName = file;
// rename main file with version
if (file === mainFile) {
if (file.endsWith(".mjs")) {
outputName = file.replace(".mjs", `-${VERSION}.mjs`);
} else {
outputName = file.replace(".js", `-${VERSION}.js`);
}
}
// JS / MJS minify + source map
if (ext === "js" || ext === "mjs") {
const result = await minify(content, {
sourceMap: {
filename: outputName,
url: outputName + ".map"
}
});
const minName = outputName.replace(ext, `min.${ext}`);
fs.writeFileSync(minName, result.code);
fs.writeFileSync(outputName + ".map", result.map);
}
// CSS minify
if (ext === "css") {
const minified = new CleanCSS().minify(content).styles;
const minName = file.replace(".css", ".min.css");
fs.writeFileSync(minName, minified);
}
}
// 🔥 CLEANUP: keep ONLY .min.* and .map, preserve .git
const all = fs.readdirSync(".");
for (const file of all) {
// never delete git directory
if (file === ".git") continue;
// remove other hidden files (.github, .gitignore, etc.)
if (file.startsWith(".")) {
fs.rmSync(file, { recursive: true, force: true });
continue;
}
const ext = file.split(".").pop();
const isMin = file.includes(".min.");
const isMap = ext === "map";
if (!isMin && !isMap) {
fs.rmSync(file, { recursive: true, force: true });
}
}
EOF
env:
VERSION: ${{ github.event.inputs.version }}
- name: Commit build
run: |
git config user.name "github-actions"
git config user.email "github-actions@github.com"
git add .
git commit -m "build v${{ github.event.inputs.version }}"
- name: Create and push tag
run: |
git tag -f v${{ github.event.inputs.version }}
git push origin v${{ github.event.inputs.version }} --force