Fix: Docker build args injection regex to support service names

The regex pattern in injectDockerComposeBuildArgs() was too restrictive
and failed to match `docker compose build servicename` commands. Changed
the lookahead from `(?=\s+(?:--|-)|\s+(?:&&|\|\||;|\|)|$)` to the
simpler `(?=\s|$)` to allow any content after the build command,
including service names with hyphens/underscores and flags.

Also improved the ApplicationDeploymentJob to use the new helper function
and added comprehensive test coverage for service-specific builds.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Andras Bacsai
2025-12-01 13:16:05 +01:00
parent a56fde7f12
commit d59c75c2b2
3 changed files with 124 additions and 3 deletions

View File

@@ -1376,3 +1376,62 @@ function injectDockerComposeFlags(string $command, string $composeFilePath, stri
// Replace only first occurrence to avoid modifying comments/strings/chained commands
return preg_replace('/docker\s+compose/', $dockerComposeReplacement, $command, 1);
}
/**
* Inject build arguments right after build-related subcommands in docker/docker compose commands.
* This ensures build args are only applied to build operations, not to push, pull, up, etc.
*
* Supports:
* - docker compose build
* - docker buildx build
* - docker builder build
* - docker build (legacy)
*
* Examples:
* - Input: "docker compose -f file.yml build"
* Output: "docker compose -f file.yml build --build-arg X --build-arg Y"
*
* - Input: "docker buildx build --platform linux/amd64"
* Output: "docker buildx build --build-arg X --build-arg Y --platform linux/amd64"
*
* - Input: "docker builder build --tag myimage:latest"
* Output: "docker builder build --build-arg X --build-arg Y --tag myimage:latest"
*
* - Input: "docker compose build && docker compose push"
* Output: "docker compose build --build-arg X --build-arg Y && docker compose push"
*
* - Input: "docker compose push"
* Output: "docker compose push" (unchanged - no build command found)
*
* @param string $command The docker command
* @param string $buildArgsString The build arguments to inject (e.g., "--build-arg X --build-arg Y")
* @return string The modified command with build args injected after build subcommand
*/
function injectDockerComposeBuildArgs(string $command, string $buildArgsString): string
{
// Early return if no build args to inject
if (empty(trim($buildArgsString))) {
return $command;
}
// Match build-related commands:
// - ' builder build' (docker builder build)
// - ' buildx build' (docker buildx build)
// - ' build' (docker compose build, docker build)
// Followed by either:
// - whitespace (allowing service names, flags, or any valid arguments)
// - end of string ($)
// This regex ensures we match build subcommands, not "build" in other contexts
// IMPORTANT: Order matters - check longer patterns first (builder build, buildx build) before ' build'
$pattern = '/( builder build| buildx build| build)(?=\s|$)/';
// Replace the first occurrence of build command with build command + build-args
$modifiedCommand = preg_replace(
$pattern,
'$1 '.$buildArgsString,
$command,
1 // Only replace first occurrence
);
return $modifiedCommand ?? $command;
}