Advanced Use Cases
Advanced patterns for complex synchronization scenarios.
Multi-Target Sync
Section titled “Multi-Target Sync”Sync one source to multiple destinations with different configurations.
Same Content, Multiple Destinations
Section titled “Same Content, Multiple Destinations”# Sync to GitHub and GitLab simultaneouslydef make_workflow(name, dest_url): return core.workflow( name = name, origin = git.origin( url = "https://internal.corp/repo", ref = "main", ), destination = git.destination( url = dest_url, push = "main", ), origin_files = glob(["src/**", "docs/**"]), authoring = authoring.pass_thru("Bot <bot@example.com>"), transformations = [ metadata.add_header("Synced from internal"), ], )
make_workflow("to-github", "https://github.com/org/repo")make_workflow("to-gitlab", "https://gitlab.com/org/repo")Run both:
copybara migrate copy.bara.sky to-githubcopybara migrate copy.bara.sky to-gitlabDifferent Content Per Destination
Section titled “Different Content Per Destination”# Community edition vs Enterprise editioncore.workflow( name = "community", origin = git.origin(url = "https://internal/repo", ref = "main"), destination = git.destination(url = "https://github.com/org/community"), origin_files = glob( include = ["**"], exclude = ["enterprise/**", "internal/**"], ), transformations = [ core.remove(glob(["**/*_enterprise.*"])), ],)
core.workflow( name = "enterprise", origin = git.origin(url = "https://internal/repo", ref = "main"), destination = git.destination(url = "https://github.com/org/enterprise"), origin_files = glob(["**"]), # No exclusions - full content)Vendor Dependency Management
Section titled “Vendor Dependency Management”Keep vendored dependencies in sync with upstream.
Basic Vendor Sync
Section titled “Basic Vendor Sync”core.workflow( name = "vendor-protobuf", origin = git.origin( url = "https://github.com/protocolbuffers/protobuf", ref = "v3.21.0", # Pin to specific version ), destination = git.destination( url = "https://github.com/myorg/myrepo", push = "main", ), origin_files = glob(["src/**"]), destination_files = glob(["vendor/protobuf/**"]), transformations = [ core.move("src", "vendor/protobuf"), metadata.add_header("Vendor update: protobuf v3.21.0"), ],)Multi-Vendor Management
Section titled “Multi-Vendor Management”def vendor_dep(name, url, ref, src_path, include_patterns): return core.workflow( name = "vendor-" + name, origin = git.origin(url = url, ref = ref), destination = git.destination( url = "https://github.com/myorg/myrepo", ), origin_files = glob(include_patterns), destination_files = glob(["vendor/" + name + "/**"]), transformations = [ core.move(src_path, "vendor/" + name), metadata.replace_message( "Vendor " + name + " @ " + ref + "\n\n" + "Source: " + url + "\n" + "Ref: " + ref ), ], )
vendor_dep( name = "grpc", url = "https://github.com/grpc/grpc", ref = "v1.50.0", src_path = "src/core", include_patterns = ["src/core/**"],)
vendor_dep( name = "abseil", url = "https://github.com/abseil/abseil-cpp", ref = "20230125.0", src_path = "absl", include_patterns = ["absl/**"],)Vendor with Patches
Section titled “Vendor with Patches”Apply local patches after vendoring:
core.workflow( name = "vendor-with-patches", origin = git.origin( url = "https://github.com/upstream/library", ref = "v2.0.0", ), destination = git.destination( url = "https://github.com/myorg/myrepo", ), destination_files = glob(["vendor/library/**", "patches/library/**"]), transformations = [ core.move("", "vendor/library"), patch.apply(series = "patches/library/series"), ],)Gradual Rollout
Section titled “Gradual Rollout”Deploy changes progressively across environments.
Canary to Stable Pipeline
Section titled “Canary to Stable Pipeline”# Stage 1: Canary deploymentcore.workflow( name = "deploy-canary", origin = git.origin( url = "https://github.com/org/app", ref = "main", ), destination = git.destination( url = "https://github.com/org/app-deploy", push = "canary", ), transformations = [ core.replace( before = "ENVIRONMENT=production", after = "ENVIRONMENT=canary", paths = glob(["config/**"]), ), metadata.add_header("[CANARY] ${COPYBARA_CURRENT_MESSAGE}"), ],)
# Stage 2: Promote canary to stable (after validation)core.workflow( name = "promote-stable", origin = git.origin( url = "https://github.com/org/app-deploy", ref = "canary", ), destination = git.destination( url = "https://github.com/org/app-deploy", push = "stable", ), transformations = [ core.replace( before = "ENVIRONMENT=canary", after = "ENVIRONMENT=stable", paths = glob(["config/**"]), ), metadata.replace_message("[STABLE] Promoted from canary"), ],)Feature Flag Rollout
Section titled “Feature Flag Rollout”def rollout_workflow(percentage): return core.workflow( name = "rollout-" + str(percentage), origin = git.origin(url = "...", ref = "main"), destination = git.destination(url = "...", push = "deploy"), transformations = [ core.replace( before = "ROLLOUT_PERCENTAGE=\\d+", after = "ROLLOUT_PERCENTAGE=" + str(percentage), regex_groups = {}, paths = glob(["config/rollout.yaml"]), ), ], )
rollout_workflow(10) # 10% rolloutrollout_workflow(50) # 50% rolloutrollout_workflow(100) # Full rolloutCross-Organization Sync
Section titled “Cross-Organization Sync”Sync between organizations with different authentication.
GitHub to GitLab (Different Orgs)
Section titled “GitHub to GitLab (Different Orgs)”core.workflow( name = "github-to-gitlab", origin = git.origin( url = "https://github.com/org-a/repo", ref = "main", ), destination = git.destination( url = "https://gitlab.com/org-b/repo", push = "main", ), authoring = authoring.overwrite( default = "Sync Bot <sync@org-b.com>", ), transformations = [ # Map authors between organizations metadata.map_author({ "dev@org-a.com": "Dev User <dev@org-b.com>", }), # Update internal references metadata.map_references( before = "org-a/repo#${reference}", after = "org-b/repo#${reference}", regex_groups = {"before_ref": "[0-9]+"}, ), ],)Credential Setup
Section titled “Credential Setup”# Store credentials for both platformsecho "https://x-access-token:${GITHUB_TOKEN}@github.com" >> ~/.git-credentialsecho "https://oauth2:${GITLAB_TOKEN}@gitlab.com" >> ~/.git-credentialsgit config --global credential.helper storeBidirectional Cross-Org Sync
Section titled “Bidirectional Cross-Org Sync”# Shared configurationGITHUB_REPO = "https://github.com/org-a/shared"GITLAB_REPO = "https://gitlab.com/org-b/shared"
core.workflow( name = "github-to-gitlab", origin = git.origin(url = GITHUB_REPO, ref = "main"), destination = git.destination(url = GITLAB_REPO, push = "main"), authoring = authoring.pass_thru("Sync <sync@example.com>"), transformations = [ metadata.save_author("ORIGINAL_AUTHOR"), ],)
core.workflow( name = "gitlab-to-github", origin = git.origin(url = GITLAB_REPO, ref = "main"), destination = git.destination(url = GITHUB_REPO, push = "main"), authoring = authoring.pass_thru("Sync <sync@example.com>"), transformations = [ metadata.restore_author("ORIGINAL_AUTHOR"), ],)Fork Management
Section titled “Fork Management”Keep forks synchronized with upstream while preserving local changes.
core.workflow( name = "sync-upstream", origin = git.origin( url = "https://github.com/upstream/project", ref = "main", ), destination = git.destination( url = "https://github.com/myorg/project-fork", push = "upstream-sync", ), destination_files = glob( include = ["**"], exclude = ["local/**", ".github/workflows/**"], ), transformations = [ metadata.add_header("Upstream sync: ${COPYBARA_REVISION}"), ],)Then merge upstream-sync into your main branch manually or via PR.
Next Steps
Section titled “Next Steps”- Mirroring repos - Simple mirroring
- Monorepo extraction - Split large repos
- State management - Handle sync state