A GitHub Action that copies a selected set of files from one source branch to all other branches in the repository. Useful for keeping shared, repo-wide files (license, contribution docs, editor/CI config) consistent across every branch without manual cherry-picking.
Unless otherwise specified, these files and folders are copied:
LICENSE
NOTICE
README.md
CONTRIBUTING.md
.vscode/
.devcontainer/
.github/
Reference the published action by its owner/repo@ref in any repository. Pass
values to each input through the with: block. To let whoever triggers the run
type values (e.g. which files to copy) from the Actions tab, declare
workflow_dispatch inputs and forward them with ${{ inputs.* }}:
# .github/workflows/sync-shared-files.yaml (in YOUR repo)
name: Sync shared files
on:
workflow_dispatch:
inputs:
source-branch:
description: "Source branch to copy files from (blank = default branch)"
required: false
default: ""
files:
description: "Comma or newline separated list of files/dirs/globs to copy (blank = default list)"
required: false
default: ""
permissions:
contents: write # required for push mode
pull-requests: write # required for pr mode
jobs:
sync:
runs-on: ubuntu-latest
steps:
- uses: LinkedInLearning/lil-update-branches@v1.0.1
with:
source-branch: ${{ inputs.source-branch }}
files: ${{ inputs.files }}Notes for cross-repo use:
- No checkout needed. When you reference a published action by
owner/repo@ref, GitHub fetches it automatically - you do not need anactions/checkoutstep (that's only required when using the local./form inside this action's own repo). - Pin a ref. Use a tag (
@v1), branch, or commit SHA. A SHA is the most secure (@<full-sha>). - Omit an input to use its default. Leaving
filesblank falls back to the built-in default list. - Hardcode instead of prompting by skipping the
workflow_dispatchinputs and setting values directly, e.g.files: |followed by your selectors.
name: Sync shared files
on:
workflow_dispatch:
# Optional: run on a schedule
# schedule:
# - cron: "0 6 * * 1" # every Monday 06:00 UTC
permissions:
contents: write # required for push mode
pull-requests: write # required for pr mode
jobs:
sync:
runs-on: ubuntu-latest
steps:
- uses: LinkedInLearning/lil-update-branches@v1.0.1
with:
# All inputs are optional; defaults shown below.
source-branch: "" # default: repository default branch
files: "" # default: see "Default file list"
include-branches: "*"
exclude-branches: ""
mode: push # or "pr"
dry-run: "false" - uses: LinkedInLearning/lil-update-branches@v1.0.1
with:
mode: prIn pr mode the action maintains a stable head branch
sync-shared-files/<target-branch> per target and reuses/updates an existing
open PR on re-runs instead of opening duplicates.
- uses: LinkedInLearning/lil-update-branches@v1.0.1
with:
dry-run: "true"| Input | Required | Default | Description |
|---|---|---|---|
source-branch |
no | repo default branch | Branch to copy files from. |
files |
no | (default list below) | Newline/comma-separated paths, directory prefixes, and/or globs to copy. |
include-branches |
no | * |
Glob(s) of target branches to include. |
exclude-branches |
no | (none) | Glob(s) of target branches to exclude. The source branch is always excluded. |
mode |
no | push |
push = commit directly to each branch. pr = open a pull request per branch. |
dry-run |
no | false |
Compute and report planned changes without writing. |
commit-message |
no | chore: sync shared files from {source-branch} |
Commit message. {source-branch} is substituted. |
pr-title |
no | chore: sync shared files from {source-branch} |
PR title (pr mode). {source-branch} is substituted. |
token |
no | ${{ github.token }} |
Token used for API/Git operations. Override for cross-repo or elevated permissions. |
Each entry in files may be:
- an exact path - e.g.
LICENSE - a directory prefix - e.g.
.github/orsrc(copies everything under it, recursively) - a glob - e.g.
**/*.md,*.yml
Example:
with:
files: |
LICENSE
.github/
docs/**/*.md| Output | Description |
|---|---|
updated-branches |
JSON array of branches that received changes. |
skipped-branches |
JSON array of { branch, reason } for skipped/failed branches. |
summary |
Human-readable summary (also written to the job step summary). |
mode: pushrequirescontents: write.mode: prrequirescontents: writeandpull-requests: write.
Branch protection rules may block direct pushes; in that case the affected
branches are reported under skipped-branches and the run still succeeds. Use
mode: pr for protected branches.
npm ci # install
npm test # run unit tests (Jest)
npm run lint # eslint
npm run build # type-check + bundle dist/
npm run all # lint + type-check + test + bundleThe committed dist/ bundle is what the runtime executes - always run
npm run all and commit dist/ after changing src/.