doc-site
Developer guide

Branches and theme sync

How theme editor edits get back into git, and how to avoid overwriting a merchandiser's work.

Branches and theme sync

Two systems write to this theme. Developers write code through git. Merchandisers write settings through the Shopify theme editor, straight to the live theme, with no branch and no review.

A GitHub Action keeps the second set of changes from being lost.

Branches

BranchRole
mainDefault branch. Pull requests target it
productionReceives automated pulls from the live Shopify theme
main-v6.7.xRelease branches, named for the version in package.json
Numbered feature branchesOne per ticket, for example 4-ba-115-fx-auhk-update-gift-cards-page

Feature branches follow <issue-number>-<ticket>-<short-description>, which ties a branch to its GitHub issue and its ProWorkflow job.

What the theme-pull workflow does

.github/workflows/theme-pull.yml runs on four triggers: a repository_dispatch with the theme_update event type, a manual run, a daily schedule at midnight UTC, and a push to master.

When it runs it:

  1. Verifies client_payload.repo matches this repository, so one webhook proxy can serve several stores without crossing them.
  2. Checks required configuration is present and fails with a clear message when it is not.
  3. Checks out production, creating it if it does not exist.
  4. Installs the Shopify CLI.
  5. Runs shopify theme pull against the live theme.
  6. Commits any changes as chore: pull theme from shopify on theme update and pushes to production.

The workflow reads this configuration.

NameKindValue
SHOPIFY_CLI_THEME_TOKENSecretA Theme Access token for the store
SHOPIFY_FLAG_STOREVariableThe myshopify domain
SHOPIFY_FLAG_LIVEVariableMust be true, which makes the pull target the live theme

The workflow writes to production and nowhere else. Nothing merges it into main automatically.

What a pull changes

A pull almost always changes these three.

config/settings_data.json, which holds every theme setting's saved value.

templates/*.json, which hold each page's section layout and per-section settings.

sections/*.json section groups, when a merchandiser edits a header or footer group.

Occasionally an app writes a snippet back. Discount Ninja and Boost both do this, which is why several of their files are listed in .prettierignore.

The rule

Merge production into your branch before you push a theme deployment.

git fetch origin
git merge origin/production

Skipping this overwrites every theme editor change made since your branch diverged. The failure is quiet. Nothing errors, and the first sign is a merchandiser asking why their homepage reverted.

The recent history of this repository shows the pattern in use. Commit 98126f4 is a merge of production into a feature branch before a release.

Resolving a conflict in a settings file

Conflicts in config/settings_data.json and templates/*.json are common. Shopify writes these files, so resolving them rarely needs a line-by-line merge.

Take the production side for any hunk you did not deliberately change. It holds what the live store currently has, which is what merchandisers expect to keep.

Take your side only for settings your change introduced, such as a new key you added to settings_schema.json.

When a conflict is large or the file will not parse afterwards, take production wholesale and reapply your setting through the theme editor after deploying:

git checkout --theirs config/settings_data.json
git add config/settings_data.json

Verify the result parses before committing:

python3 -m json.tool config/settings_data.json > /dev/null

Why theme editor sync is on during development

shopify.theme.toml sets theme-editor-sync = true for both environments, so shopify theme dev pulls theme editor changes into your working copy while it runs.

That means git status can show changes to config/settings_data.json and templates/*.json that you did not make. Review them. Committing them is sometimes right, when you want your branch to carry the current live settings, and sometimes wrong, when it drags an unrelated in-progress merchandiser edit into your pull request.

reconciliation-strategy = "keep-local" means your local copy wins when both sides changed the same file. It protects your work and discards theirs locally. The canonical copy is still on the store, so nothing is permanently lost, but do not treat your local settings file as authoritative.

Setting the sync up on a new store

The README has the full setup. In short:

  1. Create and push a production branch.
  2. In GitHub, under Settings, Actions, General, Workflow permissions, select Read and write permissions.
  3. Add the SHOPIFY_CLI_THEME_TOKEN secret, generated through the Shopify Theme Access app.
  4. Add the SHOPIFY_FLAG_STORE and SHOPIFY_FLAG_LIVE variables.
  5. Wire a Shopify themes/update webhook to a repository_dispatch call through a small proxy, so every theme editor save triggers a pull.

If production is a protected branch, the default GITHUB_TOKEN cannot push to it. Either allow github-actions[bot] past the protection, or swap in a personal access token or deploy key.

Source map

ConcernFile
Theme pull workflow.github/workflows/theme-pull.yml
Store and environment configurationshopify.theme.toml
Files excluded from theme pushes.shopifyignore
Files excluded from Prettier.prettierignore

On this page