Skip to content

Commit

Permalink
Website deployment: Fix builder redirect (#1696)
Browse files Browse the repository at this point in the history
## Motivation for the change, related issues

The `builder/` redirect does not work right now.

Today, when any file (including PHP files), is subject to a
`custom-redirects.php` redirect rule, we set that file aside in the
`files-to-serve-via-php` folder. We set aside files that need
special/custom treatment in a `files-to-serve-via-php` directory because
nginx for the Playground website is configured to delegate requests for
missing static files to WordPress/PHP. We leverage this fallback
behavior in order to implement custom redirects and set custom headers
for various static files.

Unfortunately, this is causing problems with `builder/` redirects. When
a directory is missing an index file, nginx responds with a 403 status
rather than giving us a chance to redirect or handle the request.

This is causing problems for the `/builder` redirect to
`/builder/builder.html`. We use a stub `/builder/index.php` file and
`custom-redirects.php` to support that redirect. During deployment
`/builder/index.php` is moved to
`/files-to-serve-via-php/builder/index.php`, so when the user requests
`/builder`, nginx redirects to `/builder/`, tries to find an index file
in that directory, and 403s when no index file is found.

The good news is that PHP files never needed to be set aside to be
subject to processing by `custom-redirects.php`. `custom-redirects.php`
is invoked when running any PHP file. So we can leave
`builder/index.php` in place and avoid this conflict with nginx.

## Implementation details

This PR adjusts the deployment process to stop moving PHP files to
`files-to-serve-via-php`. It also renames the directory to
`static-files-to-serve-via-php` for clarity.

## Testing Instructions (or ideally a Blueprint)

- Run `npm run build` locally
- rsync the `website-deployment` and
`dist/packages/playground/wasm-wordpress-net` folders to a staging
server via SSH
- Rename the remote `wasm-wordpress-net` directory to
`updated-playground-files`
- Run `website-deployment/apply-update.sh` to apply the updates
- Make sure Playground loads on the staging site
- Make sure a request for `builder/` redirects to `builder/builder.html`
  • Loading branch information
brandonpayton authored Aug 24, 2024
1 parent 97519dc commit 3715f21
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 16 deletions.
4 changes: 2 additions & 2 deletions packages/playground/website-deployment/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ In order to customize these aspects for static files on WP Cloud, we did the fol
- Configured the WP Cloud site to delegate requests for non-existent files to WordPress.
- Provided a `__wp__/index.php` file as a default target for Nginx. - Even though this is not a WordPress site, we can provide a `__wp__/index.php` file that Nginx will run as a fallback for non-existent files. The `__wp__/index.php` file is empty and simply exists so Nginx will invoke PHP.
- Added a `custom-redirects.php` file to implement special request handling. - WP Cloud invokes `<web-root>/custom-redirects.php` (if it exists) at the beginning of every PHP run in order to provide custom request handling. We added this file to implement the rewrites, redirects, and custom headers that we used to get via htaccess.
- Set aside files that need special handling. - If we need custom treatment of static files, those files cannot be found by Nginx. Otherwise, Nginx will serve them directly without invoking PHP. For this reason, all files that need special treatment are set aside under `<web-root>/files-to-serve-via-php/`
- Set aside files that need special handling. - If we need custom treatment of static files, those files cannot be found by Nginx. Otherwise, Nginx will serve them directly without invoking PHP. For this reason, all static files that need special treatment are set aside under `<web-root>/static-files-to-serve-via-php/`

## Deployment notes

New website builds are pushed to the WP Cloud site via SSH.

During deployment, we consult `custom-redirects-lib.php` about each file, and if it needs special treatment (e.g., URL rewrites, redirects, etc), it is set aside into the `<web-root>/files-to-serve-via-php/` folder with its relative path otherwise preserved. For example, if a file `a/b/c/playground.png` requires special handling, it is moved to `<web-root>/files-to-serve-via-php/a/b/c/playground.png`. Nginx will no longer find the file based on the request URI `a/b/c/playground.png` and will delegate the request to PHP, giving us a chance to customize how the file is served.
During deployment, we consult `custom-redirects-lib.php` about each file, and if it needs special treatment (e.g., URL rewrites, redirects, etc), it is set aside into the `<web-root>/static-files-to-serve-via-php/` folder with its relative path otherwise preserved. For example, if a file `a/b/c/playground.png` requires special handling, it is moved to `<web-root>/static-files-to-serve-via-php/a/b/c/playground.png`. Nginx will no longer find the file based on the request URI `a/b/c/playground.png` and will delegate the request to PHP, giving us a chance to customize how the file is served.

At the end of the deployment process, the WP Cloud edge cache is purged.

Expand Down
16 changes: 8 additions & 8 deletions packages/playground/website-deployment/apply-update.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ rm -rf website-update

echo Moving updated Playground files to staging directory
mv updated-playground-files website-update
mkdir website-update/files-to-serve-via-php
mkdir website-update/static-files-to-serve-via-php

echo Copy supporting files for WP Cloud
cp -r ~/website-deployment/__wp__ ~/website-update/
Expand Down Expand Up @@ -60,24 +60,24 @@ echo Checking mime-types.php
echo Adding mime-types.php to updated website files
cp ~/website-deployment/mime-types.php ~/website-update/

function match_files_to_serve_via_php() (
function match_static_files_to_serve_via_php() (
cd ~/website-deployment

"$SITE_PHP" -r '
require "custom-redirects-lib.php";
while ( $path = fgets( STDIN ) ) {
$path = trim( $path );
if ( playground_file_needs_special_treatment($path) ) {
if ( playground_is_static_file_needing_special_treatment($path) ) {
echo "$path\n";
}
}
'
)

function set_aside_files_to_serve_via_php() {
function set_aside_static_files_to_serve_via_php() {
while read FILE_TO_SERVE_VIA_PHP; do
echo " php-served: $FILE_TO_SERVE_VIA_PHP"
TARGET_DIR="files-to-serve-via-php/$(dirname "$FILE_TO_SERVE_VIA_PHP")"
TARGET_DIR="static-files-to-serve-via-php/$(dirname "$FILE_TO_SERVE_VIA_PHP")"
mkdir -p "$TARGET_DIR"
mv "$FILE_TO_SERVE_VIA_PHP" "$TARGET_DIR/"
done
Expand All @@ -86,11 +86,11 @@ function set_aside_files_to_serve_via_php() {
echo Configure which files should be served by Nginx and which by PHP
cd ~/website-update
find -type f |
grep -v files-to-serve-via-php | # avoid files that are moved as part of this pipeline
grep -v static-files-to-serve-via-php | # avoid files that are moved as part of this pipeline
sed 's#^\.##' | # filter '.' from './' so paths are like request URIs
match_files_to_serve_via_php |
match_static_files_to_serve_via_php |
sed 's#^/##' | # remove the leading '/' to get paths relative to current dir
set_aside_files_to_serve_via_php
set_aside_static_files_to_serve_via_php

echo Syncing staged files to production
rsync -av --delete --no-perms --omit-dir-times ~/website-update/ /srv/htdocs/
Expand Down
17 changes: 11 additions & 6 deletions packages/playground/website-deployment/custom-redirects-lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@
*/

// Used during deployment to identify files that need to be served in a custom way via PHP
function playground_file_needs_special_treatment( $path ) {
function playground_is_static_file_needing_special_treatment( $path ) {
if ( str_ends_with( $path, '.php' ) ) {
return false;
}

return (
!! playground_maybe_rewrite( $path ) ||
!! playground_maybe_redirect( $path ) ||
Expand Down Expand Up @@ -86,8 +90,9 @@ function playground_handle_request() {
$resolved_path = playground_resolve_to_index_file( $resolved_path );
}

if ( false === $resolved_path ) {
$resolved_path = realpath( __DIR__ . '/files-to-serve-via-php' . $requested_path );
if ( false === $resolved_path && ! str_ends_with( $requested_path, '.php' ) ) {
// Static files that need special treatment are served from a different directory.
$resolved_path = realpath( __DIR__ . '/static-files-to-serve-via-php' . $requested_path );
if ( is_dir( $resolved_path ) ) {
$resolved_path = playground_resolve_to_index_file( $resolved_path );
}
Expand Down Expand Up @@ -195,21 +200,21 @@ function playground_maybe_redirect( $requested_path ) {
str_ends_with( $requested_path, '/builder/index.php' )
) {
return array(
'location' => 'https://playground.wordpress.net/builder/builder.html',
'location' => 'builder.html',
'status' => 301
);
}

if ( str_ends_with( $requested_path, '/wordpress' ) ) {
return array(
'location' => 'https://playground.wordpress.net/wordpress.html',
'location' => 'wordpress.html',
'status' => 301
);
}

if ( str_ends_with( $requested_path, '/gutenberg' ) ) {
return array(
'location' => 'https://playground.wordpress.net/gutenberg.html',
'location' => 'gutenberg.html',
'status' => 301
);
}
Expand Down
18 changes: 18 additions & 0 deletions packages/playground/website/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,24 @@ export default defineConfig(({ command, mode }) => {
outputFile: 'assets-required-for-offline-mode.json',
distDirectoriesToList: ['./', '../remote', '../client'],
}) as Plugin,

/**
* Copy the `builder/index.php` workaround to the `dist/playground/website/builder/` directory.
*/
{
name: 'builder-index-plugin',
apply: 'build',
writeBundle({ dir: outputDir }) {
const indexPath = path('builder/index.php');

if (existsSync(indexPath) && outputDir) {
copyFileSync(
indexPath,
join(outputDir, 'builder/index.php')
);
}
},
} as Plugin,
],

// Configuration for building your library.
Expand Down

0 comments on commit 3715f21

Please sign in to comment.