GitSync

Synchronize ProcessWire modules with GitHub repository branches

ProcessWire module that synchronizes installed modules with GitHub repository branches directly from the admin panel. Pull the latest code onto a test server without manual FTP uploads after every commit.

GitSync Overview

Features


  • Differential sync – Compares git blob SHAs to detect changes, only downloads modified files
  • Branch-level control – List all branches, sync any of them with one click
  • GitHub Webhook support – Automatic sync on every push, no browser tab required
  • Auto-check on admin login – For repos without a webhook, optionally notify or auto-sync when a new commit is detected upstream
  • Install from GitHub – Install new modules directly from a GitHub URL (public and private repos)
  • No git required – Uses the GitHub REST API exclusively, no git binary needed on the server
  • Update detection – Shows whether the synced branch is up to date or has new commits
  • Private repo support – Authenticate with a fine-grained GitHub Personal Access Token
  • Sync log – All operations are logged via ProcessWire's built-in log system
  • Permission-based access – Dedicated gitsync permission for role-based access control

Requirements


  • ProcessWire >= 3.0
  • PHP >= 8.0
  • PHP cURL extension
  • PHP ZipArchive extension (used by Install from GitHub — ProcessWire core requires it as well)

Installation


  1. Copy the module files into site/modules/GitSync/
  2. In the ProcessWire admin go to Modules > Refresh
  3. Install the GitSync module
  4. The module appears under Setup > GitSync

Go to Modules > Configure > GitSync and enter a GitHub Personal Access Token.

Without tokenWith token
Public reposyesyes
Private reposnoyes
API rate limit60 requests/hour5,000 requests/hour

Create a fine-grained token at GitHub > Settings > Developer settings > Personal access tokens with read-only access to Contents for the repositories you need.

Important: Under "Repository access", make sure all repositories you want to sync are included. If you select "All repositories", verify in the token settings that no leftover selection is limiting access.

GitHub Webhook (optional)

Set up a webhook to automatically sync modules whenever you push to GitHub.

  1. On the GitSync overview page, click Webhook Credentials to get the Payload URL and Secret
  2. In your GitHub repository go to Settings > Webhooks > Add webhook
  3. Payload URL: paste the URL from the modal
  4. Content type: application/json
  5. Secret: paste the secret from the modal
  6. Events: select "Just the push event"
  7. Click Add webhook

If no webhook secret is configured yet, the modal links you directly to the module settings.

Repeat steps 2–7 for each GitHub repository you want to auto-sync. Use the same secret and URL for all of them.

The webhook only triggers a sync for modules that have an actively tracked branch matching the pushed branch. If you push to main but a module tracks develop, nothing happens.

Usage


Click Link Module on the GitSync overview page. Select a module from the dropdown – GitSync automatically searches GitHub for a matching repository. You can also enter a repository URL manually.

Link Module

Install a new module from GitHub

On the same page, expand Install new module from GitHub and paste the repository URL. GitSync downloads the module's default branch as a single ZIP archive (one HTTPS request, regardless of file count), extracts it into site/modules/, installs it in ProcessWire, and links it automatically. Subsequent Sync operations on the linked module then use the differential sync described below.

Link Module

Browse branches

Click Branches next to a linked module to see all available branches with their latest commit SHA and date. The status badge shows up to date or updates available for the active branch.

Branch List

Auto-Sync on admin login

For repos you don't own (and therefore can't add a webhook to), GitSync can check for upstream updates automatically on the first admin page load per session.

Each linked module has an Auto-Sync column in the overview with three modes:

  • off (default) – manual sync only
  • notify – check for new commits and show a warning notice with a link to the branches view
  • auto-sync – check and sync immediately without confirmation

Update available

When an update is detected, an orange update available badge stays on the GitSync overview next to the affected module, even after the notice is dismissed.

Notes:

  • The check runs once per session, not on every page load.
  • Mappings with an active webhook are skipped (the webhook handles it).
  • GitSync itself is excluded from auto-sync – self-updates remain manual to avoid mid-request fatal errors.
  • Without a GitHub token you have 60 API requests/hour total. Use auto-sync sparingly when linking many public repos, or configure a token to raise the limit to 5,000/hour.

