Search code examples
phplaraveldockergdalpine-linux

Why is imagecreatetruecolor undefined despite being installed?


How can I enable gd image methods such as imagecreatetruecolor in Laravel tests running on a Composer image through Bitbucket Pipelines?


I'm using Bitbucket's pipelines for CI/CD and the official Composer image composer:2.1.9 (alipne) for testing. Usually this is fine out of the box but for one particular package I need to add some extensions for image manuipulation.

I am fairly confident I have gd installed and enabled with build steps that complete sucessfully:

script:
  - apk add libzip-dev
  - apk add libpng-dev
  - apk add jpeg-dev
  - apk add libjpeg-turbo-dev
  - docker-php-ext-configure gd --enable-gd --with-jpeg
  - docker-php-ext-install gd
  - docker-php-ext-enable gd
  - composer self-update
  - composer update
  - composer install --prefer-dist --no-progress --optimize-autoloader --classmap-authoritative
  - php -m
  - php -i

But when the tests are run we get errors Error: Call to undefined function Illuminate\Http\Testing\imagecreatetruecolor():

[...]

1) Gavin\Marketing\Tests\Integration\Http\Controller\ContactControllerTest::testContactUsFileUploadFileTooBig
Error: Call to undefined function Illuminate\Http\Testing\imagecreatetruecolor()
/opt/atlassian/pipelines/agent/build/vendor/laravel/framework/src/Illuminate/Http/Testing/FileFactory.php:77
/opt/atlassian/pipelines/agent/build/vendor/laravel/framework/src/Illuminate/Support/helpers.php:263
/opt/atlassian/pipelines/agent/build/vendor/laravel/framework/src/Illuminate/Http/Testing/FileFactory.php:82
/opt/atlassian/pipelines/agent/build/vendor/laravel/framework/src/Illuminate/Http/Testing/FileFactory.php:56
/opt/atlassian/pipelines/agent/build/tests/Integration/Http/Controller/ContactControllerTest.php:95

2) Gavin\Marketing\Tests\Integration\Http\Controller\ContactControllerTest::testContactUsFileUpload
Error: Call to undefined function Illuminate\Http\Testing\imagecreatetruecolor()
/opt/atlassian/pipelines/agent/build/vendor/laravel/framework/src/Illuminate/Http/Testing/FileFactory.php:77
/opt/atlassian/pipelines/agent/build/vendor/laravel/framework/src/Illuminate/Support/helpers.php:263
/opt/atlassian/pipelines/agent/build/vendor/laravel/framework/src/Illuminate/Http/Testing/FileFactory.php:82
/opt/atlassian/pipelines/agent/build/vendor/laravel/framework/src/Illuminate/Http/Testing/FileFactory.php:56
/opt/atlassian/pipelines/agent/build/tests/Integration/Http/Controller/ContactControllerTest.php:118

The error is triggered by a unit test when a fake image file is generated by UploadedFile::fake()->image() (works locally):

/**
 * Check we get a 422 on file too large
 */
public function testContactUsFileUploadFileTooBig(): void
{
    Storage::fake('s3'); // \Illuminate\Support\Facades\Storage

    $fileNames = ['testImage1.png','testImage2.png'];

    // create some pretend images
    $fakeFiles = [];
    foreach ($fileNames as $fileName){
        // \Illuminate\Http\UploadedFile
        $fakeFile = UploadedFile::fake()->image($fileName, 100, 100)->size(1000001); // size in kb
        // ^ this is the error line tests/Integration/Http/Controller/ContactControllerTest.php
        $fakeFiles[] = $fakeFile;
    }

    // ... rest of the test ...


The gd section of php -i looks like so:

gd

GD Support => enabled
GD Version => bundled (2.1.0 compatible)
GIF Read Support => enabled
GIF Create Support => enabled
JPEG Support => enabled
libJPEG Version => 8
PNG Support => enabled
libPNG Version => 1.6.37
WBMP Support => enabled
XBM Support => enabled
BMP Support => enabled
TGA Read Support => enabled

Directive => Local Value => Master Value
gd.jpeg_ignore_warning => 1 => 1

Solution

  • Adding the entire build step script lines before every testing step 'resolved' this.

    I expect artefacts are not being cached in the build step properly for the test step to then use.