How To Fix orchestra/testbench Permissions Error In GitHub Actions
I was recently setting up GitHub Actions CI for one of my Laravel packages which adds a layered cache driver for Laravel.
The tests had been running fine locally but when running in GitHub CI they all failed with this error:
Exception: The /home/runner/work/laravel-multi-cache/laravel-multi-cache/vendor/orchestra/testbench-core/laravel/bootstrap/cache directory must be present and writable.
/home/runner/work/laravel-multi-cache/laravel-multi-cache/vendor/laravel/framework/src/Illuminate/Foundation/PackageManifest.php:178
/home/runner/work/laravel-multi-cache/laravel-multi-cache/vendor/orchestra/testbench-core/src/Foundation/PackageManifest.php:174
/home/runner/work/laravel-multi-cache/laravel-multi-cache/vendor/laravel/framework/src/Illuminate/Foundation/PackageManifest.php:137
/home/runner/work/laravel-multi-cache/laravel-multi-cache/vendor/laravel/framework/src/Illuminate/Foundation/PackageManifest.php:107
/home/runner/work/laravel-multi-cache/laravel-multi-cache/vendor/orchestra/testbench-core/src/Foundation/PackageManifest.php:107
/home/runner/work/laravel-multi-cache/laravel-multi-cache/vendor/laravel/framework/src/Illuminate/Foundation/PackageManifest.php:90
/home/runner/work/laravel-multi-cache/laravel-multi-cache/vendor/laravel/framework/src/Illuminate/Foundation/PackageManifest.php:79
/home/runner/work/laravel-multi-cache/laravel-multi-cache/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/RegisterFacades.php:26
/home/runner/work/laravel-multi-cache/laravel-multi-cache/vendor/orchestra/testbench-core/src/Concerns/CreatesApplication.php:426
/home/runner/work/laravel-multi-cache/laravel-multi-cache/vendor/orchestra/testbench-core/src/Concerns/CreatesApplication.php:247
/home/runner/work/laravel-multi-cache/laravel-multi-cache/vendor/orchestra/testbench-core/src/TestCase.php:122
/home/runner/work/laravel-multi-cache/laravel-multi-cache/vendor/orchestra/testbench-core/src/Concerns/ApplicationTestingHooks.php:72
/home/runner/work/laravel-multi-cache/laravel-multi-cache/vendor/orchestra/testbench-core/src/Concerns/Testing.php:45
/home/runner/work/laravel-multi-cache/laravel-multi-cache/vendor/laravel/framework/src/Illuminate/Collections/helpers.php:224
/home/runner/work/laravel-multi-cache/laravel-multi-cache/vendor/orchestra/testbench-core/src/functions.php:117
/home/runner/work/laravel-multi-cache/laravel-multi-cache/vendor/laravel/framework/src/Illuminate/Collections/helpers.php:224
/home/runner/work/laravel-multi-cache/laravel-multi-cache/vendor/orchestra/testbench-core/src/Concerns/Testing.php:57
/home/runner/work/laravel-multi-cache/laravel-multi-cache/vendor/orchestra/testbench-core/src/TestCase.php:51
/home/runner/work/laravel-multi-cache/laravel-multi-cache/tests/MultiStoreTest.php:24
"directory must be present and writable" shows us that it's likely a permissions issue. The user running phpunit doesn't have write access to the directory.
For reference, here is my pipelines.yaml
file:
name: pipeline
# https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#concurrency
concurrency:
group: ${{ github.ref_name }}
cancel-in-progress: true
on:
push:
workflow_dispatch:
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install dependencies
uses: php-actions/composer@v6
with:
php_version: 8.1
- name: Run tests
run: vendor/bin/phpunit
It's odd that it wants to write to the vendor directly, but that seems to just be how testbench works. You can change it, but that means providing your own demo Laravel installation for the tests.
On the other side, the question is why can't we write to the vendor directory? I added these steps to my pipeline.yaml
file to find out:
# Show who the current user is
- run: whoami
# Show the owner of the directroy in question
- run: ls -la vendor/orchestra/testbench-core/laravel/bootstrap
Here's the result:
The tests run as a user called runner
, but the cache
directory is owned by root
.
I found an open issue for the php-actions/composer
package asking about why the dependencies are installed as root. There is no resolution as of yet.
So we're stuck with two issues:
- orchestra/testbench unusually wants to write to the vendor directory. Changing this seems like more hassle than it's worth.
- Our runner user can't write to the directory because php-actions/composer will only run as (and install the dependencies as) root.
The Workaround
To solve this issue we can just change the owner of the vendor
directory after the dependencies are installed. Add this line to your pipeline.yaml
just after the php-actions/composer@v6
step
- run: sudo chown -R $USER:$USER $GITHUB_WORKSPACE/vendor
Now we have a happy pipeline!