This directory contains workflow configurations for automatically copying code examples to destination repositories.
What is this? An automated system that copies your code examples to other repositories when you merge a PR.
What do I need to know?
- When you merge a PR in this repo, the copier automatically runs
- Files are matched against patterns in
.copier/config.yaml - Matched files are copied to destination repositories
- A PR is created in each destination repository (usually)
- Someone needs to review and merge the destination PRs (unless auto-merge is enabled)
What happens to deleted files?
- They are NOT automatically deleted from destination repositories
- They are tracked in
deprecated_examples.jsonfor manual cleanup
Do I need to do anything?
- Usually no! Just merge your PR as normal
- Check destination repositories to ensure PRs are created
- If something goes wrong, contact the DevEx team
Where are the logs?
gcloud run services logs read github-copier --limit=100Place your workflow configuration at: .copier/config.yaml
workflows:
- name: "my-workflow"
destination:
repo: "mongodb/destination-repo"
branch: "main"
transformations:
- move:
from: "source/path"
to: "destination/path"All file paths in transformations are relative to the repository root, not to the config file location.
Even though your config is at .copier/config.yaml, patterns and paths are matched against the full repository path:
# ✅ Correct - paths from repository root
transformations:
- move:
from: "examples/go"
to: "code"
# ❌ Wrong - don't use relative paths like ../
transformations:
- move:
from: "../examples/go" # Don't do this!
to: "code"-
Edit
.copier/config.yamlin your repository -
Add a new workflow entry:
workflows:
- name: "my-new-workflow"
destination:
repo: "mongodb/my-destination-repo"
branch: "main"
transformations:
- move:
from: "examples/my-code"
to: "code"- Commit and push - the workflow is now active!
Simply edit the workflow in .copier/config.yaml and commit your changes. The updated configuration will be used for the next PR merge.
Copy all files from one directory to another:
transformations:
- move:
from: "examples/go"
to: "code/go"Copy a specific file:
transformations:
- copy:
from: "README.md"
to: "docs/README.md"Use glob patterns for flexible matching:
transformations:
- glob:
pattern: "examples/**/*.go"
transform: "code/${relative_path}"Choose how files are committed to destination repositories:
Creates a PR in the destination repository for review:
commit_strategy:
type: "pull_request"
pr_title: "Update examples from ${source_repo}"
pr_body: |
Automated update from source repository.
Source PR: #${pr_number}
Commit: ${commit_sha}
auto_merge: false # Requires manual review and mergeWhen to use:
- When destination repo requires code review
- When you want to run CI/CD tests before merging
- When changes need approval (most common)
Creates a PR and automatically merges it if there are no conflicts:
commit_strategy:
type: "pull_request"
auto_merge: true # Automatically merges if no conflictsWhen to use:
- When destination repo has automated tests that must pass
- When you trust the source content completely
- When you want fast propagation with safety checks
Commits directly to the destination branch (no PR):
commit_strategy:
type: "direct"
commit_message: "Update examples from ${source_repo}"When to use:
- When destination repo doesn't require review
- When you need immediate updates
- When you have full confidence in the source content
Use these variables in PR titles, bodies, and commit messages:
${source_repo}- Source repository name${source_branch}- Source branch name${pr_number}- Source PR number${commit_sha}- Source commit SHA${file_count}- Number of files changed
Use these in path transformations:
${relative_path}- Path relative to the matched pattern${path}- Full source file path${filename}- Just the filename${dir}- Directory path${ext}- File extension
Prevent certain files from being copied:
workflows:
- name: "my-workflow"
destination:
repo: "mongodb/destination-repo"
branch: "main"
transformations:
- move: { from: "src", to: "dest" }
exclude:
- "**/.env" # Environment files
- "**/node_modules/**" # Dependencies
- "**/*.test.js" # Test files
- "**/.DS_Store" # Mac system filesCommon exclusions:
- Environment files:
**/.env,**/.env.* - Dependencies:
**/node_modules/**,**/vendor/** - Build artifacts:
**/dist/**,**/build/** - Test files:
**/*.test.*,**/tests/** - System files:
**/.DS_Store,**/Thumbs.db
Apply settings to all workflows in this file:
defaults:
commit_strategy:
type: "pull_request"
auto_merge: false
exclude:
- "**/.env"
- "**/node_modules/**"
workflows:
- name: "workflow-1"
# inherits defaults
destination:
repo: "mongodb/dest-1"
transformations:
- move: { from: "src", to: "dest" }
- name: "workflow-2"
# inherits defaults
destination:
repo: "mongodb/dest-2"
transformations:
- move: { from: "examples", to: "code" }Before committing, you can validate your configuration:
# Validate syntax
./config-validator validate -config .copier/config.yaml
# Test a pattern match
./config-validator test-pattern \
-type glob \
-pattern "examples/**/*.go" \
-file "examples/database/connect.go"- You merge a PR in this repository
- GitHub sends a webhook to the copier application
- Copier loads your workflows from
.copier/config.yaml - Files are matched against transformation patterns
- Files are copied to destination repositories
- PRs are created in destination repositories (or committed directly)
✅ Triggers:
- Merging a PR (action:
closed+merged: true)
❌ Does NOT trigger:
- Opening a PR
- Updating a PR
- Closing a PR without merging
- Direct commits to main branch (no PR)
- Draft PRs
Added or Modified Files:
- Matched against transformation patterns
- Copied to destination repository
- Included in destination PR
Deleted Files:
- Matched against transformation patterns
- Added to deprecation tracking file (if enabled)
- NOT automatically deleted from destination
- Manual cleanup required (see Deprecation Tracking below)
When you merge a PR in this repository, the copier creates a PR in each destination repository:
PR Structure:
- Branch name:
copier/YYYYMMDD-HHMMSS(e.g.,copier/20240115-143022) - Base branch: The branch specified in your workflow (usually
main) - Title: From your
pr_titleconfiguration - Body: From your
pr_bodyconfiguration - Files: All matched files from your source PR
Example:
Source PR: mongodb/docs-code-examples #123
↓
Destination PR: mongodb/go-examples-repo #45
Branch: copier/20240115-143022
Files: 5 files changed
Status: Open (awaiting review)
If auto_merge: false (default):
- PR is created and left open
- Destination repo maintainers review the PR
- CI/CD tests run (if configured)
- Someone manually merges the PR
If auto_merge: true:
- PR is created
- Copier waits for GitHub to compute mergeability
- If no conflicts: PR is automatically merged
- If conflicts: PR is left open for manual resolution
- Temporary branch is deleted after merge
If type: "direct":
- No PR is created
- Files are committed directly to the target branch
- No review process
When you delete files from this repository, the copier can track them for cleanup in destination repositories.
- You delete a file and merge the PR
- Copier detects the deletion and matches it against patterns
- File is added to
deprecated_examples.jsonin this repository - You manually clean up the file from destination repositories
workflows:
- name: "my-workflow"
destination:
repo: "mongodb/destination-repo"
branch: "main"
transformations:
- move: { from: "examples", to: "code" }
deprecation_check:
enabled: true
file: "deprecated_examples.json" # Optional: custom filenameThe deprecation file is stored in this repository (source):
[
{
"filename": "code/go/old-example.go",
"repo": "mongodb/destination-repo",
"branch": "main",
"deleted_on": "2024-01-15T10:30:00Z"
}
]- Review
deprecated_examples.jsonperiodically - Create PRs in destination repositories to remove deprecated files
- Remove entries from
deprecated_examples.jsonafter cleanup
Note: Files are NOT automatically deleted from destination repositories. Deprecation tracking only records what needs to be cleaned up.
- Full Documentation: Code Example Tooling Repository
- Configuration Examples: See
github-copier/configs/copier-config-examples/ - Pattern Matching Guide: See
github-copier/docs/PATTERN-MATCHING-GUIDE.md - Main Config Architecture: See
github-copier/configs/copier-config-examples/MAIN-CONFIG-README.md - Deprecation Tracking: See
github-copier/docs/DEPRECATION-TRACKING-EXPLAINED.md
# .copier/config.yaml
defaults:
commit_strategy:
type: "pull_request"
auto_merge: false
exclude:
- "**/.env"
- "**/node_modules/**"
workflows:
- name: "go-examples"
destination:
repo: "mongodb/go-examples-repo"
branch: "main"
transformations:
- move:
from: "examples/go"
to: "code"
commit_strategy:
pr_title: "Update Go examples from ${source_repo}"
pr_body: |
Automated update of Go code examples.
**Source**: ${source_repo} (PR #${pr_number})
**Commit**: ${commit_sha}
**Files**: ${file_count} changed
deprecation_check:
enabled: true
file: "deprecated_examples.json"Check:
- Was it a merged PR? (not just closed)
- Do the changed files match your transformation patterns?
- Check the copier logs (see below)
- Verify
.copier/config.yamlis valid YAML
# View recent logs (Cloud Run)
gcloud run services logs read github-copier --limit=100# Validate YAML syntax
./config-validator validate -config .copier/config.yaml
# Test a pattern match
./config-validator test-pattern \
-type glob \
-pattern "examples/**/*.go" \
-file "examples/database/connect.go"Check:
- Are your paths relative to repository root? (not relative to config file)
- Is your
transformpattern correct? - Test with
config-validatortool
Create multiple workflows, one for each destination:
workflows:
- name: "copy-to-docs"
destination:
repo: "mongodb/docs"
transformations:
- move: { from: "examples", to: "code" }
- name: "copy-to-website"
destination:
repo: "mongodb/website"
transformations:
- move: { from: "examples", to: "static/examples" }Contact the Developer Docs team or open an issue in the github-copier repository.