Examples
Real-world examples of script caching for common build workflows.
TypeScript Compilation
Cache TypeScript compilation with automatic invalidation when source files change.
#!/usr/bin/env bash
#FABRIK input "src/**/*.ts"
#FABRIK input "src/**/*.tsx"
#FABRIK input "tsconfig.json"
#FABRIK input "package.json"
#FABRIK output "dist/"
#FABRIK env "NODE_ENV"
echo "Compiling TypeScript..."
npx tscRun:
fabrik run compile-ts.shCode Generation
Cache code generation that depends on schema files.
#!/usr/bin/env node
#FABRIK input "schema/**/*.graphql"
#FABRIK input "codegen.yml"
#FABRIK output "src/generated/"
// Generate TypeScript types from GraphQL schema
const { exec } = require('child_process');
exec('graphql-codegen --config codegen.yml', (error, stdout, stderr) => {
if (error) {
console.error(stderr);
process.exit(1);
}
console.log(stdout);
});Run:
fabrik run codegen.jsImage Optimization
Cache image processing with size-based input tracking (faster for large files).
#!/usr/bin/env bash
#FABRIK input "assets/images/**/*.png" hash=size
#FABRIK input "assets/images/**/*.jpg" hash=size
#FABRIK output "dist/images/"
echo "Optimizing images..."
mkdir -p dist/images
# Optimize all images
for img in assets/images/*; do
filename=$(basename "$img")
magick "$img" -quality 85 -strip "dist/images/$filename"
doneRun:
fabrik run optimize-images.shTest Runner
Cache test execution when source files haven't changed.
#!/usr/bin/env bash
#FABRIK input "src/**/*.ts"
#FABRIK input "tests/**/*.test.ts"
#FABRIK input "jest.config.js"
#FABRIK output "coverage/"
#FABRIK env "CI"
echo "Running tests..."
npm test -- --coverageRun:
fabrik run test.shNote: Only cache if tests are deterministic. Skip flaky tests or tests with external dependencies.
Dependency Installation
Cache node_modules when package.json or lock file hasn't changed.
#!/usr/bin/env bash
#FABRIK input "package.json"
#FABRIK input "package-lock.json"
#FABRIK output "node_modules/"
echo "Installing dependencies..."
npm ciRun:
fabrik run install-deps.shDocker Image Build
Cache Docker image builds with multi-stage caching.
#!/usr/bin/env bash
#FABRIK input "Dockerfile"
#FABRIK input "src/**/*.go"
#FABRIK input "go.mod"
#FABRIK input "go.sum"
#FABRIK output "image-digest.txt"
#FABRIK env "DOCKER_BUILDKIT"
echo "Building Docker image..."
docker build -t myapp:latest . --iidfile=image-digest.txtRun:
fabrik run docker-build.shMulti-Step Pipeline
Chain multiple scripts with dependencies.
Step 1: Install dependencies
#!/usr/bin/env bash
# install.sh
#FABRIK input "package.json"
#FABRIK input "package-lock.json"
#FABRIK output "node_modules/"
npm ciStep 2: Build application
#!/usr/bin/env bash
# build.sh
#FABRIK input "src/**/*.ts"
#FABRIK input "tsconfig.json"
#FABRIK depends "./install.sh" use-outputs=#true
#FABRIK output "dist/"
npm run buildStep 3: Run tests
#!/usr/bin/env bash
# test.sh
#FABRIK input "tests/**/*.test.ts"
#FABRIK depends "./build.sh" use-outputs=#true
#FABRIK output "coverage/"
npm test -- --coverageRun:
# Run the entire pipeline (automatically resolves dependencies)
fabrik run test.shLinting & Formatting
Cache linting results when source files haven't changed.
#!/usr/bin/env bash
#FABRIK input "src/**/*.ts"
#FABRIK input ".eslintrc.js"
#FABRIK input ".prettierrc"
#FABRIK output ".lint-cache/"
echo "Running ESLint..."
npx eslint src/ --cache --cache-location .lint-cache/
echo "Running Prettier..."
npx prettier src/ --checkRun:
fabrik run lint.shAsset Bundling
Cache webpack/rollup builds with proper input tracking.
#!/usr/bin/env bash
#FABRIK input "src/**/*.js"
#FABRIK input "src/**/*.css"
#FABRIK input "webpack.config.js"
#FABRIK input "package.json"
#FABRIK output "dist/"
#FABRIK env "NODE_ENV"
#FABRIK exec timeout="10m"
echo "Bundling assets..."
npx webpack --mode productionRun:
NODE_ENV=production fabrik run bundle.shPython Data Processing
Cache Python script execution with virtual environment.
#!/usr/bin/env python3
#FABRIK input "data/*.csv"
#FABRIK input "requirements.txt"
#FABRIK output "processed/"
#FABRIK env "PROCESSING_MODE"
import pandas as pd
import os
mode = os.getenv('PROCESSING_MODE', 'standard')
print(f"Processing data in {mode} mode...")
# Read all CSV files
for file in os.listdir('data'):
if file.endswith('.csv'):
df = pd.read_csv(f'data/{file}')
# Process data...
df.to_csv(f'processed/{file}', index=False)Run:
fabrik run process-data.pyProtobuf Generation
Cache protobuf compilation.
#!/usr/bin/env bash
#FABRIK input "proto/**/*.proto"
#FABRIK output "src/generated/"
echo "Generating protobuf code..."
mkdir -p src/generated
protoc \
--proto_path=proto \
--go_out=src/generated \
--go_opt=paths=source_relative \
proto/**/*.protoRun:
fabrik run gen-proto.shEnvironment-Specific Builds
Use environment variables to create separate caches per environment.
#!/usr/bin/env bash
#FABRIK input "src/**/*.ts"
#FABRIK input "config/${BUILD_ENV}.json"
#FABRIK output "dist/"
#FABRIK env "BUILD_ENV"
#FABRIK env "API_URL"
echo "Building for $BUILD_ENV environment..."
npm run build -- --env=$BUILD_ENVRun:
# Each environment gets its own cache
BUILD_ENV=development fabrik run build.sh
BUILD_ENV=staging fabrik run build.sh
BUILD_ENV=production fabrik run build.shCustom Cache Keys
Manually version your cache for breaking changes.
#!/usr/bin/env bash
#FABRIK input "src/**/*.ts"
#FABRIK output "dist/"
#FABRIK cache key="v2" # Bump this to invalidate all caches
# After major refactoring, bump key to v3 to bust all caches
npm run buildRun:
fabrik run build.shTime-Based Cache Expiration
Cache nightly reports with 24-hour expiration.
#!/usr/bin/env bash
#FABRIK input "data/*.log"
#FABRIK output "reports/"
#FABRIK cache ttl="24h"
echo "Generating daily report..."
./generate-report.sh > reports/$(date +%Y-%m-%d).htmlRun:
fabrik run daily-report.shCI/CD Integration
Example GitHub Actions workflow using script caching.
name: Build
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Install Fabrik
- run: curl -fsSL https://fabrik.sh/install | bash
# All scripts use caching automatically
- run: fabrik run install-deps.sh
- run: fabrik run build.sh
- run: fabrik run test.sh
# Check cache statistics
- run: fabrik cache statsAdvanced: Conditional Caching
Disable caching for release builds.
#!/usr/bin/env bash
if [ "$RELEASE_BUILD" = "true" ]; then
#FABRIK cache disable
fi
#FABRIK input "src/**/*.ts"
#FABRIK output "dist/"
npm run buildRun:
# Development build (cached)
fabrik run build.sh
# Release build (not cached)
RELEASE_BUILD=true fabrik run build.shDebugging
Use verbose mode to see exactly what's happening.
# See input/output tracking and cache operations
fabrik run --verbose build.sh
# Dry run to see cache key without executing
fabrik run --dry-run build.sh
# Force re-execution
fabrik run --no-cache build.sh
# Clean cache and re-execute
fabrik run --clean build.shSee Also
- Introduction - Overview and quick start
- Annotations Reference - Complete directive reference