メインコンテンツへスキップ

Adding PR Preview Buttons with GitHub Actions

The Playground PR Preview action adds a preview button to your pull requests. Clicking the button launches Playground with your plugin or theme installed from the PR branch:

PR Preview Button

For complete configuration options and advanced features, see the action-wp-playground-pr-preview workflow README.

How it works

The action runs on pull request events (opened, updated, edited). It can either update the PR description with a preview button or post the button as a comment.

Basic setup for plugins

For plugins without a build step, create .github/workflows/pr-preview.yml:

name: PR Preview
on:
pull_request:
types: [opened, synchronize, reopened, edited]

jobs:
preview:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Post Playground Preview Button
uses: WordPress/action-wp-playground-pr-preview@v2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
mode: 'append-to-description'
plugin-path: .

The plugin-path: . setting points to your plugin directory. For subdirectories like plugins/my-plugin, use plugin-path: plugins/my-plugin.

See adamziel/preview-in-playground-button-plugin-example for a live example of this workflow in action.

Basic setup for themes

For themes, use theme-path instead of plugin-path:

name: PR Preview
on:
pull_request:
types: [opened, synchronize, reopened, edited]

jobs:
preview:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Post Playground Preview Button
uses: WordPress/action-wp-playground-pr-preview@v2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
theme-path: .

Button placement

By default, the action updates the PR description (mode: append-to-description). To post as a comment instead:

with:
plugin-path: .
mode: comment
github-token: ${{ secrets.GITHUB_TOKEN }}

The action wraps the button in HTML markers and updates it on subsequent runs. By default, it restores the button if you remove it. To prevent restoration:

with:
plugin-path: .
restore-button-if-removed: false

Working with built artifacts

For plugins or themes requiring compilation, the workflow involves building the code, exposing it via GitHub releases, and creating a blueprint that references the public URL.

Example workflow (see complete documentation):

name: PR Preview with Build
on:
pull_request:
types: [opened, synchronize, reopened, edited]

permissions:
contents: write
pull-requests: write

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build
run: |
npm install
npm run build
zip -r plugin.zip dist/
- uses: actions/upload-artifact@v4
with:
name: built-plugin
path: plugin.zip

expose-build:
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
artifact-url: ${{ steps.expose.outputs.artifact-url }}
steps:
- name: Expose built artifact
id: expose
uses: WordPress/action-wp-playground-pr-preview/.github/actions/expose-artifact-on-public-url@v2
with:
artifact-name: 'built-plugin'
pr-number: ${{ github.event.pull_request.number }}
commit-sha: ${{ github.sha }}
artifacts-to-keep: '2'

create-blueprint:
needs: expose-build
runs-on: ubuntu-latest
outputs:
blueprint: ${{ steps.blueprint.outputs.result }}
steps:
- uses: actions/github-script@v7
id: blueprint
with:
script: |
const blueprint = {
steps: [{
step: "installPlugin",
pluginZipFile: {
resource: "url",
url: "${{ needs.expose-build.outputs.artifact-url }}"
}
}]
};
return JSON.stringify(blueprint);
result-encoding: string

preview:
needs: create-blueprint
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: WordPress/action-wp-playground-pr-preview@v2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
blueprint: ${{ needs.create-blueprint.outputs.blueprint }}

The artifacts-to-keep setting controls how many builds to retain per PR. For themes, change installPlugin to installTheme.

See adamziel/preview-in-playground-button-built-artifact-example for a complete working example.

Custom blueprints

Use blueprints to configure the Playground environment. You can install additional plugins, set WordPress options, import content, or run custom PHP.

Example installing your plugin with WooCommerce:

jobs:
create-blueprint:
name: Create Blueprint
runs-on: ubuntu-latest
outputs:
blueprint: ${{ steps.blueprint.outputs.result }}
steps:
- name: Create Blueprint
id: blueprint
uses: actions/github-script@v7
with:
script: |
const blueprint = {
steps: [
{
step: "installPlugin",
pluginData: {
resource: "git:directory",
url: `https://github.com/${context.repo.owner}/${context.repo.repo}.git`,
ref: context.payload.pull_request.head.ref,
path: "/"
}
},
{
step: "installPlugin",
pluginData: {
resource: "wordpress.org/plugins",
slug: "woocommerce"
}
}
]
};
return JSON.stringify(blueprint);
result-encoding: string

preview:
needs: create-blueprint
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: WordPress/action-wp-playground-pr-preview@v2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
blueprint: ${{ needs.create-blueprint.outputs.blueprint }}

Or reference an external blueprint:

with:
blueprint-url: https://example.com/path/to/blueprint.json

See Blueprints documentation for all available steps and configuration options.

Template customization

Customize the preview content using template variables:

with:
plugin-path: .
description-template: |
### Test this PR in WordPress Playground

{{PLAYGROUND_BUTTON}}

**Branch:** {{PR_HEAD_REF}}

Available variables: {{PLAYGROUND_BUTTON}}, {{PLUGIN_SLUG}}, {{THEME_SLUG}}, {{PR_NUMBER}}, {{PR_TITLE}}, {{PR_HEAD_REF}}, and more.

See the workflow README for the complete list.

Artifact exposure

The expose-artifact-on-public-url action uploads built files to a single release (tagged ci-artifacts by default). Each artifact gets a unique filename like pr-123-abc1234.zip. Old artifacts are automatically cleaned up based on artifacts-to-keep.

Configuration options: Expose Artifact Inputs

Troubleshooting

Button not appearing: Workflow file must exist on the default branch. Check Actions tab for errors.

Preview fails to load: Verify path points to valid plugin/theme directory. Check build logs for artifacts.

Not activated: Check browser console for PHP errors. Dependencies may be missing.

Permissions errors: Set permissions at job level.

More: workflow README

Examples

Next steps

  • Add demo content (guide)
  • Create custom blueprints (docs)
  • Integrate with testing workflows
  • Customize templates for reviewers