Proof documentation

Bring your theme, your build, and a preview store. Proof connects them through GitHub Actions.

On this page

Getting started

Pre-release software. The Action is not published on Marketplace yet. Store-backed end-to-end validation is still required. Use a dedicated development store for experiments, not a production store.

Proof builds pull request code in one job, then deploys the resulting theme files in a separate job. The deployment updates a PR comment with storefront and Theme Editor links.

You will need a Shopify theme in a GitHub repository, GitHub Actions enabled, and permission to manage repository environments. Your GitHub plan must support environments for the repository’s visibility.

  1. Create a Theme Access credential and save it in GitHub.
  2. Add the reusable workflow to your repository.
  3. Configure a build, or skip this step for a theme at the repository root that needs no build.

Connect Theme Access

Use a dedicated password from Shopify’s free Theme Access app. This is not your Shopify login password or the storefront password.

  1. Install Theme Access on your preview store.
  2. Select Create theme password and enter the recipient’s details. Use a dedicated credential for Proof.
  3. Open the emailed link and copy the password. It can only be viewed once; the link expires after seven days or after viewing.
  4. In your GitHub repository, open Settings → Environments → New environment. Name it theme-preview.
  5. Add the following secret and variable to that environment.
Environment: theme-preview
Name Type Value
SHOPIFY_CLI_THEME_TOKEN Secret Your Theme Access password
SHOPIFY_FLAG_STORE Variable example.myshopify.com

The store domain is not sensitive. The password is. Never put it in your repository, configuration file, or workflow YAML. Theme Access can modify store themes; treat it as a privileged credential.

Prefer the GitHub CLI?

After creating the environment, run these commands from your theme repository. The first command prompts for the secret instead of putting it in your shell history.

Terminal
gh secret set --env theme-preview SHOPIFY_CLI_THEME_TOKEN
gh variable set --env theme-preview SHOPIFY_FLAG_STORE --body example.myshopify.com

Only deployment and cleanup jobs use this environment. You do not need to forward secrets in the caller workflow or use secrets: inherit. Required reviewers can add an approval step to both deployment and cleanup.

To revoke access, delete the password in Theme Access. To rotate it, create a new password and replace the GitHub environment secret. See Shopify’s Theme Access guide.

Add the GitHub workflow

Create .github/workflows/theme-proof.yml in your theme repository. The reusable workflow supplies the separate build, deploy, and cleanup jobs.

This experimental example uses @main, which can change. There is no v1 release yet. Internal Action references are pinned to a reviewed bundle commit. Pin this caller to a reviewed commit SHA when validating a release candidate. Do not treat this example as a production release.

.github/workflows/theme-proof.yml
name: Theme Proof

on:
  pull_request:
    types: [opened, synchronize, reopened, closed]

permissions:
  contents: read
  pull-requests: write

jobs:
  preview:
    if: github.event.pull_request.head.repo.full_name == github.repository
    uses: BillyNoyes/Proof/.github/workflows/preview.yml@main
    with:
      config: theme-proof.config.json
      environment: theme-preview

The condition skips fork pull requests. Keep it in place. Do not replace pull_request with pull_request_target to obtain secrets for untrusted code.

Reusable workflow inputs
Input Default Purpose
config theme-proof.config.json Build config path, relative to the repository root
environment theme-preview GitHub environment holding the credential
target-mode development-context The only supported target mode
shopify-cli-version 4.8.0 Pinned CLI version for deployment and cleanup

The workflow currently uses Node.js 24 on Ubuntu. pull-requests: write is needed to create and update the preview comment.

Configure your build

Add theme-proof.config.json to your repository. It is static JSON, not executable configuration. Optional setup, install, and build commands run in that order.

No build, including Dawn

If the theme is at the repository root and needs no build, no config file is required. The explicit equivalent is:

theme-proof.config.json · No build
{
  "version": 1,
  "build": {
    "themeDirectory": "."
  }
}

A theme with a build step

Specify your package manager and commands. Proof does not need to know whether you use Easel, Vite, or another tool. Point themeDirectory at the complete deployable theme, not just a folder of compiled assets.

theme-proof.config.json · Custom build
{
  "$schema": "https://raw.githubusercontent.com/BillyNoyes/Proof/main/schema/theme-proof.schema.json",
  "version": 1,
  "build": {
    "workingDirectory": ".",
    "setup": "npm install --global pnpm@10.28.0",
    "install": "pnpm install --frozen-lockfile",
    "command": "pnpm build",
    "themeDirectory": "."
  }
}

Nested themes and output directories

Both directory paths are relative to the repository root. For example, a project in themes/storefront that writes a complete theme to its dist directory would use:

theme-proof.config.json · Nested project
{
  "version": 1,
  "build": {
    "workingDirectory": "themes/storefront",
    "install": "npm ci",
    "command": "npm run build",
    "themeDirectory": "themes/storefront/dist"
  }
}

Directory defaults are .; commands are omitted by default. Each command has a 15-minute timeout. Absolute paths, paths outside the workspace, unknown properties, and unsupported config versions are rejected.

A missing default config uses the no-build defaults. A missing custom config path is an error. Use the JSON Schema for editor validation.

The preview lifecycle

The current implementation uses a Shopify development context derived from the repository ID and PR number. Subsequent commits use the same context, rather than intentionally creating a new theme for each commit.

  • Open or update: build, stage, validate, then push with Shopify CLI’s strict validation.
  • Review: update one comment with the storefront and Theme Editor links.
  • Close or merge: run cleanup and update the comment.

New builds cancel older builds for the same PR. Deployment and cleanup are serialized without canceling running mutations; stale commits and cleanup for reopened PRs are skipped. Development themes are temporary, not permanent staging environments. Context reuse, URL behavior on password-protected stores, and cleanup of expired or manually deleted themes still need store-backed verification.

Existing-theme selection and new unpublished-theme creation are not implemented. Only development-context is accepted. Live themes are rejected as preview targets.

Build code is not deployment code

The security boundary is the separation between jobs. Filtering environment variables is a precaution, not a sandbox for arbitrary PR code.

  • The build job checks out the PR head SHA and runs repository commands with read-only repository access and no Shopify environment.
  • Only theme directories are staged: assets, blocks, config, layout, locales, sections, snippets, and templates.
  • The deployment job validates the artifact again and does not run repository build scripts.
  • Artifacts must include layout/theme.liquid. Symlinks and unsupported file types are rejected.
  • Default limits are 5,000 files, 10 MiB per file, and 100 MiB total.

Store credentials and deployment targets do not belong in PR-controlled build configuration. Protect workflow changes and configure GitHub environment approvals where appropriate. Do not use a persistent self-hosted runner for untrusted builds.

Report suspected vulnerabilities privately through the repository’s security policy.

Troubleshooting

The deployment cannot find the credential

Check the environment name, then confirm SHOPIFY_CLI_THEME_TOKEN is an environment secret and SHOPIFY_FLAG_STORE is an environment variable. Required reviewers and deployment restrictions can hold or block the job. Fork PRs are not supported for automatic deployment.

The theme artifact is invalid

Check that themeDirectory contains the full theme, including layout/theme.liquid. A Vite assets-only output directory is not a deployable theme. Remove symlinks and inspect the reported file-size or file-count limit.

The build command cannot be found

Install the required tool in build.setup. The workflow provides Node.js, but does not infer or install your project’s package manager or dependencies.

The PR comment cannot be updated

Confirm that the caller grants pull-requests: write and that repository or organization policy allows it. Do not work around token restrictions by exposing a privileged token to the build.

A preview remains after the PR closes

Check the cleanup job for pending environment approval or a failed run. Retry the failed job after resolving the cause. If manual removal is necessary, verify the store and theme identity before deleting anything.

Still stuck? Open an issue with the failing step and sanitized logs. Never include a password or token.

Before the first release

Proof is an open-source, pre-release GitHub Action. Build configuration, artifact validation, deployment, comments, and cleanup have an implementation and automated tests. There is no stable tag or Marketplace listing yet.

The next release gate is an end-to-end test against a dedicated development store, followed by versioned Action references and a Marketplace release. Existing and unpublished theme modes remain future work.

Read the implementation plan, check releases, or contribute on GitHub.