git
A Buildkite plugin for cross-repo automation with reusable primitives:
- optional artifact download into the source workspace
- source command execution (generation/build steps)
- cloning a target repo + branch handling + git identity/auth
- file/dir sync and generic YAML subtree merge (
merge-yaml) - commit/push and PR create/update via
gh - templated Slack notifications via webhook
Examples
steps:
- label: ":yaml: generate and sync config"
command: task config:ci # generate local config artifacts first
plugins:
- theopenlane/git#v0.1.4:
execute-phase: post-command # run after step command completes
repository: git@github.com:theopenlane/openlane-infra.git # target repo to open PR against
branch: "update-helm-config-${BUILDKITE_BUILD_NUMBER}" # explicit target branch
preset: helm-sync # enables merge-yaml defaults + chart path defaults
chart-name: openlane # default target-root becomes charts/openlane
base-merge-target-path: .openlane.coreConfiguration # reused merge destination key
base-merge-source-path: .openlane.coreConfiguration // .coreConfiguration # fallback source expression
user:
name: theopenlane-bender
email: bender@theopenlane.io
sync:
- from: helm-values.yaml
to: values.yaml # maps to charts/openlane/values.yaml via preset
- from: helm-values.yaml
to: values.yaml
merge-target-suffix: .externalSecrets # appends to base merge target path
required: false # skip if source subtree doesn't exist
merge-delete-paths:
- .externalSecrets # remove top-level copy after nesting under coreConfiguration
- from: configmap-config-file.yaml
to: templates/core-configmap-file.yaml
type: file
- from: external-secrets
to: templates/external-secrets
type: dir # directory sync mode
delete: true # mirror source directory (remove stale dest files)
target-run:
- |
# run target repo maintenance after sync
task docs
yq e '.openlane' values.yaml | sed -n '1,40p'
commit-message: "chore: update Helm config from core build #{{BUILD_NUMBER}}" # templated commit message
pr:
enabled: true
title: "π€ Update Helm chart from core config (Build #{{BUILD_NUMBER}})"
body-file: templates/github/helm-update-pr.md
comment-on-source-pr: true
source-comment: |
## π§ Configuration Changes Detected
Automated infra PR: {{TARGET_PR_URL}}
slack:
enabled: true
webhook-env: SLACK_WEBHOOK_URL
template-file: templates/slack/helm-update-notification.json
steps:
- label: ":graphql: sync generated files to go-client"
command: task graphql:generate # generate artifacts in source repo
plugins:
- theopenlane/git#v0.1.4:
repository: git@github.com:theopenlane/go-client.git # downstream repo
branch-prefix: sync-go-client
source-run:
- task graphql:generate # optional re-run before copy
sync:
- from: internal/graphql/generated
to: graphql
type: dir
delete: true # keep target graphql dir in exact sync
target-run:
- |
# post-sync generation in target repo
go generate ./...
gofmt -w .
- "git status --short | sed -n '1,80p'" # inline shell pipeline is supported
commit-message: "chore: sync graphql artifacts from core #{{BUILD_NUMBER}}"
pr:
title: "Sync GraphQL artifacts from core (Build #{{BUILD_NUMBER}})"
steps:
- label: ":book: sync schemas to docs repo and regenerate"
command: task graphql:schema:export # export schema/assets from source repo
plugins:
- theopenlane/git#v0.1.4:
repository: git@github.com:theopenlane/docs.git # docs repo target
branch-prefix: sync-docs
sync:
- from: docs/graphql/schema.graphql
to: content/reference/schema.graphql
type: file
- from: docs/graphql/examples
to: content/reference/examples
type: dir
delete: true # remove docs examples no longer present in source
target-run:
- |
# regenerate docs in target repo
npm ci
npm run docs:generate
commit-message: "docs: refresh graphql schema and examples (#{{BUILD_NUMBER}})"
pr:
title: "Docs refresh from core GraphQL schema (Build #{{BUILD_NUMBER}})"
Hook Behavior
environment: sets plugin defaultspre-command: validates configuration and required dependenciescommand: runs workflow whenexecute-phase: commandpost-command: runs workflow whenexecute-phase: post-command(default)
Use post-command for generate-then-sync pipelines.
Configuration
enabled (optional, default true)
Enable/disable plugin execution.
execute-phase (optional, default post-command)
One of command or post-command.
skip-on-command-failure (optional, default true)
Only applies to post-command. Skips automation when step command failed.
repository (required)
Target repository URL or slug.
base-branch (optional, default main)
Base branch used when creating a new working branch.
preset (optional, default custom)
custom or helm-sync.
helm-sync defaults:
sync.typetomerge-yamlwhen omittedsource-roottoconfigtarget-roottocharts/<chart-name>whenchart-nameis set, otherwisecharts
chart-name (optional)
Used by preset: helm-sync to derive default target-root.
source-root / target-root (optional)
Prefix applied to relative sync.from / sync.to values.
base-merge-target-path (optional)
Default merge target key for merge-yaml entries.
base-merge-source-path (optional)
Default merge source expression for merge-yaml entries.
branch (optional)
Explicit branch name. If unset, branch is generated from branch-prefix/branch-suffix.
branch-prefix / branch-suffix (optional)
Used to construct dynamic branch names.
user.name / user.email (optional)
Git identity for commits.
auth.mode (optional, default ssh)
ssh or https-token.
auth.token-env (optional, default GITHUB_TOKEN)
Token env var used when auth.mode: https-token.
auth.token-user (optional, default x-access-token)
Username part for HTTPS token auth.
artifact-download (optional)
Download Buildkite artifacts into source workspace before sync.
pattern(required)destination(optional, default.)step(optional)
source-directory (optional)
Base directory for relative sync.from paths.
run / source-run (optional)
Commands executed in source workspace.
target-run (optional)
Commands executed in cloned target repository via bash -lc.
Pipes, redirects, and multiline commands are supported (use YAML block scalars).
sync (optional)
List of sync operations.
-
Common fields:
-
from(optional formerge-yamlwhenmerge-source-envis set) -
to(required unless same asfrom) -
required(optional, defaulttrue) -
type: auto | file | dir | merge-yaml -
For
dir: -
delete(optional, defaultfalse) -
When
true, destination contents are made to match source (stale files are removed). -
For
merge-yaml: -
merge-target-path(required unlessbase-merge-target-pathresolves it) -
merge-target-suffix(optional; appended tobase-merge-target-path) -
merge-source-path(optional, default.) -
merge-source-env(optional) -
merge-delete-paths(optional list of YAML paths to delete after merge)
add (optional)
Explicit pathspecs for git add -A. Defaults to all changes.
commit-message (optional)
Commit message template.
commit-signoff / commit-gpg-sign (optional)
Enable --signoff and/or --gpg-sign on commit.
push-force-with-lease (optional, default false)
Push with --force-with-lease.
fail-on-no-changes (optional, default false)
Fail build when no staged changes were detected.
pr.* (optional)
PR settings (enabled, repo, base, title, body, body-file, draft, update-existing, labels, reviewers, assignees, source PR linking options).
slack.* (optional)
Slack settings (enabled, webhook-env, template-file, template-inline, notify-on-no-changes, fail-on-error).
template-vars / pr.vars / slack.vars (optional)
Custom template vars exposed as env-expanded placeholders.
Templates
This plugin ships reusable templates copied from your existing automation flow:
templates/github/*.mdtemplates/slack/*.json
Default fallbacks:
- PR body:
templates/github/default-pr.md - Slack payload:
templates/slack/default-notification.json
Template Variables
Built-ins include:
{{BUILD_ID}},{{BUILD_NUMBER}},{{BUILD_URL}},{{PIPELINE_NAME}},{{PIPELINE_SLUG}},{{BUILD_CREATOR}}{{SOURCE_REPO_URL}},{{SOURCE_REPO}},{{SOURCE_BRANCH}},{{SOURCE_COMMIT}},{{SOURCE_COMMIT_SHORT}},{{SOURCE_PR_NUMBER}}{{TARGET_REPOSITORY}},{{TARGET_REPO}},{{TARGET_BASE_BRANCH}},{{TARGET_BRANCH}},{{TARGET_PR_URL}}{{CHANGED_FILES}},{{CHANGE_SUMMARY}}
Developing
task ci
or
./scripts/test