Configuration File Structure
Configuration File Structure
Section titled “Configuration File Structure”Copybara uses Starlark configuration files, typically named copy.bara.sky.
Basic Structure
Section titled “Basic Structure”# Variables (optional)internal_url = "https://github.com/org/internal"external_url = "https://github.com/org/external"
# Workflow definitionscore.workflow( name = "export", origin = git.origin(url = internal_url, ref = "main"), destination = git.destination(url = external_url, push = "main"), authoring = authoring.pass_thru("Bot <bot@example.com>"), transformations = [...],)
# Additional workflowscore.workflow( name = "import", ...)File Naming
Section titled “File Naming”| File | Purpose |
|---|---|
copy.bara.sky | Standard configuration file |
*.bara.sky | Any .bara.sky extension works |
Variables
Section titled “Variables”Define reusable values at the top:
# Repository URLsinternal_repo = "https://github.com/myorg/internal"public_repo = "https://github.com/myorg/public"
# Common patternsinternal_globs = glob(["**/internal/**"])public_files = glob(["src/**", "docs/**"])
# Author infodefault_author = "Sync Bot <sync@example.com>"Functions
Section titled “Functions”Define reusable transformation functions:
def common_transforms(): """Transformations used in multiple workflows.""" return [ core.replace("internal.corp", "example.com"), core.verify_match( regex = "SECRET", verify_no_match = True, ), ]
core.workflow( name = "export", transformations = common_transforms() + [ core.move("src/", ""), ], ...)Multiple Workflows
Section titled “Multiple Workflows”One file can contain multiple workflows:
# Export: internal → externalcore.workflow( name = "export", origin = git.origin(url = internal_url, ref = "main"), destination = git.github_destination(url = external_url, push = "main"), ...)
# Import: external PRs → internalcore.workflow( name = "import", origin = git.github_pr_origin(url = external_url, branch = "main"), destination = git.gerrit_destination(url = internal_url, ...), ...)
# Validate: dry runcore.workflow( name = "validate", origin = git.origin(url = internal_url, ref = "main"), destination = folder.destination(), ...)Run specific workflow:
java -jar copybara.jar migrate copy.bara.sky exportjava -jar copybara.jar migrate copy.bara.sky importConditional Logic
Section titled “Conditional Logic”Use Starlark conditionals:
# Environment-based configurationis_production = True
transforms = [ core.move("src/", "lib/"),]
if is_production: transforms.append( core.verify_match(regex = "DEBUG", verify_no_match = True) )
core.workflow( name = "export", transformations = transforms, ...)Imports
Section titled “Imports”Split configuration across files:
def standard_transforms(): return [ core.replace("internal", "external"), ]
INTERNAL_URL = "https://github.com/org/internal"load("common.bara.sky", "standard_transforms", "INTERNAL_URL")
core.workflow( name = "export", origin = git.origin(url = INTERNAL_URL, ref = "main"), transformations = standard_transforms(), ...)Comments
Section titled “Comments”Use # for comments:
# Main export workflow# Syncs internal code to public GitHub repositorycore.workflow( name = "export", # Unique identifier origin = git.origin( url = "https://github.com/org/internal", ref = "main", # Track main branch ), ...)Organization Patterns
Section titled “Organization Patterns”By Direction
Section titled “By Direction”copybara/├── export.bara.sky # Internal → External├── import.bara.sky # External → Internal└── common.bara.sky # Shared definitionsBy Target
Section titled “By Target”copybara/├── github.bara.sky # Sync to GitHub├── gerrit.bara.sky # Sync to Gerrit└── common.bara.sky # Shared definitionsSingle File
Section titled “Single File”copy.bara.sky # All workflows in one fileComplete Example
Section titled “Complete Example”# Configuration for syncing between internal and public repositories
# ==== Variables ====INTERNAL = "https://github.com/myorg/internal"PUBLIC = "https://github.com/myorg/public"BOT = "Sync Bot <sync@myorg.com>"
# ==== Shared Transforms ====def security_checks(): """Verify no secrets are exposed.""" return [ core.verify_match( regex = "API_KEY|SECRET|PASSWORD", verify_no_match = True, ), ]
def url_transforms(): """Replace internal URLs.""" return [ core.replace("internal.myorg.com", "api.myorg.io"), ]
# ==== Workflows ====
# Export internal code to public repositorycore.workflow( name = "export", origin = git.github_origin( url = INTERNAL, ref = "main", ), destination = git.github_pr_destination( url = PUBLIC, destination_ref = "main", pr_branch = "sync/${CONTEXT_REFERENCE}", ), origin_files = glob( include = ["src/**", "docs/**"], exclude = ["**/internal/**"], ), authoring = authoring.pass_thru(BOT), transformations = security_checks() + url_transforms() + [ core.move("src/public/", "src/"), metadata.add_header("Synced-From: internal"), ], mode = "SQUASH",)
# Import external contributionscore.workflow( name = "import", origin = git.github_pr_origin( url = PUBLIC, branch = "main", required_labels = ["ready-to-import"], ), destination = git.gerrit_destination( url = INTERNAL, fetch = "main", push_to_refs_for = "main", ), authoring = authoring.pass_thru(BOT), transformations = [ core.move("src/", "src/public/"), ], mode = "CHANGE_REQUEST_FROM_SOT",)