Skip to content

FasterApiWeb/fork-shepherd

Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Fork Shepherd

Fork Shepherd logo

All-in-one GitHub Action to keep your fork in sync with upstream
Branch sync · PR monitoring · Backporting · Conflict cleanup

GitHub Marketplace Release CI License

Stars Forks Watchers Issues Pull requests Commit activity Last commit

Pin to a major version (@v1) for automatic non-breaking updates, or to an exact tag (@v1.1.0) for full reproducibility.

Marketplace: github.com/marketplace/actions/fork-shepherd
Source: github.com/FasterApiWeb/fork-shepherd
Insights / traffic: Repository insights (maintainers)


Table of contents

Features

Feature What it does
Branch sync Fast-forward or merge upstream into your fork branches; open conflict issues when needed
PR monitor Keep labeled PRs up to date with their base branch; detect upstream reverts
Backport Cherry-pick merged PRs onto release branches via labels
Cleanup Auto-close resolved sync-conflict issues

Installation

1. Create a PAT for your fork

Fork Shepherd needs a token that can push branches and manage issues/PRs on your fork.

Fine-grained PAT (recommended for one fork):

  1. Open Fine-grained tokens
  2. Generate new token → select your fork repository
  3. Permissions:
    • Contents: Read and write
    • Issues: Read and write
    • Pull requests: Read and write
  4. Generate and copy the token

Classic PAT: enable repo (add workflow only if you sync branches that contain workflow files).

If the org uses SAML SSO, authorize the token for that organization.

2. Add the secret on your fork

On your fork: Settings → Secrets and variables → Actions → New repository secret

Name Value
FORK_SYNC_PAT The PAT from step 1

3. Add a workflow file

Create .github/workflows/fork-shepherd.yml on your fork (see Usage).

4. (Optional) Labels

With monitor_all_prs: "true" you do not need sync-bot for auto-updates.

Label Used for
sync-bot Only if monitor_all_prs is false (opt-in monitoring)
sync-conflict Conflict issues (default conflict_label)
backport-to-<branch> e.g. backport-to-release-1.0

Usage

What runs when

Goal How it works
Keep fork branches synced with upstream schedule (e.g. hourly) — GitHub cannot notify your fork when upstream moves
Auto-update a PR into main when main advances push to main → merges/rebases main into that PR’s head
Same for master / develop push to those branches → only PRs with that base are updated
Conflicts Bot comments with fix steps; no force-push — you resolve manually

With monitor_all_prs: "true", every open PR is kept current for its own base (main, master, develop, …). No sync-bot label and no “Update branch” button unless there is a conflict.

Recommended workflow (fork sync + auto PR updates)

Create .github/workflows/fork-shepherd.yml on your fork:

name: Fork Shepherd

on:
  schedule:
    - cron: "0 * * * *"   # hourly upstream sync
  workflow_dispatch:
  push:
    branches: [main, master, develop]
  pull_request_target:
    types: [opened, labeled, closed]

jobs:
  shepherd:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
          token: ${{ secrets.FORK_SYNC_PAT }}

      - uses: FasterApiWeb/fork-shepherd@v1
        with:
          upstream_repo: "original-owner/original-repo"
          sync_branches: "main,master,develop"
          github_token: ${{ secrets.FORK_SYNC_PAT }}
          monitor_all_prs: "true"

Replace original-owner/original-repo with the upstream you forked from. Adjust sync_branches / push.branches to match your repo.

Minimal — sync main on a schedule only

name: Sync Fork

on:
  schedule:
    - cron: "0 */6 * * *"
  workflow_dispatch:

jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
          token: ${{ secrets.FORK_SYNC_PAT }}

      - uses: FasterApiWeb/fork-shepherd@v1
        with:
          upstream_repo: "original-owner/original-repo"
          sync_branches: "main"
          github_token: ${{ secrets.FORK_SYNC_PAT }}

Day-to-day

Goal What to do
Auto-update all PRs monitor_all_prs: "true" (recommended)
Opt-in per PR only monitor_all_prs: "false" and add label sync-bot
Backport a merged PR Add label backport-to-release-1.0 (branch must exist)
Run manually Actions → Run workflow
Preview without writes dry_run: "true"

Version pinning

# Recommended — gets non-breaking updates
- uses: FasterApiWeb/fork-shepherd@v1

# Exact — fully reproducible
- uses: FasterApiWeb/fork-shepherd@v1.1.0

