Skip to content

Instantly share code, notes, and snippets.

@jdevalk
Last active February 28, 2024 05:00
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jdevalk/62d523be19743fd495144ade4c65e54c to your computer and use it in GitHub Desktop.
Save jdevalk/62d523be19743fd495144ade4c65e54c to your computer and use it in GitHub Desktop.

Playground Comment Worker

This simple playground.yml creates a comment that opens a WordPress Playground and installs the plugin from the current repository. The current iteration only works with plugins that do not require a build step.

Playground test comment in action

CORS issues

Because GitHub doesn't send the right CORS headers for zip files to be able to install them in a Playground, you need a reverse proxy to bypass the CORS restrictions. The Worker below in worker.js can be used as a Cloudflare worker that does just that.

Blueprint functionality

The Playground URL uses the blueprint functionality of the WordPress Playground, feel free to change that to what you need it to do.

You can see this worker in action here.

name: Playground Comment
on:
pull_request:
jobs:
test:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: mshick/add-pr-comment@v2
with:
message: |
## WordPress Playground
You can easily [test this pull request on the WordPress Playground](https://playground.wordpress.net/#{"landingPage":"/wp-admin/","features":{"networking":true},"steps":[{"step":"defineWpConfigConsts","consts":{"IS_PLAYGROUND_PREVIEW":true}},{"step":"login","username":"admin","password":"password"},{"step":"installPlugin","pluginZipFile":{"resource":"url","url":"https://bypass-cors.altha.workers.dev/${{ github.server_url }}/${{ github.repository }}/archive/${{ github.sha }}.zip"},"options":{"activate":true}}]}), or [download the zip file](${{ github.server_url }}/${{ github.repository }}/archive/${{ github.sha }}.zip).
/**
* Create a simple CORS proxy with Cloudflare Workers
* to bypass cors restrictions in the browser.
* This version follows redirects, only returns a response when the response status is 200,
* and is restricted to handling only ZIP files.
* Example Usage: https://<worker_subdomain>.workers.dev/https://example.com/file.zip
*/
addEventListener('fetch', event =>
event.respondWith(handleRequest(event.request))
)
const handleRequest = async request => {
let url = new URL(request.url);
let requestUrl = request.url.replace(`${url.origin}/`, '');
request = new Request(requestUrl, request);
if (request.headers.has('origin')) request.headers.delete('origin');
if (request.headers.has('referer')) request.headers.delete('referer');
let response = await fetch(request, { redirect: 'follow' }); // Follow redirects
// Check if the response status is 200, otherwise throw an error
if (response.status !== 200) {
throw new Error(`Request failed with status: ${response.status}`);
}
// Check for ZIP file content type
let contentType = response.headers.get('content-type');
if (!contentType || !contentType.includes('application/zip')) {
throw new Error('The requested resource is not a ZIP file.');
}
response = new Response(response.body, response);
response.headers.set('access-control-allow-origin', '*');
response.headers.set('access-control-allow-headers', '*');
return response;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment