feat(cli): add custom Dockerfile flag to gordon push --build
- commit
- a33815347b0ba78801f91ca1af291e5a4b906235
- author
- brice · · 2026-02-06 15:42 UTC
- committer
- brice · · 2026-02-06 19:34 UTC
- parent
- c00c10c
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
3 files · +41 -17
M docs/cli/push.md +7 -2
| @@ -21,6 +21,7 @@ gordon push <domain> [options] | |||
| 21 | 21 | | Option | Description | | |
| 22 | 22 | |--------|-------------| | |
| 23 | 23 | | `--build` | Build the image first using `docker buildx` | | |
| 24 | + | | `-f, --file` | Path to Dockerfile (default: `./Dockerfile`, used with `--build`) | | |
| 24 | 25 | | `--platform` | Target platform for buildx (default: `linux/amd64`) | | |
| 25 | 26 | | `--build-arg` | Additional build args (repeatable, `KEY=VALUE`) | | |
| 26 | 27 | | `--tag` | Override version tag (default: `git describe --tags --abbrev=0`) | | |
| @@ -37,8 +38,9 @@ Gordon registry, pushes it, and optionally deploys it. | |||
| 37 | 38 | - The registry and repository are derived from the route image on the server. | |
| 38 | 39 | - The version tag defaults to the latest git tag. If no tag is found, `latest` | |
| 39 | 40 | is used. | |
| 40 | - | - When `--build` is set, the command uses `docker buildx build --push` and | |
| 41 | - | injects `VERSION=<tag>` plus any `--build-arg` values. | |
| 41 | + | - When `--build` is set, the command builds with `docker buildx build --load` | |
| 42 | + | and injects `VERSION=<tag>` plus any `--build-arg` values. | |
| 43 | + | - Use `-f/--file` to build from a Dockerfile outside the current directory root. | |
| 42 | 44 | - The version tag and `latest` are both pushed (unless the version is `latest`). | |
| 43 | 45 | ||
| 44 | 46 | ### Examples | |
| @@ -55,6 +57,9 @@ gordon push myapp.example.com --no-confirm | |||
| 55 | 57 | ||
| 56 | 58 | # Build for ARM and pass build args | |
| 57 | 59 | gordon push myapp.example.com --build --platform linux/arm64 --build-arg CGO_ENABLED=0 | |
| 60 | + | ||
| 61 | + | # Build from a custom Dockerfile path | |
| 62 | + | gordon push myapp.example.com --build -f docker/app/Dockerfile | |
| 58 | 63 | ``` | |
| 59 | 64 | ||
| 60 | 65 | ### Notes | |
| @@ -21,6 +21,7 @@ gordon push <domain> [options] | |||||
| 21 | | Option | Description | | 21 | | Option | Description | | ||
| 22 | |--------|-------------| | 22 | |--------|-------------| | ||
| 23 | | `--build` | Build the image first using `docker buildx` | | 23 | | `--build` | Build the image first using `docker buildx` | | ||
| 24 | + | | `-f, --file` | Path to Dockerfile (default: `./Dockerfile`, used with `--build`) | | |||
| 24 | | `--platform` | Target platform for buildx (default: `linux/amd64`) | | 25 | | `--platform` | Target platform for buildx (default: `linux/amd64`) | | ||
| 25 | | `--build-arg` | Additional build args (repeatable, `KEY=VALUE`) | | 26 | | `--build-arg` | Additional build args (repeatable, `KEY=VALUE`) | | ||
| 26 | | `--tag` | Override version tag (default: `git describe --tags --abbrev=0`) | | 27 | | `--tag` | Override version tag (default: `git describe --tags --abbrev=0`) | | ||
| @@ -37,8 +38,9 @@ Gordon registry, pushes it, and optionally deploys it. | |||||
| 37 | - The registry and repository are derived from the route image on the server. | 38 | - The registry and repository are derived from the route image on the server. | ||
| 38 | - The version tag defaults to the latest git tag. If no tag is found, `latest` | 39 | - The version tag defaults to the latest git tag. If no tag is found, `latest` | ||
| 39 | is used. | 40 | is used. | ||
| 40 | - | - When `--build` is set, the command uses `docker buildx build --push` and | 41 | + | - When `--build` is set, the command builds with `docker buildx build --load` |
| 41 | - | injects `VERSION=<tag>` plus any `--build-arg` values. | 42 | + | and injects `VERSION=<tag>` plus any `--build-arg` values. |
| 43 | + | - Use `-f/--file` to build from a Dockerfile outside the current directory root. | |||
| 42 | - The version tag and `latest` are both pushed (unless the version is `latest`). | 44 | - The version tag and `latest` are both pushed (unless the version is `latest`). | ||
| 43 | 45 | ||||
| 44 | ### Examples | 46 | ### Examples | ||
| @@ -55,6 +57,9 @@ gordon push myapp.example.com --no-confirm | |||||
| 55 | 57 | ||||
| 56 | # Build for ARM and pass build args | 58 | # Build for ARM and pass build args | ||
| 57 | gordon push myapp.example.com --build --platform linux/arm64 --build-arg CGO_ENABLED=0 | 59 | gordon push myapp.example.com --build --platform linux/arm64 --build-arg CGO_ENABLED=0 | ||
| 60 | + | ||||
| 61 | + | # Build from a custom Dockerfile path | |||
| 62 | + | gordon push myapp.example.com --build -f docker/app/Dockerfile | |||
| 58 | ``` | 63 | ``` | ||
| 59 | 64 | ||||
| 60 | ### Notes | 65 | ### Notes | ||
M internal/adapters/in/cli/push.go +24 -14
| @@ -18,12 +18,13 @@ import ( | |||
| 18 | 18 | ||
| 19 | 19 | func newPushCmd() *cobra.Command { | |
| 20 | 20 | var ( | |
| 21 | - | noDeploy bool | |
| 22 | - | noConfirm bool | |
| 23 | - | build bool | |
| 24 | - | platform string | |
| 25 | - | tag string | |
| 26 | - | buildArgs []string | |
| 21 | + | noDeploy bool | |
| 22 | + | noConfirm bool | |
| 23 | + | build bool | |
| 24 | + | platform string | |
| 25 | + | tag string | |
| 26 | + | dockerfile string | |
| 27 | + | buildArgs []string | |
| 27 | 28 | ) | |
| 28 | 29 | ||
| 29 | 30 | cmd := &cobra.Command{ | |
| @@ -41,7 +42,7 @@ Examples: | |||
| 41 | 42 | gordon push myapp.example.com --build --build-arg CGO_ENABLED=0 --remote ...`, | |
| 42 | 43 | Args: cobra.ExactArgs(1), | |
| 43 | 44 | RunE: func(cmd *cobra.Command, args []string) error { | |
| 44 | - | return runPush(cmd.Context(), args[0], tag, build, platform, buildArgs, noDeploy, noConfirm) | |
| 45 | + | return runPush(cmd.Context(), args[0], tag, build, platform, dockerfile, buildArgs, noDeploy, noConfirm) | |
| 45 | 46 | }, | |
| 46 | 47 | } | |
| 47 | 48 | ||
| @@ -49,18 +50,26 @@ Examples: | |||
| 49 | 50 | cmd.Flags().BoolVar(&noConfirm, "no-confirm", false, "Skip deploy confirmation prompt") | |
| 50 | 51 | cmd.Flags().BoolVar(&build, "build", false, "Build the image first using docker buildx") | |
| 51 | 52 | cmd.Flags().StringVar(&platform, "platform", "linux/amd64", "Target platform (used with --build)") | |
| 53 | + | cmd.Flags().StringVarP(&dockerfile, "file", "f", "", "Path to Dockerfile (default: ./Dockerfile, used with --build)") | |
| 52 | 54 | cmd.Flags().StringVar(&tag, "tag", "", "Override version tag (default: git describe)") | |
| 53 | 55 | cmd.Flags().StringArrayVar(&buildArgs, "build-arg", nil, "Additional build args (used with --build)") | |
| 54 | 56 | ||
| 55 | 57 | return cmd | |
| 56 | 58 | } | |
| 57 | 59 | ||
| 58 | - | func runPush(ctx context.Context, pushDomain, tag string, build bool, platform string, buildArgs []string, noDeploy bool, noConfirm bool) error { | |
| 60 | + | func runPush(ctx context.Context, pushDomain, tag string, build bool, platform string, dockerfile string, buildArgs []string, noDeploy bool, noConfirm bool) error { | |
| 59 | 61 | client, isRemote := GetRemoteClient() | |
| 60 | 62 | if !isRemote { | |
| 61 | 63 | return fmt.Errorf("push requires remote mode") | |
| 62 | 64 | } | |
| 63 | 65 | ||
| 66 | + | if dockerfile != "" && !build { | |
| 67 | + | return fmt.Errorf("--file can only be used with --build") | |
| 68 | + | } | |
| 69 | + | if dockerfile == "" { | |
| 70 | + | dockerfile = "Dockerfile" | |
| 71 | + | } | |
| 72 | + | ||
| 64 | 73 | route, err := client.GetRoute(ctx, pushDomain) | |
| 65 | 74 | if err != nil { | |
| 66 | 75 | return fmt.Errorf("failed to get route: %w", err) | |
| @@ -93,7 +102,7 @@ func runPush(ctx context.Context, pushDomain, tag string, build bool, platform s | |||
| 93 | 102 | } | |
| 94 | 103 | ||
| 95 | 104 | if build { | |
| 96 | - | if err := buildAndPush(ctx, version, platform, buildArgs, versionRef, latestRef); err != nil { | |
| 105 | + | if err := buildAndPush(ctx, version, platform, dockerfile, buildArgs, versionRef, latestRef); err != nil { | |
| 97 | 106 | return err | |
| 98 | 107 | } | |
| 99 | 108 | } else { | |
| @@ -122,9 +131,9 @@ func determineVersion(ctx context.Context, tag string) string { | |||
| 122 | 131 | return version | |
| 123 | 132 | } | |
| 124 | 133 | ||
| 125 | - | func buildAndPush(ctx context.Context, version, platform string, buildArgs []string, versionRef, latestRef string) error { | |
| 126 | - | if _, err := os.Stat("Dockerfile"); os.IsNotExist(err) { | |
| 127 | - | return fmt.Errorf("no Dockerfile found in current directory") | |
| 134 | + | func buildAndPush(ctx context.Context, version, platform, dockerfile string, buildArgs []string, versionRef, latestRef string) error { | |
| 135 | + | if _, err := os.Stat(dockerfile); os.IsNotExist(err) { | |
| 136 | + | return fmt.Errorf("Dockerfile not found: %s", dockerfile) | |
| 128 | 137 | } | |
| 129 | 138 | ||
| 130 | 139 | // Build and load into local daemon (NOT --push). | |
| @@ -132,7 +141,7 @@ func buildAndPush(ctx context.Context, version, platform string, buildArgs []str | |||
| 132 | 141 | // Cloudflare's 100MB per-request limit. Loading locally then | |
| 133 | 142 | // using docker push gives us chunked uploads (~5MB per request). | |
| 134 | 143 | fmt.Println("\nBuilding image...") | |
| 135 | - | buildCmd := exec.CommandContext(ctx, "docker", buildImageArgs(version, platform, buildArgs, versionRef, latestRef)...) // #nosec G204 | |
| 144 | + | buildCmd := exec.CommandContext(ctx, "docker", buildImageArgs(version, platform, dockerfile, buildArgs, versionRef, latestRef)...) // #nosec G204 | |
| 136 | 145 | buildCmd.Stdout = os.Stdout | |
| 137 | 146 | buildCmd.Stderr = os.Stderr | |
| 138 | 147 | if err := buildCmd.Run(); err != nil { | |
| @@ -155,10 +164,11 @@ func buildAndPush(ctx context.Context, version, platform string, buildArgs []str | |||
| 155 | 164 | // buildImageArgs constructs the docker buildx build arguments. | |
| 156 | 165 | // Uses --load instead of --push so the image is loaded into the local | |
| 157 | 166 | // daemon, allowing docker push to handle the upload with chunked requests. | |
| 158 | - | func buildImageArgs(version, platform string, buildArgs []string, versionRef, latestRef string) []string { | |
| 167 | + | func buildImageArgs(version, platform, dockerfile string, buildArgs []string, versionRef, latestRef string) []string { | |
| 159 | 168 | args := []string{ | |
| 160 | 169 | "buildx", "build", | |
| 161 | 170 | "--platform", platform, | |
| 171 | + | "-f", dockerfile, | |
| 162 | 172 | "-t", latestRef, | |
| 163 | 173 | "--build-arg", "VERSION=" + version, | |
| 164 | 174 | } | |
| @@ -18,12 +18,13 @@ import ( | |||||
| 18 | 18 | ||||
| 19 | func newPushCmd() *cobra.Command { | 19 | func newPushCmd() *cobra.Command { | ||
| 20 | var ( | 20 | var ( | ||
| 21 | - | noDeploy bool | 21 | + | noDeploy bool |
| 22 | - | noConfirm bool | 22 | + | noConfirm bool |
| 23 | - | build bool | 23 | + | build bool |
| 24 | - | platform string | 24 | + | platform string |
| 25 | - | tag string | 25 | + | tag string |
| 26 | - | buildArgs []string | 26 | + | dockerfile string |
| 27 | + | buildArgs []string | |||
| 27 | ) | 28 | ) | ||
| 28 | 29 | ||||
| 29 | cmd := &cobra.Command{ | 30 | cmd := &cobra.Command{ | ||
| @@ -41,7 +42,7 @@ Examples: | |||||
| 41 | gordon push myapp.example.com --build --build-arg CGO_ENABLED=0 --remote ...`, | 42 | gordon push myapp.example.com --build --build-arg CGO_ENABLED=0 --remote ...`, | ||
| 42 | Args: cobra.ExactArgs(1), | 43 | Args: cobra.ExactArgs(1), | ||
| 43 | RunE: func(cmd *cobra.Command, args []string) error { | 44 | RunE: func(cmd *cobra.Command, args []string) error { | ||
| 44 | - | return runPush(cmd.Context(), args[0], tag, build, platform, buildArgs, noDeploy, noConfirm) | 45 | + | return runPush(cmd.Context(), args[0], tag, build, platform, dockerfile, buildArgs, noDeploy, noConfirm) |
| 45 | }, | 46 | }, | ||
| 46 | } | 47 | } | ||
| 47 | 48 | ||||
| @@ -49,18 +50,26 @@ Examples: | |||||
| 49 | cmd.Flags().BoolVar(&noConfirm, "no-confirm", false, "Skip deploy confirmation prompt") | 50 | cmd.Flags().BoolVar(&noConfirm, "no-confirm", false, "Skip deploy confirmation prompt") | ||
| 50 | cmd.Flags().BoolVar(&build, "build", false, "Build the image first using docker buildx") | 51 | cmd.Flags().BoolVar(&build, "build", false, "Build the image first using docker buildx") | ||
| 51 | cmd.Flags().StringVar(&platform, "platform", "linux/amd64", "Target platform (used with --build)") | 52 | cmd.Flags().StringVar(&platform, "platform", "linux/amd64", "Target platform (used with --build)") | ||
| 53 | + | cmd.Flags().StringVarP(&dockerfile, "file", "f", "", "Path to Dockerfile (default: ./Dockerfile, used with --build)") | |||
| 52 | cmd.Flags().StringVar(&tag, "tag", "", "Override version tag (default: git describe)") | 54 | cmd.Flags().StringVar(&tag, "tag", "", "Override version tag (default: git describe)") | ||
| 53 | cmd.Flags().StringArrayVar(&buildArgs, "build-arg", nil, "Additional build args (used with --build)") | 55 | cmd.Flags().StringArrayVar(&buildArgs, "build-arg", nil, "Additional build args (used with --build)") | ||
| 54 | 56 | ||||
| 55 | return cmd | 57 | return cmd | ||
| 56 | } | 58 | } | ||
| 57 | 59 | ||||
| 58 | - | func runPush(ctx context.Context, pushDomain, tag string, build bool, platform string, buildArgs []string, noDeploy bool, noConfirm bool) error { | 60 | + | func runPush(ctx context.Context, pushDomain, tag string, build bool, platform string, dockerfile string, buildArgs []string, noDeploy bool, noConfirm bool) error { |
| 59 | client, isRemote := GetRemoteClient() | 61 | client, isRemote := GetRemoteClient() | ||
| 60 | if !isRemote { | 62 | if !isRemote { | ||
| 61 | return fmt.Errorf("push requires remote mode") | 63 | return fmt.Errorf("push requires remote mode") | ||
| 62 | } | 64 | } | ||
| 63 | 65 | ||||
| 66 | + | if dockerfile != "" && !build { | |||
| 67 | + | return fmt.Errorf("--file can only be used with --build") | |||
| 68 | + | } | |||
| 69 | + | if dockerfile == "" { | |||
| 70 | + | dockerfile = "Dockerfile" | |||
| 71 | + | } | |||
| 72 | + | ||||
| 64 | route, err := client.GetRoute(ctx, pushDomain) | 73 | route, err := client.GetRoute(ctx, pushDomain) | ||
| 65 | if err != nil { | 74 | if err != nil { | ||
| 66 | return fmt.Errorf("failed to get route: %w", err) | 75 | return fmt.Errorf("failed to get route: %w", err) | ||
| @@ -93,7 +102,7 @@ func runPush(ctx context.Context, pushDomain, tag string, build bool, platform s | |||||
| 93 | } | 102 | } | ||
| 94 | 103 | ||||
| 95 | if build { | 104 | if build { | ||
| 96 | - | if err := buildAndPush(ctx, version, platform, buildArgs, versionRef, latestRef); err != nil { | 105 | + | if err := buildAndPush(ctx, version, platform, dockerfile, buildArgs, versionRef, latestRef); err != nil { |
| 97 | return err | 106 | return err | ||
| 98 | } | 107 | } | ||
| 99 | } else { | 108 | } else { | ||
| @@ -122,9 +131,9 @@ func determineVersion(ctx context.Context, tag string) string { | |||||
| 122 | return version | 131 | return version | ||
| 123 | } | 132 | } | ||
| 124 | 133 | ||||
| 125 | - | func buildAndPush(ctx context.Context, version, platform string, buildArgs []string, versionRef, latestRef string) error { | 134 | + | func buildAndPush(ctx context.Context, version, platform, dockerfile string, buildArgs []string, versionRef, latestRef string) error { |
| 126 | - | if _, err := os.Stat("Dockerfile"); os.IsNotExist(err) { | 135 | + | if _, err := os.Stat(dockerfile); os.IsNotExist(err) { |
| 127 | - | return fmt.Errorf("no Dockerfile found in current directory") | 136 | + | return fmt.Errorf("Dockerfile not found: %s", dockerfile) |
| 128 | } | 137 | } | ||
| 129 | 138 | ||||
| 130 | // Build and load into local daemon (NOT --push). | 139 | // Build and load into local daemon (NOT --push). | ||
| @@ -132,7 +141,7 @@ func buildAndPush(ctx context.Context, version, platform string, buildArgs []str | |||||
| 132 | // Cloudflare's 100MB per-request limit. Loading locally then | 141 | // Cloudflare's 100MB per-request limit. Loading locally then | ||
| 133 | // using docker push gives us chunked uploads (~5MB per request). | 142 | // using docker push gives us chunked uploads (~5MB per request). | ||
| 134 | fmt.Println("\nBuilding image...") | 143 | fmt.Println("\nBuilding image...") | ||
| 135 | - | buildCmd := exec.CommandContext(ctx, "docker", buildImageArgs(version, platform, buildArgs, versionRef, latestRef)...) // #nosec G204 | 144 | + | buildCmd := exec.CommandContext(ctx, "docker", buildImageArgs(version, platform, dockerfile, buildArgs, versionRef, latestRef)...) // #nosec G204 |
| 136 | buildCmd.Stdout = os.Stdout | 145 | buildCmd.Stdout = os.Stdout | ||
| 137 | buildCmd.Stderr = os.Stderr | 146 | buildCmd.Stderr = os.Stderr | ||
| 138 | if err := buildCmd.Run(); err != nil { | 147 | if err := buildCmd.Run(); err != nil { | ||
| @@ -155,10 +164,11 @@ func buildAndPush(ctx context.Context, version, platform string, buildArgs []str | |||||
| 155 | // buildImageArgs constructs the docker buildx build arguments. | 164 | // buildImageArgs constructs the docker buildx build arguments. | ||
| 156 | // Uses --load instead of --push so the image is loaded into the local | 165 | // Uses --load instead of --push so the image is loaded into the local | ||
| 157 | // daemon, allowing docker push to handle the upload with chunked requests. | 166 | // daemon, allowing docker push to handle the upload with chunked requests. | ||
| 158 | - | func buildImageArgs(version, platform string, buildArgs []string, versionRef, latestRef string) []string { | 167 | + | func buildImageArgs(version, platform, dockerfile string, buildArgs []string, versionRef, latestRef string) []string { |
| 159 | args := []string{ | 168 | args := []string{ | ||
| 160 | "buildx", "build", | 169 | "buildx", "build", | ||
| 161 | "--platform", platform, | 170 | "--platform", platform, | ||
| 171 | + | "-f", dockerfile, | |||
| 162 | "-t", latestRef, | 172 | "-t", latestRef, | ||
| 163 | "--build-arg", "VERSION=" + version, | 173 | "--build-arg", "VERSION=" + version, | ||
| 164 | } | 174 | } | ||
M internal/adapters/in/cli/push_test.go +10 -1
| @@ -63,9 +63,18 @@ func TestParseImageRef(t *testing.T) { | |||
| 63 | 63 | ||
| 64 | 64 | func TestBuildAndPush_BuildArgs(t *testing.T) { | |
| 65 | 65 | // Verify buildImageArgs produces --load instead of --push | |
| 66 | - | args := buildImageArgs("v1.0.0", "linux/amd64", []string{"CGO_ENABLED=0"}, "reg.example.com/app:v1.0.0", "reg.example.com/app:latest") | |
| 66 | + | args := buildImageArgs("v1.0.0", "linux/amd64", "Dockerfile", []string{"CGO_ENABLED=0"}, "reg.example.com/app:v1.0.0", "reg.example.com/app:latest") | |
| 67 | 67 | ||
| 68 | 68 | assert.Contains(t, args, "--load") | |
| 69 | 69 | assert.NotContains(t, args, "--push") | |
| 70 | 70 | assert.Contains(t, args, "--platform") | |
| 71 | + | assert.Contains(t, args, "-f") | |
| 72 | + | assert.Contains(t, args, "Dockerfile") | |
| 73 | + | } | |
| 74 | + | ||
| 75 | + | func TestBuildImageArgs_CustomDockerfile(t *testing.T) { | |
| 76 | + | args := buildImageArgs("v1.0.0", "linux/amd64", "docker/app/Dockerfile", nil, "reg.example.com/app:v1.0.0", "reg.example.com/app:latest") | |
| 77 | + | ||
| 78 | + | assert.Contains(t, args, "-f") | |
| 79 | + | assert.Contains(t, args, "docker/app/Dockerfile") | |
| 71 | 80 | } | |
| @@ -63,9 +63,18 @@ func TestParseImageRef(t *testing.T) { | |||||
| 63 | 63 | ||||
| 64 | func TestBuildAndPush_BuildArgs(t *testing.T) { | 64 | func TestBuildAndPush_BuildArgs(t *testing.T) { | ||
| 65 | // Verify buildImageArgs produces --load instead of --push | 65 | // Verify buildImageArgs produces --load instead of --push | ||
| 66 | - | args := buildImageArgs("v1.0.0", "linux/amd64", []string{"CGO_ENABLED=0"}, "reg.example.com/app:v1.0.0", "reg.example.com/app:latest") | 66 | + | args := buildImageArgs("v1.0.0", "linux/amd64", "Dockerfile", []string{"CGO_ENABLED=0"}, "reg.example.com/app:v1.0.0", "reg.example.com/app:latest") |
| 67 | 67 | ||||
| 68 | assert.Contains(t, args, "--load") | 68 | assert.Contains(t, args, "--load") | ||
| 69 | assert.NotContains(t, args, "--push") | 69 | assert.NotContains(t, args, "--push") | ||
| 70 | assert.Contains(t, args, "--platform") | 70 | assert.Contains(t, args, "--platform") | ||
| 71 | + | assert.Contains(t, args, "-f") | |||
| 72 | + | assert.Contains(t, args, "Dockerfile") | |||
| 73 | + | } | |||
| 74 | + | ||||
| 75 | + | func TestBuildImageArgs_CustomDockerfile(t *testing.T) { | |||
| 76 | + | args := buildImageArgs("v1.0.0", "linux/amd64", "docker/app/Dockerfile", nil, "reg.example.com/app:v1.0.0", "reg.example.com/app:latest") | |||
| 77 | + | ||||
| 78 | + | assert.Contains(t, args, "-f") | |||
| 79 | + | assert.Contains(t, args, "docker/app/Dockerfile") | |||
| 71 | } | 80 | } | ||