Cache metanorma-related assets to speed up CI builds.
- System Asset Caching - Always caches metanorma system directories
- Site Output Caching - Conditionally caches generated site output based on source files
- Cross-Platform - Works on Linux, macOS, and Windows runners
- Type-Safe - Written in TypeScript with full type definitions
- Modern Stack - Built with Node 24, ES2024, and Vitest
By default, this action caches metanorma system assets:
- uses: actions-mn/cache@v2This caches the following directories across both Docker and Ubuntu environments:
~/.metanormaand/root/.metanorma~/.fontistand/root/.fontist~/.relatonand/root/.relaton~/.metanorma-ietf-workgroup-cache.jsonand/root/.metanorma-ietf-workgroup-cache.json
Note: The action automatically detects which paths are accessible in your environment and only caches paths that exist. See Runtime Environments for details.
To cache the generated site output based on your metanorma.yml manifest:
- uses: actions-mn/cache@v2
with:
cache-site-for-manifest: metanorma.ymlThis will:
- Parse your
metanorma.ymlmanifest file - Hash all source files listed in
metanorma.source.files - Generate a cache key based on the file hashes
- Cache the site output directory (default:
_site)
- uses: actions-mn/cache@v2
with:
cache-site-for-manifest: path/to/metanorma.yml
extra-input: |
assets
templates
config
cache-site-path: site| Input | Description | Default | Required |
|---|---|---|---|
cache-site-for-manifest |
Path to metanorma.yml manifest file | '' |
No |
extra-input |
Comma/line separated directories affecting build (relative to manifest) | '' |
No |
cache-site-path |
Path to output site directory | _site |
No |
| Output | Description |
|---|---|
cache-site-cache-hit |
"true" if site cache was hit, "false" otherwise |
Metanorma CI builds run in two different environments. This action handles both automatically:
When running directly on GitHub Actions ubuntu-latest runners:
- User:
runner(non-privileged user) - Home directory:
/home/runner - Accessible paths:
~/.metanorma→/home/runner/.metanorma✓~/.fontist→/home/runner/.fontist✓~/.relaton→/home/runner/.relaton✓
- Inaccessible paths (permission denied):
/root/.metanorma✗/root/.fontist✗/root/.relaton✗
When running inside Metanorma Docker containers (via actions-mn/setup or directly):
- User:
root(or container user with root privileges) - Home directory:
/root - Accessible paths:
~/.metanorma→/root/.metanorma✓~/.fontist→/root/.fontist✓~/.relaton→/root/.relaton✓/root/.metanorma✓ (same as~/.metanormain container)/root/.fontist✓/root/.relaton✓
This action automatically detects which paths are accessible:
- Each cache path is checked for existence using
fs.existsSync() - Inaccessible paths (like
/root/.metanormaon Ubuntu runners) are silently skipped - Only accessible paths are included in cache operations
- This prevents
EACCES: permission deniederrors
Example - On Ubuntu runner, only these paths are cached:
# Cached:
/home/runner/.metanorma
/home/runner/.fontist
/home/runner/.relaton
# Skipped (permission denied):
/root/.metanorma
/root/.fontist
/root/.relatonExample - In Docker container, all paths are cached:
# Cached:
/root/.metanorma
/root/.fontist
/root/.relatonThis action implements a two-tier caching strategy:
-
System Cache (Always) - Caches metanorma installation assets
- Four independent cache entries (not one combined cache):
metanorma-home→~/.metanorma,/root/.metanormametanorma-relaton→~/.relaton,/root/.relatonmetanorma-fontist→~/.fontist,/config/fonts,/root/.fontistmetanorma-ietf-workgroup-cache→~/.metanorma-ietf-workgroup-cache.json,/root/...
- Four independent cache entries (not one combined cache):
-
Site Cache (Conditional) - Caches generated site output
- Key:
metanorma-site-cache-{hash} - Hash computed from source files in manifest
- Only enabled when
cache-site-for-manifestis provided
- Key:
The site cache key is generated by:
- Reading
metanorma.source.filesfrom the manifest - Extracting parent directories of each source file
- Adding any
extra-inputdirectories - Computing SHA256 hash of all matched files
This ensures the cache is invalidated when any source file changes.
The system cache (metanorma-cache) is shared across all repositories that use this action. This is intentional because:
- Metanorma fonts are universal and reusable across projects
- Fontist and Relaton caches contain generic data
- Sharing reduces overall cache storage and improves hit rates
Note: Your repository's site cache is unique to your project (based on your source file hashes).
name: Build Metanorma Site
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions-mn/setup@main
- uses: actions-mn/cache@v2
with:
cache-site-for-manifest: metanorma.yml
- uses: actions-mn/site-gen@main
with:
source-path: .
config-file: metanorma.yml
agree-to-terms: true
output-dir: siteIf caching doesn't seem to be working:
- Check the cache key: Ensure your
metanorma.ymlfile exists and has validsource.filesentries - Verify file paths: All source files must exist relative to the manifest file location
- Check cache size: GitHub Actions cache has a 10GB per repository limit
The action validates manifest files and will fail with clear error messages for:
- Non-existent files:
Manifest file "path/to/metanorma.yml" does not exist - Wrong extension:
Manifest file must have .yml or .yaml extension - Path is directory:
Path is a directory, not a file - Home directory paths:
Path starts with ~. Use "$HOME" instead - Path traversal: Paths containing
..are rejected for security reasons
This is expected behavior. The cache key is computed from the hash of all source files. When any source file changes:
- The hash changes
- A new cache key is generated
- Cache miss occurs and new output is built
- New output is cached for future runs
- System Cache (
~/.metanorma,~/.fontist,~/.relaton) is always cached regardless of inputs - Site Cache only runs when
cache-site-for-manifestis provided - If you only need system caching, use the action without any inputs
The action requires no special permissions for basic caching. If you see permission errors:
- Ensure the workflow has
contents: readpermission (default on public repos) - For private repos, you may need to explicitly set
permissions: contents: read
Note: This action automatically handles permission errors for cache paths. Inaccessible paths (like /root/.metanorma on Ubuntu runners where the user is runner, not root) are silently skipped. You will see debug messages like:
Path does not exist, skipping: /root/.metanorma
This is expected behavior and not an error.
This repository includes comprehensive tests:
| Test Type | Description | Location |
|---|---|---|
| Unit Tests | Vitest tests for action logic (mocked cache) | __test__/*.test.ts |
| Integration Tests | Real Metanorma builds on multiple OSes | .github/workflows/integration-test.yml |
| Environment Tests | Docker vs Ubuntu runner scenarios | .github/workflows/test.yml |
# Install dependencies
npm ci
# Run unit tests
npm test
# Run linting
npm run lint
# Run format check
npm run format-check
# Build production bundle
npm run buildThe integration tests cover these scenarios:
- Cold Start (No Cache) - First time running, no cache exists
- Warm Start (Cache Hit) - Second run with cache from previous run
- Ubuntu Runner - Running on GitHub Actions
ubuntu-latest(user:runner) - Docker Container - Running inside Metanorma Docker (user:
root) - Cross-Platform - Linux, macOS, Windows
- Site Cache - Manifest-based site output caching
- System Cache Only - Without manifest (just fonts/relaton)
MIT