Remove build-release.sh, minify.js, and scripts README from main

Replaced by MokoStandards API. Only download-google-fonts remains
(will be converted to PHP on next merge from dev).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-07 19:14:39 -05:00
parent cbe681738b
commit 99bbc06caa
3 changed files with 0 additions and 596 deletions

View File

@@ -1,276 +0,0 @@
# Scripts — MokoCassiopeia
This directory contains utility scripts for building, releasing, and managing the MokoCassiopeia Joomla template.
## Available Scripts
### build-release.sh
**Purpose**: Build a release package for MokoCassiopeia template.
**Usage**:
```bash
# Build with auto-detected version from templateDetails.xml
./scripts/build-release.sh
# Build with specific version
./scripts/build-release.sh 03.08.03
```
**What it does**:
1. Creates a `build/` directory
2. Copies template files from `src/`
3. Copies media files from `src/media/` to `media/`
4. Creates a ZIP package: `mokocassiopeia-src-{version}.zip`
5. Generates SHA-256 and MD5 checksums
6. Outputs package location and checksums
**Output**:
- `build/mokocassiopeia-src-{version}.zip` - Installation package
- `build/mokocassiopeia-src-{version}.zip.sha256` - SHA-256 checksum
- `build/mokocassiopeia-src-{version}.zip.md5` - MD5 checksum
**Requirements**:
- `rsync` for file copying
- `zip` for package creation
- `sha256sum` and `md5sum` for checksums
---
## Automated Workflows
The repository includes GitHub Actions workflows that automate the build and release process:
### `.github/workflows/release.yml`
**Purpose**: Automated release creation when tags are pushed.
**Triggers**:
- Push of version tag (e.g., `03.08.03`)
- Manual workflow dispatch with version input
**Process**:
1. Checks out repository
2. Sets up PHP environment
3. Installs dependencies (if composer.json exists)
4. Updates version numbers in manifest files
5. Creates package structure
6. Builds ZIP package
7. Generates checksums
8. Creates GitHub Release with artifacts
**Usage**:
```bash
# Create and push a tag
git tag 03.08.04
git push origin 03.08.04
# Or use GitHub UI to run manually
```
---
### `.github/workflows/auto-update-sha.yml`
**Purpose**: Automatically update SHA-256 hash in `updates.xml` after a release is published.
**Triggers**:
- GitHub Release published
- Manual workflow dispatch with tag input
**Process**:
1. Downloads the release package
2. Calculates SHA-256 hash
3. Updates `updates.xml` with:
- New version number
- Current date
- Download URL
- SHA-256 hash
4. Commits and pushes changes to main branch
**Benefits**:
- Ensures `updates.xml` always has correct SHA-256 hash
- Enables Joomla update server functionality
- Reduces manual update errors
- Automates security verification
---
## Release Process
### Manual Release (Local Build)
1. **Update version numbers**:
```bash
# Update these files manually:
# - src/templateDetails.xml
# - updates.xml
# - CHANGELOG.md
```
2. **Build package**:
```bash
./scripts/build-release.sh 03.08.04
```
3. **Test package**:
- Install ZIP in Joomla test environment
- Verify all features work correctly
4. **Create GitHub Release**:
- Go to GitHub Releases
- Click "Create a new release"
- Upload the ZIP, SHA256, and MD5 files
- Add release notes from CHANGELOG.md
5. **Update updates.xml**:
- Copy SHA-256 hash from `.sha256` file
- Update `updates.xml` with new hash
- Commit and push changes
---
### Automated Release (GitHub Actions)
1. **Update version numbers**:
```bash
# Update these files in a branch:
# - src/templateDetails.xml
# - CHANGELOG.md
git checkout -b release/03.08.04
# Make changes
git commit -m "chore: Prepare release 03.08.04"
git push origin release/03.08.04
```
2. **Create and merge PR**:
- Create PR from release branch
- Review changes
- Merge to main
3. **Create and push tag**:
```bash
git checkout main
git pull
git tag 03.08.04
git push origin 03.08.04
```
4. **Automated process**:
- GitHub Actions builds package automatically
- Creates GitHub Release with artifacts
- `auto-update-sha` workflow updates `updates.xml`
5. **Verify**:
- Check GitHub Release is created
- Verify `updates.xml` has correct SHA-256
- Test Joomla update server
---
## Development Workflow
### Testing Local Builds
```bash
# Build current version
./scripts/build-release.sh
# Install in Joomla
# Navigate to Extensions > Manage > Install > Upload Package File
# Select: build/mokocassiopeia-src-{version}.zip
```
### Pre-Release Checklist
- [ ] All code changes merged to main
- [ ] Version numbers updated:
- [ ] `src/templateDetails.xml`
- [ ] `CHANGELOG.md`
- [ ] CHANGELOG.md updated with release notes
- [ ] Tests passing
- [ ] Documentation updated
- [ ] Local build tested in Joomla
---
## Troubleshooting
### Build Fails
**Problem**: `rsync: command not found`
```bash
# Ubuntu/Debian
sudo apt-get install rsync
# macOS
brew install rsync
```
**Problem**: `zip: command not found`
```bash
# Ubuntu/Debian
sudo apt-get install zip
# macOS (usually pre-installed)
brew install zip
```
### GitHub Actions Fails
**Problem**: Release workflow fails on tag push
Check:
1. Tag format matches pattern: `[0-9][0-9].[0-9][0-9].[0-9][0-9]`
2. Repository has write permissions for GITHUB_TOKEN
3. `src/` and `src/media/` directories exist
**Problem**: auto-update-sha fails
Check:
1. Release package was published successfully
2. Workflow has write permissions
3. Package naming matches expected format
---
## File Structure
```
scripts/
├── README.md # This file
└── build-release.sh # Local build script
.github/workflows/
├── release.yml # Automated release workflow
└── auto-update-sha.yml # SHA hash update workflow
```
---
## Contributing
When adding new scripts:
1. Add GPL-3.0-or-later license header
2. Include FILE INFORMATION block
3. Add usage documentation in this README
4. Make scripts executable: `chmod +x scripts/your-script.sh`
5. Test thoroughly before committing
---
## Support
- **Issues**: [GitHub Issues](https://github.com/mokoconsulting-tech/MokoCassiopeia/issues)
- **Email**: hello@mokoconsulting.tech
- **Documentation**: [docs/](../docs/)
---
## License
All scripts are licensed under GPL-3.0-or-later.
Copyright (C) 2026 Moko Consulting

View File

@@ -1,132 +0,0 @@
#!/usr/bin/env bash
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: Build.Scripts
# INGROUP: MokoCassiopeia.Build
# REPO: https://github.com/mokoconsulting-tech/MokoCassiopeia
# PATH: /scripts/build-release.sh
# VERSION: 01.00.00
# BRIEF: Build release package for MokoCassiopeia template
# USAGE: ./scripts/build-release.sh [version]
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
# Functions
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Check if version is provided
if [ -z "$1" ]; then
# Try to extract version from templateDetails.xml
if [ -f "${PROJECT_ROOT}/src/templateDetails.xml" ]; then
VERSION=$(grep -oP '<version>\K[^<]+' "${PROJECT_ROOT}/src/templateDetails.xml" | head -1)
log_info "Detected version: ${VERSION}"
else
log_error "Please provide version as argument: ./build-release.sh 03.08.03"
exit 1
fi
else
VERSION="$1"
fi
log_info "Building MokoCassiopeia release package"
log_info "Version: ${VERSION}"
# Change to project root
cd "${PROJECT_ROOT}"
# Create build directory
BUILD_DIR="${PROJECT_ROOT}/build"
PACKAGE_DIR="${BUILD_DIR}/package"
rm -rf "${BUILD_DIR}"
mkdir -p "${PACKAGE_DIR}"
log_info "Creating package structure..."
# Copy template files from src (excluding media directory)
if [ -d "src" ]; then
rsync -av --exclude='.git*' --exclude='media' src/ "${PACKAGE_DIR}/"
else
log_error "src directory not found!"
exit 1
fi
# Copy media files from src/media
if [ -d "src/media" ]; then
mkdir -p "${PACKAGE_DIR}/media"
rsync -av --exclude='.git*' src/media/ "${PACKAGE_DIR}/media/"
else
log_warning "src/media directory not found, skipping media files"
fi
log_info "Package structure created"
# Create ZIP package
cd "${PACKAGE_DIR}"
ZIP_NAME="mokocassiopeia-src-${VERSION}.zip"
log_info "Creating ZIP package: ${ZIP_NAME}"
zip -r "../${ZIP_NAME}" . -q
if [ $? -ne 0 ]; then
log_error "Failed to create ZIP package"
exit 1
fi
cd "${BUILD_DIR}"
log_success "Created: ${ZIP_NAME}"
# Generate checksums
log_info "Generating checksums..."
sha256sum "${ZIP_NAME}" > "${ZIP_NAME}.sha256"
md5sum "${ZIP_NAME}" > "${ZIP_NAME}.md5"
# Extract just the hash
SHA256_HASH=$(sha256sum "${ZIP_NAME}" | cut -d' ' -f1)
log_success "SHA-256: ${SHA256_HASH}"
log_success "MD5: $(md5sum "${ZIP_NAME}" | cut -d' ' -f1)"
# Show file info
FILE_SIZE=$(du -h "${ZIP_NAME}" | cut -f1)
log_info "Package size: ${FILE_SIZE}"
# Summary
echo ""
log_success "Build completed successfully!"
echo ""
echo "Package: ${BUILD_DIR}/${ZIP_NAME}"
echo "SHA-256: ${BUILD_DIR}/${ZIP_NAME}.sha256"
echo "MD5: ${BUILD_DIR}/${ZIP_NAME}.md5"
echo ""
echo "Next steps:"
echo "1. Test the package installation in Joomla"
echo "2. Create a GitHub release with this package"
echo "3. Update updates.xml with the new version and SHA-256 hash"
echo ""

View File

@@ -1,188 +0,0 @@
#!/usr/bin/env node
/* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
*
* This file is part of a Moko Consulting project.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
* # FILE INFORMATION
* DEFGROUP: Joomla.Template.Site
* INGROUP: MokoCassiopeia
* REPO: https://github.com/mokoconsulting-tech/MokoCassiopeia
* PATH: ./scripts/minify.js
* VERSION: 03.09.03
* BRIEF: Generates .min.css and .min.js files from the Joomla asset manifest
*/
'use strict';
const fs = require('fs');
const path = require('path');
const CleanCSS = require('clean-css');
const { minify: terserMinify } = require('terser');
// ---------------------------------------------------------------------------
// Config
// ---------------------------------------------------------------------------
const ROOT = path.resolve(__dirname, '..');
const SRC_MEDIA = path.join(ROOT, 'src', 'media');
const ASSET_JSON = path.join(ROOT, 'src', 'joomla.asset.json');
// URI prefix used in the manifest — maps to SRC_MEDIA on disk.
// e.g. "media/templates/site/mokocassiopeia/css/template.css"
const URI_PREFIX = 'media/templates/site/mokocassiopeia/';
// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------
/**
* Resolve a manifest URI to an absolute disk path under src/media/.
*
* @param {string} uri e.g. "media/templates/site/mokocassiopeia/css/foo.css"
* @returns {string|null}
*/
function uriToPath(uri) {
if (!uri.startsWith(URI_PREFIX)) return null;
return path.join(SRC_MEDIA, uri.slice(URI_PREFIX.length));
}
/**
* Return true if the filename looks like an already-minified file or belongs
* to a vendor bundle we don't own.
*/
function isVendorOrUserFile(filePath) {
const rel = filePath.replace(SRC_MEDIA + path.sep, '');
return rel.startsWith('vendor' + path.sep)
|| path.basename(filePath).startsWith('user.');
}
// ---------------------------------------------------------------------------
// Pair detection
// ---------------------------------------------------------------------------
/**
* Read the asset manifest and return an array of { src, dest, type } pairs
* where dest is a minified version of src that doesn't already exist or is
* older than src.
*
* Pairing logic: for every non-.min asset, check whether the manifest also
* contains a corresponding .min asset. If so, that's our pair.
*/
function detectPairs(assets) {
// Build a lookup of all URIs in the manifest.
const uriSet = new Set(assets.map(a => a.uri));
const pairs = [];
for (const asset of assets) {
const { uri, type } = asset;
if (type !== 'style' && type !== 'script') continue;
// Skip already-minified entries.
if (/\.min\.(css|js)$/.test(uri)) continue;
// Derive the expected .min URI.
const minUri = uri.replace(/\.(css|js)$/, '.min.$1');
if (!uriSet.has(minUri)) continue;
const srcPath = uriToPath(uri);
const destPath = uriToPath(minUri);
if (!srcPath || !destPath) continue;
if (isVendorOrUserFile(srcPath)) continue;
if (!fs.existsSync(srcPath)) {
console.warn(` [skip] source missing: ${srcPath}`);
continue;
}
pairs.push({ src: srcPath, dest: destPath, type });
}
return pairs;
}
// ---------------------------------------------------------------------------
// Minifiers
// ---------------------------------------------------------------------------
async function minifyCSS(srcPath, destPath) {
const source = fs.readFileSync(srcPath, 'utf8');
const result = new CleanCSS({ level: 2, returnPromise: true });
const output = await result.minify(source);
if (output.errors && output.errors.length) {
throw new Error(output.errors.join('\n'));
}
fs.mkdirSync(path.dirname(destPath), { recursive: true });
fs.writeFileSync(destPath, output.styles, 'utf8');
const srcSize = Buffer.byteLength(source, 'utf8');
const destSize = Buffer.byteLength(output.styles, 'utf8');
const saving = (100 - (destSize / srcSize * 100)).toFixed(1);
return { srcSize, destSize, saving };
}
async function minifyJS(srcPath, destPath) {
const source = fs.readFileSync(srcPath, 'utf8');
const result = await terserMinify(source, {
compress: { drop_console: false },
mangle: true,
format: { comments: false }
});
if (!result.code) throw new Error('terser returned no output');
fs.mkdirSync(path.dirname(destPath), { recursive: true });
fs.writeFileSync(destPath, result.code, 'utf8');
const srcSize = Buffer.byteLength(source, 'utf8');
const destSize = Buffer.byteLength(result.code, 'utf8');
const saving = (100 - (destSize / srcSize * 100)).toFixed(1);
return { srcSize, destSize, saving };
}
// ---------------------------------------------------------------------------
// Main
// ---------------------------------------------------------------------------
(async () => {
const manifest = JSON.parse(fs.readFileSync(ASSET_JSON, 'utf8'));
const pairs = detectPairs(manifest.assets);
if (pairs.length === 0) {
console.log('No pairs found — nothing to minify.');
return;
}
console.log(`\nMinifying ${pairs.length} file(s)...\n`);
let ok = 0, fail = 0;
for (const { src, dest, type } of pairs) {
const label = path.relative(ROOT, src);
process.stdout.write(` ${label} ... `);
try {
const stats = type === 'style'
? await minifyCSS(src, dest)
: await minifyJS(src, dest);
const kb = n => (n / 1024).toFixed(1) + ' kB';
console.log(`${kb(stats.srcSize)}${kb(stats.destSize)} (${stats.saving}% saved)`);
ok++;
} catch (err) {
console.error(`FAILED\n ${err.message}`);
fail++;
}
}
console.log(`\nDone. ${ok} succeeded, ${fail} failed.\n`);
if (fail > 0) process.exit(1);
})();