More examples: examples/full.yml, examples/basic.yml, examples/pr-only.yml.


Configuration

Inputs

Input Required Default Description
upstream_repo Yes Upstream repo in owner/repo format
sync_branches Yes main Comma-separated branches to sync
github_token Yes PAT with access to your fork (and read on upstream)
pr_label No sync-bot Label for PR monitoring when monitor_all_prs is false
monitor_all_prs No false Monitor every open PR for its own base (main/master/develop/…)
backport_prefix No backport-to- Label prefix for backport targets
enable_branch_sync No true Toggle branch sync
enable_pr_monitor No true Toggle PR monitoring
enable_backport No true Toggle backport
enable_cleanup No true Toggle cleanup
dry_run No false Log without making changes
conflict_label No sync-conflict Label for conflict issues
bot_name No sync-bot Name shown in bot comments
merge_strategy No merge PR update strategy: merge or rebase

Outputs

Output Description
synced_branches Comma-separated list of successfully synced branches
conflict_branches Comma-separated list of branches with conflicts
monitored_prs Comma-separated list of monitored PR numbers
backported_prs Comma-separated list of backported PR numbers
closed_issues Comma-separated list of auto-closed issue numbers

Example workflows

Basic — branch sync only

name: Sync Fork
on:
  schedule:
    - cron: "0 */6 * * *"
  workflow_dispatch:

jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
          token: ${{ secrets.FORK_SYNC_PAT }}

      - uses: FasterApiWeb/fork-shepherd@v1
        with:
          upstream_repo: "upstream-owner/upstream-repo"
          sync_branches: "main"
          github_token: ${{ secrets.FORK_SYNC_PAT }}
          enable_pr_monitor: "false"
          enable_backport: "false"

PR monitoring only

name: PR Monitor
on:
  schedule:
    - cron: "0 */4 * * *"
  pull_request_target:
    types: [labeled]

jobs:
  monitor:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
          token: ${{ secrets.FORK_SYNC_PAT }}

      - uses: FasterApiWeb/fork-shepherd@v1
        with:
          upstream_repo: "upstream-owner/upstream-repo"
          github_token: ${{ secrets.FORK_SYNC_PAT }}
          enable_branch_sync: "false"
          enable_backport: "false"
          enable_cleanup: "false"

How it works

Branch sync

Fetches from upstream and updates each configured branch in your fork. Tries fast-forward first, then a regular merge. On conflict, opens an issue with the sync-conflict label and resolution steps. Branches that exist upstream but not in your fork are created automatically.

PR monitor

Finds open PRs with the configured label and merges (or rebases) the latest base into each PR branch. Comments with success or conflict instructions. Also warns if upstream contains reverts of commits present in the PR.

Backport

When a PR is merged with a label like backport-to-release-1.0, cherry-picks the merge commit onto release-1.0 and opens a backport PR. On conflict, comments on the original PR with manual steps.

Cleanup

Closes open sync-conflict issues once the named branch is in sync again (upstream is an ancestor of the fork branch).


Permissions

Scope / permission Why
repo (classic) or Contents/Issues/PRs write (fine-grained) Push branches, open PRs, manage issues
workflow (classic, optional) Only if synced branches include workflow files

Use the same secret for actions/checkout (token:) and this action (github_token:).


FAQ

Why not GITHUB_TOKEN?

GITHUB_TOKEN cannot reliably push the updates this action needs across fork workflows. A PAT (or fine-grained token) on the fork is required.

Can I use private repos?

Yes. The token needs read access to upstream and read/write on your fork.

What if upstream force-pushes?

The action merges; it never force-pushes your fork. Conflicts open a sync-conflict issue for manual resolution.

How do I stop monitoring a PR?

Remove the sync-bot label (or your custom pr_label).


Contributing

See CONTRIBUTING.md. CI runs shellcheck, validates action.yml, and scans with leash-secrets.

Releasing

Maintainers: see release steps in CONTRIBUTING.md. Summary:

  1. Actions → Release → Run workflow (pick branch + semver bump)
  2. Edit the draft release → check Publish this Action to the GitHub MarketplacePublish release

Drafts are not Marketplace-listed until published in the UI.

Security

See SECURITY.md.

License

MIT

About

All-in-one GitHub Action for fork sync, PR monitoring, backporting, and conflict cleanup

Topics

Resources

License

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages