Skip to content

Commit

Permalink
Merge pull request #218 from laravel/fix/docker-validation
Browse files Browse the repository at this point in the history
[1.x] Handles build args in Dockerfile
  • Loading branch information
nunomaduro authored Apr 17, 2023
2 parents 724e42a + 5517af1 commit 446c42b
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 14 deletions.
42 changes: 32 additions & 10 deletions src/BuildProcess/BuildContainerImage.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Laravel\VaporCli\BuildProcess;

use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use Laravel\VaporCli\Docker;
use Laravel\VaporCli\Helpers;
Expand Down Expand Up @@ -37,11 +38,18 @@ class BuildContainerImage
];

/**
* The Docker build arguments.
* The Docker CLI build arguments.
*
* @var array
*/
protected $buildArgs;
protected $cliBuildArgs;

/**
* The Docker manifest build arguments.
*
* @var array
*/
protected $manifestBuildArgs;

/**
* Create a new project builder.
Expand All @@ -50,11 +58,12 @@ class BuildContainerImage
* @param array $buildArgs
* @return void
*/
public function __construct($environment = null, $buildArgs = [])
public function __construct($environment = null, $cliBuildArgs = [], $manifestBuildArgs = [])
{
$this->baseConstructor($environment);

$this->buildArgs = $buildArgs;
$this->cliBuildArgs = $cliBuildArgs;
$this->manifestBuildArgs = $manifestBuildArgs;
}

/**
Expand All @@ -68,7 +77,16 @@ public function __invoke()
return;
}

if (! $this->validateDockerFile($this->environment, $runtime = Manifest::runtime($this->environment))) {
$buildArgs = Collection::make($this->manifestBuildArgs)
->merge(Collection::make($this->cliBuildArgs)
->mapWithKeys(function ($value) {
[$key, $value] = explode('=', $value, 2);

return [$key => $value];
})
)->toArray();

if (! $this->validateDockerFile($this->environment, $runtime = Manifest::runtime($this->environment), $buildArgs)) {
Helpers::abort('The base image used in '.Path::dockerfile($this->environment).' is incompatible with the "'.$runtime.'" runtime, or you are running an outdated version of Vapor CLI.');
}

Expand Down Expand Up @@ -97,17 +115,21 @@ protected function getTagName()
*
* @param string $environment
* @param string $runtime
* @param array $buildArgs
* @return bool
*/
public function validateDockerFile($environment, $runtime)
public function validateDockerFile($environment, $runtime, $buildArgs)
{
$contents = file_get_contents(Path::dockerfile($environment));

if (! Str::contains($contents, 'laravelphp/vapor:php')) {
// Custom image...
if (! Str::contains($contents, 'FROM laravelphp/vapor')) {
return false;
}

foreach ($buildArgs as $key => $value) {
$contents = str_replace('${'.$key.'}', $value, $contents);
}

if ($runtime === 'docker') {
foreach (static::$x86Images as $image) {
if (! Str::contains($contents, 'FROM '.$image.'-')
Expand All @@ -127,15 +149,15 @@ public function validateDockerFile($environment, $runtime)
}

/**
* Format the Docker build arguments.
* Format the Docker CLI build arguments.
*
* @return array<int, string>
*/
public function formatBuildArguments()
{
return array_merge(
['__VAPOR_RUNTIME='.Manifest::runtime($this->environment)],
array_filter($this->buildArgs, function ($value) {
array_filter($this->cliBuildArgs, function ($value) {
return ! Str::startsWith($value, '__VAPOR_RUNTIME');
})
);
Expand Down
2 changes: 1 addition & 1 deletion src/Commands/BuildCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public function handle()
new ExtractVendorToSeparateDirectory($this->argument('environment')),
new CompressApplication($this->argument('environment')),
new CompressVendor($this->argument('environment')),
new BuildContainerImage($this->argument('environment'), $this->option('build-arg')),
new BuildContainerImage($this->argument('environment'), $this->option('build-arg'), Manifest::dockerBuildArgs($this->argument('environment'))),
])->each->__invoke();

$time = (new DateTime())->diff($startedAt)->format('%im%Ss');
Expand Down
76 changes: 74 additions & 2 deletions tests/BuildContainerImageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ protected function tearDown(): void
/**
* @dataProvider runtimeProvider
*/
public function test_cannot_build_with_x86_runtime_and_arm_base_image($runtime, $dockerFileContents, $expectation)
public function test_cannot_build_with_x86_runtime_and_arm_base_image($runtime, $dockerFileContents, $buildArgs, $expectation)
{
file_put_contents($this->dockerFile, $dockerFileContents);

$this->assertSame(
$expectation,
(new BuildContainerImage('production'))->validateDockerFile('production', $runtime)
(new BuildContainerImage('production'))->validateDockerFile('production', $runtime, $buildArgs)
);
}

Expand Down Expand Up @@ -83,115 +83,187 @@ public function runtimeProvider()
[
'docker',
'FROM laravelphp/vapor:php82-arm',
[],
false,
],
[
'docker',
'FROM laravelphp/vapor:php82',
[],
true,
],
[
'docker-arm',
'FROM laravelphp/vapor:php82',
[],
false,
],
[
'docker-arm',
'FROM laravelphp/vapor:php82-arm',
[],
true,
],
[
'docker-arm',
'FROM custom/image',
[],
false,
],
[
'docker',
'FROM custom/image',
[],
false,
],
[
'docker',
'FROM custom/image'.PHP_EOL.'FROM laravelphp/vapor:php82',
[],
true,
],
[
'docker',
'FROM custom/image'.PHP_EOL.'FROM laravelphp/vapor:php82-arm',
[],
false,
],
[
'docker-arm',
'FROM custom/image'.PHP_EOL.'FROM laravelphp/vapor:php82-arm',
[],
true,
],
[
'docker-arm',
'FROM custom/image'.PHP_EOL.'FROM laravelphp/vapor:php82',
[],
false,
],
[
'docker',
'FROM custom/vapor:php82-arm',
[],
false,
],
[
'docker-arm',
'FROM custom/vapor:php82',
[],
false,
],

// End of line tests...
[
'docker',
"\r\nFROM laravelphp/vapor:php82-arm\r\n",
[],
false,
],
[
'docker',
"\nFROM laravelphp/vapor:php82-arm\n",
[],
false,
],
[
'docker',
"\nFROM laravelphp/vapor:php82-arm\n",
[],
false,
],
[
'docker-arm',
"\nFROM laravelphp/vapor:php82\n",
[],
false,
],

// PHP versions tests...
[
'docker',
'FROM laravelphp/vapor:php82',
[],
true,
],
[
'docker',
'FROM laravelphp/vapor:php83',
[],
false,
],
[
'docker-arm',
'FROM laravelphp/vapor:php82-arm',
[],
true,
],
[
'docker-arm',
'FROM laravelphp/vapor:php82-arm',
[],
true,
],
[
'docker-arm',
'FROM laravelphp/vapor:php83-arm',
[],
false,
],
[
'docker-arm',
'FROM laravelphp/vapor:php84-arm',
[],
false,
],
[
'docker-arm',
'FROM laravelphp/vapor:php84-arm',
[],
false,
],

// Build arguments
[
'docker-arm',
"ARG VERSION=php81\nFROM laravelphp/vapor:\${VERSION}-arm",
[],
false,
],
[
'docker',
"ARG VERSION=php81\nFROM laravelphp/vapor:\${VERSION}",
[],
false,
],
[
'docker-arm',
"ARG VERSION=php81\nFROM laravelphp/vapor:\${VERSION}",
['VERSION' => 'php82-arm'],
true,
],
[
'docker',
"ARG VERSION=php81\nFROM laravelphp/vapor:\${VERSION}",
['VERSION' => 'php82'],
true,
],
[
'docker-arm',
"ARG VERSION=php81\nFROM laravelphp/vapor:\${VERSION}",
['VERSION' => 'php82-arm'],
true,
],
[
'docker-arm',
"ARG VERSION=php81\nFROM laravelphp/vapor:\${VERSION}",
['VERSION' => 'php82'],
false,
],
[
'docker',
"ARG VERSION=php81\nFROM laravelphp/vapor:\${VERSION}",
['VERSION' => 'php82-arm'],
false,
],
];
Expand Down
2 changes: 1 addition & 1 deletion vapor
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ Container::setInstance($container = new Container);
/**
* Start the console application.
*/
$app = new Application('Laravel Vapor', '1.55.1');
$app = new Application('Laravel Vapor', '1.55.2');

// Authentication...
$app->add(new Commands\LoginCommand);
Expand Down

0 comments on commit 446c42b

Please sign in to comment.