Comments (2)
I posted about this on our internal dev list, so cross-posting the relevant content here.
The goal is to adapt Altis' composer dev-tools phpunit
command to GitHub Actions. I turned first to John's testing workflow for the Authorship plugin, which provides a great baseline. However, the composer install
step in that action didn't work for the Altis project I was working on because the project pulls in multiple private GitHub repositories via composer. Most of the complexity in the post below is due to private Composer VCS dependencies, and to a TTY mode issue in Local Server.
Post about how I set up GH Actions on Altis
Install private composer dependencies
The php-actions/composer
action supports private repositories by letting you inject an SSH key using GitHub Secrets. We followed this process:
- Create a new SI user GitHub account within the team's organization.
- Give that account read-only access to all the relevant dependency repositories.
- Generate a passwordless SSH key and add it to the user. (I tried using a key with a passphrase and spent a whole day wondering why it wouldn't work; d'oh)
- Add that SSH key as a GH secret in the settings for the main project repository
- Update the GitHub Action workflow file to look like this:
name: Unit Tests
on:
push:
branches:
- 'staging'
- 'main'
pull_request:
branches:
- '**'
jobs:
phpunit:
strategy:
matrix:
php: ['7.4']
name: PHPUnit on PHP ${{ matrix.php }}
runs-on: ubuntu-18.04
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Cache Composer dependencies
uses: actions/cache@v2
with:
path: /tmp/composer-cache
key: ${{ runner.os }}-${{ hashFiles('**/composer.lock') }}
- name: Install PHP dependencies
uses: php-actions/composer@v6
with:
version: 1 # Composer 1
php_version: ${{ matrix.php }}
ssh_key: ${{ secrets.ssh_key }}
ssh_key_pub: ${{ secrets.ssh_key_pub }}
We'll be switching over to Composer 2 soon, but for now this is the most straightforward way I could find to install Composer packages in GH Actions. The php-actions/composer
action will ensure PHP is set up, so we don't need to manually install that as John did in Authorship. I've also copied the caching example from the composer action's documentation (although I haven't seen it actually speed things up at all).
Running PHPUnit in Docker
composer dev-tools phpunit
executes the unit tests inside the running container. So, let's run Docker!
- name: Start the containers
run: |
composer server start
Whoops. Job failed: vendor/docker-compose.yml
is not writable, so the generation of the configuration file fails. OK, the Composer action must install as root. Composer doesn't like being run with sudo
, so let's see if that action has an option to set the user... nope, doesn't seem like it. We'll just manually make the file writable instead:
- name: Start the containers
# Make the docker-compose file writeable, then start the server.
run: |
sudo touch vendor/docker-compose.yml
sudo chown $(whoami) vendor/docker-compose.yml
composer server start
Commit, push, and... heck.
TTY mode requires /dev/tty to be read/writable.
π¬ I have no idea what that means. I can search the web, though! Hmm, alright, every article seems to want me to run set(βgit_ttyβ, false);
. But, I don't want to have to modify Local Server. Let's do some research.
A ha! There's a post about this specific TTY issue in the context of GitHub Actions. It's a known issue, and there's a standard workaround!
Let's use script
to run the composer server
command in a "typescript" of a terminal session. That doesn't have anything to do with TypeScript: it means that only a log of the session gets passed back from the command, so we sidestep the lack of TTY.
- name: Start the containers
shell: 'script -q -e -c "bash {0}"'
# Make the docker-compose file writeable, then start the server.
run: |
sudo touch vendor/docker-compose.yml
sudo chown $(whoami) vendor/docker-compose.yml
composer server start
Awesome, now the containers are pulling! And... the action still fails. The containers start, but it crashes out afterwards. The install was succeeding, but the error was instead triggered while trying to set up ElasticPress. We don't need ES to run our tests, so π€« let's just add continue-on-error: true
to our command, and move on.
n.b. Rob has pointed out in a Slack thread that we could have solved this by setting the environment variable ES_MEM_LIMIT=2g
. There are Altis docs about that issue. Anyway, now the containers are starting, and we can finally run our dev-tools
command!
We have the same file permissions issue when running PHPUnit, because the dev-tools
command creates vendor/phpunit.xml
. I used the same approach as above to make that file individually writable, but in retrospect I could also have made the CI runner
user the owner of the vendor
directory itself.
Putting it all together
This is our complete PHPUnit action:
name: Unit Tests
on:
push:
branches:
- 'staging'
- 'main'
pull_request:
branches:
- '**'
jobs:
phpunit:
strategy:
matrix:
php: ['7.4']
name: PHPUnit on PHP ${{ matrix.php }}
runs-on: ubuntu-18.04
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Cache Composer dependencies
uses: actions/cache@v2
with:
path: /tmp/composer-cache
key: ${{ runner.os }}-${{ hashFiles('**/composer.lock') }}
- name: Install PHP dependencies
uses: php-actions/composer@v6
with:
version: 1 # Composer 1
php_version: ${{ matrix.php }}
ssh_key: ${{ secrets.ssh_key }}
ssh_key_pub: ${{ secrets.ssh_key_pub }}
- name: Start the containers
shell: 'script -q -e -c "bash {0}"'
# Make the docker-compose file writeable, then start the server.
run: |
sudo touch vendor/docker-compose.yml
sudo chown $(whoami) vendor/docker-compose.yml
composer server start
continue-on-error: true # ElasticPress may report failure
- name: Run PHPUnit
run: |
sudo touch vendor/phpunit.xml
sudo chown $(whoami) vendor/phpunit.xml
composer dev-tools phpunit
Once I got all of this working, Rob also clued me in to the fact that Joe had gone through a similar process on another codebase. Instead of using the script
trick, Joe's action uses sed
to live-patch Local Server within the CI environment. Fixing things more permanently in Local Server would probably be a prerequisite to solving this ticket generally, because the more we can remove the confusing bits, the easier a scaffold command will be.
from altis-dev-tools.
Only thing preventing us is time and capacity, at the time GH actions weren't really suitable but I believe @joehoyle got it working and @kadamwhite too.
It's partially related to #102 and also the RFC for having a single dev dependency module for the local environments here https://github.com/humanmade/product-dev/pull/561
Ideally I'd like for devs to be able to choose their preferred CI environment by either using documented config or a scaffolding command like composer dev-tools scaffold travis
or composer dev-tools scaffold github
. I thought I'd captured that in an issue somewhere already but I guess not!
from altis-dev-tools.
Related Issues (20)
- Module tests that check front end behaviour can fail without a proper theme installed HOT 11
- Update default `dist` for travis.yml to `bionic`
- Add linting for docs added to modules HOT 10
- Create bootstrap command for codespaces HOT 2
- Integration tests erroring with "The site you have requested is not installed" HOT 4
- Error messages get swallowed when running all test suites at once
- Switch Travis config to use `arm64` architecture by default HOT 1
- Standardise the flamegraph / icicle graph usage and appearance HOT 1
- Re-add mention of XHProf to the docs
- Include WordPress action and filter names in Excimer/XHProf sampling data
- Codespaces: `composer server start` produces error message
- Codespaces: S3 Console link is generated with a local url
- Update Codespaces documentation to recommend 4-core Codespace
- Incorrect version of Requests dependency loaded HOT 2
- Documentation linting issues
- Codeception: option to disable cache for functional tests
- `composer server stop` doesn't stop mutagen container
- PHPUnit documentation links return a 404
- Fix Deprecation Notice warning in Altis Dev Tools when using PHP 8.2 HOT 1
- wp-phpunit version on 12.0.6 and above causes unit tests to immediately fail
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from altis-dev-tools.