{"id":26562732,"url":"https://github.com/upsun/modern-wp-upsun-experiment","last_synced_at":"2025-09-02T04:42:21.316Z","repository":{"id":283119409,"uuid":"950730592","full_name":"upsun/modern-wp-upsun-experiment","owner":"upsun","description":"Repository to accompany the https://upsun.com/blog/modern-wordpress-development-workflow/ blog post","archived":false,"fork":false,"pushed_at":"2025-03-18T16:27:08.000Z","size":391,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-03-18T17:36:53.715Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/upsun.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-03-18T15:48:33.000Z","updated_at":"2025-03-18T16:27:11.000Z","dependencies_parsed_at":"2025-03-18T17:48:34.074Z","dependency_job_id":null,"html_url":"https://github.com/upsun/modern-wp-upsun-experiment","commit_stats":null,"previous_names":["upsun/modern-wp-upsun-experiment"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/upsun%2Fmodern-wp-upsun-experiment","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/upsun%2Fmodern-wp-upsun-experiment/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/upsun%2Fmodern-wp-upsun-experiment/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/upsun%2Fmodern-wp-upsun-experiment/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/upsun","download_url":"https://codeload.github.com/upsun/modern-wp-upsun-experiment/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244974089,"owners_count":20541067,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-03-22T15:19:25.163Z","updated_at":"2025-03-22T15:19:25.721Z","avatar_url":"https://github.com/upsun.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n\n# Modern WordPress development and deployment workflow\n\nThis repository hosts the codebase for two sites, both\n\n- are built using [WordPress.org](https://wordpress.org)\n- are deployed on [Upsun.com](https://upsun.com) in [Multi-App setup](https://docs.upsun.com/create-apps/multi-app.html)\n- have their codebase managed via [Composer](https://getcomposer.org), thanks to [`johnpbloch/wordpress`](https://github.com/johnpbloch/wordpress) and [WordPress Packagist](https://wpackagist.org)\n- have their dependencies automatically upgraded by [Dependabot](https://dependabot.com)\n- have their Dependabot PRs automatically merged by [Mergify](https://mergify.com) when builds pass\n- have new code deployed to production automatically on every PR merge\n- use [Redis](https://redis.io) as back-end caching\n- use [Cloudflare](https://www.cloudflare.com) as CDN\n- use [GitHub Actions](https://github.com/features/actions) as CI/CD and Cron Scheduler\n\nIn addition to the above:\n\n- the `ita` site uses [Elasticsearch](https://www.elastic.co/elasticsearch/)\n- the `eng` site uses [Algolia](https://www.algolia.com)\n\n## WordPress\n\nWordPress remains by far the CMS that is easiest to adopt, and that provides a fast time to market in the majority of \nuse cases. There is so much high quality stuff out there for WordPress, be it OSS or Premium, that one can have \nbeautiful sites powered by an easy-to-use CMS up and running in no time.\n\n## Upsun.com\n\nUpsun provide an incredibly flexible and powerful PaaS. As they like to call it, it is the Idea-to-Cloud PaaS. With a \nGitHub integration, you can have a child environment cloned from your a parent environment (the root of the tree is \nusually the production environment) for each pull request, and a Status Check that runs a build on Upsun.com out of the \nnew branch, so to verify that the changes do not break anything. Upon merging a PR, the code is deployed straight to the\nparent environment.\n\n## Dependabot\n\nNow part of the GitHub family, it provides a free plan for public repositories, and it supports PHP+Composer. You can \nconfigure it to decide what kind of upgrades you want to perform on your dependencies, and the bot will issue pull \nrequests periodically, avoiding stale dependencies.\n\n## Mergify\n\nThis service, too, provides a free plan for public repositories. You can configure it with a number of conditions that, \nwhen met, will trigger an automatic merge of your pull requests.\n\n## Redis\n\nRedis is an open source, in-memory data structure store, that here I use as a back-end cache system via the\n[Redis Object Cache](https://wordpress.org/plugins/redis-cache/) plugin. It is \n[easy to adopt with Upsun](https://docs.upsun.com/add-services/redis.html), as it is one of the many containerized \nservices that you can add to your project.\n\n## Cloudflare\n\nCloudflare is one of the CDNs best [supported by Upsun](https://docs.upsun.com/domains/cdn.html); it is also one\nthat provides a good free plan. When you combine that with the awesome plugin\n[WP Cloudflare Super Page Cache](https://wordpress.org/plugins/wp-cloudflare-page-cache/), choosing Cloudflare for your \npersonal sites becomes really a no-brainer.\n\n## WordPress translation files and Composer\n\nOne of the sites is not in English and uses translation files for WordPress core, themes, and plugins for an optimal \nsetup. WordPress Packagist does not currently provide such files, but—–thankfully–—the OSS community never rests, and \n[`inpsyde/wp-translation-downloader`](https://github.com/inpsyde/wp-translation-downloader) is a great Composer plugin \nto manage WordPress translations.\n\n## GitHub Actions\n\nIt seemed like the obvious choice. Currently, no particular CI/CD task is implemented, as Upsun provide their own \nbuilt-in CI/CD for builds and deployments. Moreover, I do not require particular testing at present, so I am not using \nActions for that either. However, I am using it as Cron Scheduler, to perform regular tasks on my Upsun project.\n\nAlthough Upsun allow you to do that by defining Cron Jobs \n[on their own platform](https://docs.upsun.com/create-apps/app-reference/single-runtime-image.html#crons), I chose to \nhave this functionality decoupled from Upsun.\n\n## Elasticsearch\n\n[Elasticsearch](https://www.elastic.co/elasticsearch/) is a distributed, RESTful search and analytics engine that \ncentrally stores your data for lightning fast search, fine‑tuned relevancy, and powerful analytics that scale with ease.\n[Upsun allows a very easy adoption of the service](https://docs.upsun.com/add-services/elasticsearch.html). This \nexperimental project uses the \n[last open-source version of Elasticsearch](https://en.wikipedia.org/wiki/Elasticsearch#Licensing_changes) (7.10). \n[ElasticPress](https://github.com/10up/ElasticPress) provides a seamless integration with WordPress.\n\n## Algolia\n\n[Algolia](https://www.algolia.com/doc/faq/why/what-makes-algolia-different-than-elasticsearch-or-solr/) is a commercial \nservice similar to ElasticSearch or Solr, but that claims to be up to 200x faster than Elasticsearch. There is a\n[free plan](https://www.algolia.com/pricing) that is definitely suitable for small sites. Algolia\n[no longer maintains an official WordPress plugin](https://www.algolia.com/doc/integration/wordpress/indexing/setting-up-algolia/) \nbut their former official plugin was forked and it is now known as\n[WP Search with Algolia](https://wordpress.org/plugins/wp-search-with-algolia/). It is actively maintained and works \nwell as far as we have been able to ascertain.\n\n## Rudimentary \"distro\" support for WordPress\n\n\"Distros\" or \"install profiles\" are essentially a way to have your own default installation configuration. Whilst \n[some softwares have built-in support](https://www.drupal.org/docs/drupal-distributions) for that, WordPress does not. \nOur rudimentary support for this in WordPress relies on two things: a \n[bespoke section](https://github.com/upsun/modern-wp-upsun-experiment/blob/main/ita/composer.json#L50-L63) in the \n`composer.json` file and [a script](https://github.com/upsun/modern-wp-upsun-experiment/blob/main/ita/scripts/deploy.sh)\nthat uses the information in that section to perform some initial setup. The script is then executed as \n[part of the `deploy` hook](https://github.com/upsun/modern-wp-upsun-experiment/blob/main/.upsun/config.yaml#L98) in \nUpsun. If you are wondering why we didn't simply use the `scripts.postbuild` section in `composer.json` to run such a \nscript, the reason is that during the `build` phase in Upsun (when `composer` is run) the database service is not yet \navailable.\n\n## Jetpack's identity crisis averted\n\nYou may know that Jetpack can suffer from \n[identity crisis](https://jetpack.com/support/safe-mode/#what-is-an-identity-crisis). This template is configured so \nthat non-production environments on Upsun automatically adopt \n[Offline Mode](https://jetpack.com/support/development-mode/), thus averting the identity crisis. It would've been \npreferable to use [Staging Mode](https://jetpack.com/support/staging-sites/) instead of Offline Mode, but it turns \nout—after a long chat with WordPress support—that just adding `define( 'JETPACK_STAGING_MODE', true );` to \n`wp-config.php` for a site that already has an active production connection to Jetpack doesn't actually put that site in\nSafe Mode automatically as described, but still causes the identity crisis.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fupsun%2Fmodern-wp-upsun-experiment","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fupsun%2Fmodern-wp-upsun-experiment","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fupsun%2Fmodern-wp-upsun-experiment/lists"}