GC Articles Live Demo (MVP)
Docker-compose and VS Code Remote Container environment featuring:
- apache (reverse-proxy to wordpress/php-fpm)
- mariadb (instead of mysql)
- wordpress (wordpress/php-fpm)
- wp-cli & composer (devcontainer)
- phpmyadmin (db admin)
Including installation instructions on a Mac.
- NPM (install Node)
- Docker (install Docker Desktop)
- Docker-compose (included with Docker Desktop)
- VS Code w/ Remote Containers extension (optional)
- Composer
Clone the repo and cd
to the project directory.
git clone [email protected]:cds-snc/gc-articles.git
cd gc-articles
Copy the .env.example
file to .env
and customize as needed.
cp .env.example .env
First thing you'll want to add is an ENCRYPTION_KEY
which will be used for encrypting sensitive information in the database such as the Notify API keys.
The encryption key is a base64 encoded random string. There is a helpful Composer command for generating a key:
composer generate-encryption-key
In your .env
file, make sure to quote the entire string, including the "base64:" prefix.
ENCRYPTION_KEY="base64:dvss45WujgTWIy1lMspSU128PsnyV3fNXDfZNPZOG+k="
The following to docker-compose tasks will get all your dependencies installed and database setup:
docker-compose run composer
docker-compose run install
Afterwards, download and build your frontend dependencies:
npm i
With your encryption key, environment configuration, and dependencies installed, you can bring up the environment using docker-compose from the root of the project.
docker-compose up
Once the services are running, you can access a cli environment preconfigured with all the tools needed for development:
npm run cli
Alternatively, you can open the project in VS Code Remote Containers:
- Open the project in VS Code
- When prompted "Reopen in container" or press F1 -> Remote-Containers: Open folder in container
- VS Code will open a devcontainer terminal environment
Either way, once the environment is up, the site will be available on localhost
:
- Visit
localhost
to see your new WordPress install - Visit
localhost/login
to see the admin interface
Wordpress will be installed with some pre-configured plugins and themes, and will be configured as a multi-site install. There will also be a default administrator account, with the following credentials:
username: admin
password: secret
Web admin for MySQL database.
Web interface: localhost:8080
username: dbuser
password: secret
- two-factor
- wp-bootstrap-blocks
- wp-native-php-sessions
- wps-hide-login
- wpml
- yoast
- login-lockdown
- disable-user-login
This project is configured to use Composer to manage WordPress Themes and Plugins.
To install a plugin or theme, find it on WPackagist, add it to composer.json, and run composer install
or use composer require wpackagist-[plugin|theme]/[package-name]
. These commands should be run from within the wordpress
folder.
Note: when starting up the devcontainer or docker-compose, composer install
is run to automatically install plugins and themes defined in composer.json.
When adding plugins, if they should be automatically enabled for sites, make sure you activate them in:
- cypress/test-setup/setup-ci.sh
- docker-compose.yml
When creating a custom plugin or theme, you should prefix the folder name with cds-
. This will ensure the code is included in git and code quality scans.
Our custom plugin and theme both use Composer dependencies. It should be noted that they are configured to store their dependencies in the wordpress-level vendor folder. This reduces the risk of conflicting vendor packages being loaded by different autoloaders.
See the wordpress/composer.json
file for how we configure our plugin/theme as local "path" dependencies.
WPML is a paid/private plugin that doesn't support composer-based installs. As such, we we had to mirror the plugin code in our own private plugin repository. We will need to manually monitor for updates and update our private mirror, process TBD.
Once activated for the network, the plugin needs to be configured for each site. You can do this by visiting the WPML link in the sidebar. You will need an "activation key" which will require authorization to the vendor website.
Currently we are only using the WPML core plugin component, not the String Translation, Media Translation, or Translation Management components.
WordPress uses gettext to manage and compile translation files. We have added a couple composer scripts to simplify working with the various commands and steps.
If you prefer to run these commands from your host environment, you'll need to make sure you have composer and gettext installed.
Alternatively, if you work inside the .devcontainer
or the cli
container in the docker-compose
environment,
all necessary dependencies are installed. You can enter the cli
container in the docker-compose
environment by
running: docker exec -it cli zsh
Both the cds-base
plugin and cds-default
theme include these scripts and they work the same way. There are
also scripts in the base wordpress
-folder level composer.json that will recursively call each of the theme and plugin
scripts.
When working with theme or plugin files, create translatable strings by following the
WordPress documentation on the
subject, making sure to set the domain
as cds-snc
. In short, you will probably use syntax like the following:
__( 'Hello, dear user!', 'cds-snc' );
or
_e( 'Your Ad here', 'cds-snc' );
In order to translate these strings and make them available to WordPress, you will go through the steps below.
NOTE: You can execute the commands below in the cds-base
plugin folder, the cds-default
theme folder, or at
the root wordpress
folder, depending on scope/context.
- Prepare translation files
composer prepare-translations
This will scan the plugin or theme files and update the cds-snc.pot
file which captures all the translatable strings.
It will then merge any updates into the fr_CA.po
file which is where translations are added.
- Add translated strings
At this point, you should add any French translations to that .po file as described in the WordPress documentation.
- Compile translations
Once translatable strings have been merged to the .po file, and translations have been added, you need to compile the translations into a format that WordPress can read with the second command.
composer compile-translations
At this point, you will likely have a bunch of local changes in the languages
folder:
cds-snc.pot
fr_CA.mo
fr_CA.po
- one or more
fr_CA-xxx.json
files (* IF any strings appear in javascript files)
All of these files should be committed along with the rest of your PR.
We are using Cypress to test workflows, Pest for PHP-language unit tests, and PHP_CodeSniffer for PHP-language linting.
To run the cypress tests, first spin up a wp-env environment.
npm run wp-env:init
This brings up 2 wordpress environments: a dev environment on http://localhost:8888, and a test environment (used by cypress) on http://localhost:8889. It's not the same as what you see in the docker compose up
local development environment, but it is close enough, and it allows us to test admin workflows. The default credentials for the wp-env environment are admin
& password
.
To open cypress in a browser, use
npm run cy:open
You can run test suites one at a time or the entire set of tests.
To reset the environment, to wipe out local changes, use
npm run wp-env:clean
When you are finished testing, you can spin down the wp-env environment with
npm run wp-env:stop
Additional commands can be found in the root-level package.json
file.
Pest is used for unit-testing PHP. Pest is a wrapper around PHPUnit that abstracting away a lot of the redundant/repetitive class structure code that you usually have with PHPUnit. Pest tests must be run from the /wordpress
folder.
cd wordpress
./vendor/bin/pest
The Pest tests for the GC Lists plugin can only be run from inside the running devcontainer. Begin by opening 2 terminal windows: 1 to run the app, and 1 to SSH into the devcontainer.
# Terminal 1: start the app
docker compose up
# Terminal 2
## SSH into the running container
docker exec -it cli zsh
## Shortcut to the gc-lists directory
gclists
## Seed a wordpress integration database
composer prepare-test-db
## Run tests
composer test
PHP_CodeSniffer (phpcs
) lints our PHP code to enforce a consistent style across the codebase. To run phpcs
, first install it globally (instructions for installing with Homebrew). Then, you can lint the codebase with
phpcs .wordpress/wp-content/plugins/cds-base -n --standard=PSR12 --ignore=build,node_modules,vendor,tests,.css,.js
Note that this can pick up vendor files, so specifically targeting the module(s) you are working on (or individual files) will result in least amount of noise.
phpcs ./wordpress/wp-content/plugins/cds-base/classes/Modules/Cleanup/Articles.php --standard=PSR12
NOTE You will need to have GitHub CLI installed to complete the following steps
npm run update-version
This script will automatically update the VERSION, theme and plugin files and create a PR titled Version Bump [version number]
npm run tag-release
This step will prompt for release notes and will automatically update the environments.yml manifest file
and create a PR titled Release [version number]
.
It will also create a tag and release on Github, and build and push Staging and Production containers tagged with the version number to the container repositories for each environment.
IMPORTANT: The tagged (i.e. v1.x.x) container needs to finish building before the Release PR is merged.
You can check via the Github actions tab.
This will cause the tagged release to be deployed to Staging
.
You should always release to Staging first. The "tag-release" step above will build/tag/push both Staging and Production containers, so the Production deploy is a simple config change.
When you're ready to deploy to Production, run the following command:
npm run deploy-production
This will first prompt you for the version you would like to deploy, and it will create a PR titled Production release: [version number]
which simply
updates the deployed versions manifest.
Production
release.
When infrastructure changes are merged to main
, they are automatically deployed to Staging. To release these changes to Production, run the following:
npm run deploy-infrastructure
As with the other release commands, this will ask for a version number. This will create a new git infrastructure/vX.Y.Z
tag with X.Y.Z
replaced by the version number. Additionally a new PR will be created.
Once this release PR is merged, the infrastructure changes will be applied to Production.