Recipes and Patterns
Practical examples for common use cases.
Standard Project Setups
Rust CLI Project
A complete Rust CLI project with CI, pre-commit hooks, and conventional commits.
# .common-repo.yaml
# Inherit base Rust CLI configuration
- repo:
url: https://github.com/common-repo/rust-cli
ref: v2.0.0
with:
- include: ["**/*"]
- exclude: [".git/**", "target/**", "src/**"]
# Add pre-commit hooks for Rust
- repo:
url: https://github.com/common-repo/pre-commit-rust
ref: v1.0.0
with:
- include: [".pre-commit-config.yaml"]
# Project-specific variables
- template-vars:
project_name: my-cli
author: Your Name
description: A command-line tool
# Mark config files as templates
- template:
- Cargo.toml
- README.md
- .github/workflows/*.yml
# Require essential tools
- tools:
- rustc: ">=1.70"
- cargo: "*"
- pre-commit: ">=3.0"
Python Project with UV
Modern Python project using UV for dependency management.
# .common-repo.yaml
# Base Python project structure
- repo:
url: https://github.com/common-repo/python-uv
ref: v1.0.0
with:
- include: ["**/*"]
- exclude: [".git/**", "__pycache__/**", ".venv/**"]
# Pre-commit hooks for Python
- repo:
url: https://github.com/common-repo/pre-commit-python
ref: v1.5.0
with:
- include: [".pre-commit-config.yaml"]
# Variables
- template-vars:
project_name: my-python-project
python_version: "3.11"
author: Your Name
- template:
- pyproject.toml
- README.md
- tools:
- python: ">=3.11"
- uv: "*"
Node.js/TypeScript Project
TypeScript project with ESLint, Prettier, and GitHub Actions.
# .common-repo.yaml
# TypeScript base configuration
- repo:
url: https://github.com/common-repo/typescript
ref: v3.0.0
with:
- include:
- tsconfig.json
- .eslintrc.json
- .prettierrc
- .github/**
# Add package.json dependencies
- json:
source: dev-deps.json
dest: package.json
path: devDependencies
- template-vars:
project_name: my-project
node_version: "20"
- tools:
- node: ">=20"
- npm: ">=10"
Upstream Repo Patterns
Upstream Repo That Consumes Its Own Tooling
An upstream repo that provides shared configuration to consumers, while also pulling CI and release tooling for its own use. The self: block keeps local consumption separate from the source API.
# .common-repo.yaml in an upstream repo
# Pull tooling for this repo only — consumers never see this
- self:
- repo:
url: https://github.com/org/release-tooling
ref: v3.0.0
- repo:
url: https://github.com/org/ci-base
ref: v1.2.0
- exclude:
- ".releaserc.yaml"
- "commitlint.config.cjs"
# Source API — what consumers inherit
- include:
- "configs/**"
- ".github/**"
- template:
- ".github/workflows/ci.yml"
- template-vars:
GH_APP_ID_VAR: ORG_APP_ID
- rename:
- from: "^configs/(.*)$"
to: "$1"
Without self:, the release tooling and CI base files would leak into every consumer that inherits from this repo. See Authoring Upstream Repositories for more details.
CI/CD Patterns
GitHub Actions Workflow Inheritance
Inherit and customize GitHub Actions workflows.
# .common-repo.yaml
# Base CI workflows
- repo:
url: https://github.com/your-org/ci-templates
ref: v2.0.0
with:
- include: [".github/**"]
# Add project-specific jobs to CI
- yaml:
source: local-ci-jobs.yml
dest: .github/workflows/ci.yml
path: jobs
append: true
# Customize workflow variables
- template-vars:
default_branch: main
node_version: "20"
deploy_environment: production
- template:
- ".github/workflows/*.yml"
local-ci-jobs.yml:
integration-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run integration tests
run: ./scripts/integration-test.sh
Multi-Stage Deployment
Different configurations for different environments.
# .common-repo.yaml
# Base deployment configuration
- repo:
url: https://github.com/your-org/deploy-configs
ref: v1.0.0
path: kubernetes # Only kubernetes configs
# Environment-specific overrides
- yaml:
source: env/production.yml
dest: kubernetes/deployment.yml
path: spec.template.spec
- template-vars:
environment: staging
replicas: "3"
image_tag: latest
- template:
- "kubernetes/*.yml"
Organization Standards
Company-Wide Defaults
Create a base configuration that all projects inherit.
In your org’s base repo (github.com/your-org/base-config):
# .common-repo.yaml (this repo exports these files)
- include:
- .editorconfig
- .gitignore
- .github/CODEOWNERS
- .github/PULL_REQUEST_TEMPLATE.md
- .github/ISSUE_TEMPLATE/**
- LICENSE
- template-vars:
org_name: Your Organization
support_email: support@your-org.com
In each project:
# .common-repo.yaml
# Inherit org-wide defaults
- repo:
url: https://github.com/your-org/base-config
ref: v1.0.0
# Add language-specific configuration
- repo:
url: https://github.com/your-org/rust-standards
ref: v2.0.0
# Project-specific customization
- template-vars:
project_name: my-service
team: platform
Security Configurations
Standardize security tooling across projects.
# .common-repo.yaml
# Security scanning configuration
- repo:
url: https://github.com/your-org/security-configs
ref: v1.2.0
with:
- include:
- .github/workflows/security.yml
- .snyk
- .trivyignore
# Merge security checks into existing CI
- yaml:
source: security-jobs.yml
dest: .github/workflows/ci.yml
path: jobs
append: true
Monorepo Patterns
Shared Configuration Across Packages
Use path filtering to share configs in a monorepo.
# packages/web/.common-repo.yaml
# Inherit from monorepo root configs
- repo:
url: https://github.com/your-org/your-monorepo
ref: main
path: shared/web-configs
with:
- include: ["**/*"]
# Package-specific settings
- template-vars:
package_name: web
port: "3000"
Multiple Config Repositories
Compose from multiple specialized config repos.
# .common-repo.yaml
# Linting standards
- repo:
url: https://github.com/your-org/lint-configs
ref: v2.0.0
with:
- include: [".eslintrc.json", ".prettierrc"]
# Testing configuration
- repo:
url: https://github.com/your-org/test-configs
ref: v1.5.0
with:
- include: ["jest.config.js", "vitest.config.ts"]
# CI/CD templates
- repo:
url: https://github.com/your-org/ci-configs
ref: v3.0.0
with:
- include: [".github/**"]
Configuration Merging
Extending package.json
Add dependencies without overwriting the whole file.
# .common-repo.yaml
# Base project
- repo:
url: https://github.com/your-org/node-base
ref: v1.0.0
# Add shared dev dependencies
- json:
source: shared-dev-deps.json
dest: package.json
path: devDependencies
# Add shared scripts
- json:
source: shared-scripts.json
dest: package.json
path: scripts
append: true
shared-dev-deps.json:
{
"eslint": "^8.0.0",
"prettier": "^3.0.0",
"typescript": "^5.0.0"
}
Merging Cargo.toml Dependencies
Add common Rust dependencies.
# .common-repo.yaml
- repo:
url: https://github.com/your-org/rust-base
ref: v1.0.0
# Add logging dependencies
- toml:
source: logging-deps.toml
dest: Cargo.toml
path: dependencies
# Add dev dependencies
- toml:
source: dev-deps.toml
dest: Cargo.toml
path: dev-dependencies
logging-deps.toml:
tracing = "0.1"
tracing-subscriber = "0.3"
Extending Pre-commit Hooks
Add hooks to an existing pre-commit configuration.
# .common-repo.yaml
# Base pre-commit config
- repo:
url: https://github.com/your-org/pre-commit-base
ref: v1.0.0
with:
- include: [".pre-commit-config.yaml"]
# Add additional hooks
- yaml:
source: extra-hooks.yml
dest: .pre-commit-config.yaml
path: repos
append: true
extra-hooks.yml:
- repo: local
hooks:
- id: custom-check
name: Custom Check
entry: ./scripts/check.sh
language: script
Advanced Patterns
Conditional Configuration via Environment
Use environment variables for conditional behavior.
# .common-repo.yaml
- repo:
url: https://github.com/your-org/base-config
ref: v1.0.0
- template-vars:
# Default to development settings
log_level: debug
enable_metrics: "false"
# CI-specific overrides
ci_mode: "false"
- template:
- config/*.yml
Version Pinning Strategy
Pin specific versions while allowing updates.
# .common-repo.yaml
# Pin to specific major version for stability
- repo:
url: https://github.com/your-org/stable-configs
ref: v2.0.0 # Update manually for major versions
# Use branch for frequently updated configs
- repo:
url: https://github.com/your-org/evolving-configs
ref: main # Always get latest (use with caution)
# Use commit SHA for maximum reproducibility
- repo:
url: https://github.com/your-org/critical-configs
ref: abc123def456 # Exact commit
Template File Patterns
Use template files for customization.
In config repo:
templates/
Cargo.toml.template
README.md.template
In .common-repo.yaml:
- repo:
url: https://github.com/your-org/rust-templates
ref: v1.0.0
with:
- include: ["templates/**"]
- rename:
- "templates/(.+)\\.template$": "$1"
- template-vars:
project_name: my-project
description: A great project
license: MIT
- template:
- Cargo.toml
- README.md
Debugging Tips
Verbose Output
# See detailed processing (debug level)
common-repo apply --verbose
# Maximum verbosity (trace level)
common-repo apply --verbose --verbose
Inspect Before Applying
# List what would be created
common-repo ls -l
# See the diff
common-repo diff
# Dry run
common-repo apply --dry-run
Check Inheritance
# View inheritance tree
common-repo tree
# Get configuration overview
common-repo info
Validate Configuration
# Check syntax
common-repo validate
# Also check repo accessibility
common-repo validate --check-repos