Sync a branch

Click Sync next to any branch. GitSync performs a differential sync:

  1. Fetches the remote file tree via GitHub's Git Trees API (single request)
  2. Computes the git blob SHA (sha1("blob {size}\0{content}")) for each local file
  3. Compares SHAs – identical files are skipped
  4. Downloads only new or modified files via the Git Blobs API
  5. Deletes local files that no longer exist in the remote branch
  6. Cleans up empty directories
  7. Refreshes the ProcessWire module cache

The admin shows a summary: how many files were updated and deleted.

How Differential Sync Works


Git identifies file contents by their blob SHA – a hash computed as sha1("blob {filesize}\0{content}"). GitHub's Trees API returns this SHA for every file in a branch. GitSync computes the same hash locally. If the hashes match, the file is identical and doesn't need to be downloaded.

This means:

  • Minimal data transfer – only changed files are downloaded
  • No temp files – no zip archives or extraction needed
  • Non-destructive – unchanged files keep their timestamps
  • Accurate – uses the same content-addressing as git itself

File Structure


GitSync/
├── GitSync.module.php     Main Process module (admin UI + sync logic)
├── GitSyncAdd.js          JavaScript for the Link Module page
├── GitSyncConfig.php      Module configuration (token, webhook secret)
├── GitSyncGitHub.php      GitHub REST API client
├── LICENSE
└── README.md

Security


  • Token storage: Stored in ProcessWire's module config (database), protected by admin authentication and the gitsync permission. Use fine-grained tokens with minimal scope.
  • Webhook verification: HMAC-SHA256 signature verification (X-Hub-Signature-256). Missing or invalid signatures are rejected with HTTP 403.
  • CSRF protection: All state-changing admin operations validate ProcessWire's CSRF token.
  • Path validation: Remote file paths are checked for path traversal (..) before writing.
  • Access control: Dedicated gitsync permission. The webhook endpoint bypasses admin auth but requires a valid HMAC signature.

Limitations


  • Very large repositories (100k+ files where GitHub truncates the tree response) are not supported for differential sync.
  • Files matching the repository's root .gitignore (runtime artefacts like logs/, dumps/, bluescreen/) or marked export-ignore in .gitattributes (typically docs/, .github/, the .gitattributes file itself — i.e. files the maintainer excludes from git archive) are never added, never deleted: GitSync treats them as not part of the deployable surface. Local files outside both lists that no longer exist remotely are deleted on sync. The pattern matcher covers directory patterns, wildcards, and literal names — not the full gitignore spec (no negation, no **).
  • Small diffs use one API request per changed file. Diffs larger than 50 files automatically switch to a single ZIP archive download via GitHub's /zipball endpoint, which keeps large syncs fast and avoids the API rate limit for downloads.
  • Self-updating (syncing GitSync itself) works but may require a page reload.

License


MIT License – see LICENSE for details.

More modules by Mikel

  • ProcessDataTables

    Displays customizable backend tables for any ProcessWire template with flexible column selection, per-field output templates, and global formatting options.
  • StripePaymentLinks

    Stripe payment-link redirects, user/purchases, magic link, mails, modals.
  • User Data Table

    Displays a configurable table of user fields in the admin interface.
  • Textformatter Smart Quotes

    Replaces straight quotes "..." with typographic quotes („...“, “...”, or «...»), in visible text only.
  • Data Migrator

    Migrate external data (SQL, CSV, JSON, XML) into ProcessWire
  • StripePaymentLinks Mailchimp Sync

    Sync purchases from StripePaymentLinks to Mailchimp
  • Stripe Payment Links Admin

    View customer, purchases & products with configurable metadata columns & filters. Export reports to CSV.
  • StripePaymentLinks Customer Portal

    Adds a ready-to-use /account/ page with login flow, product grid, purchase history table, and direct access to the Stripe Customer Billing Portal
  • GitSync

    Synchronize ProcessWire modules with GitHub repository branches

All modules by Mikel

Install and use modules at your own risk. Always have a site and database backup before installing new modules.