# Execution Plan: Optimize dedicated image build path

## Analysis

### Impact Table

| Area | Files | Expected impact | Verification |
| --- | --- | --- | --- |
| Dedicated CD workflow | `.github/workflows/dedicated-cd.yaml` | Compile the service on the Linux runner before Docker packaging, while preserving tag and deploy behavior | `sed -n '1,220p' .github/workflows/dedicated-cd.yaml` |
| Service image packaging | `deployments/docker/Dockerfile.service`, `.dockerignore` | Package `dist/dataflow` directly into the runtime image without recompiling in Docker | `sed -n '1,80p' deployments/docker/Dockerfile.service`, `sed -n '1,40p' .dockerignore` |
| Execution plan record | `docs/coding-with-agents/3306-ci-optimize-dedicated-build-path.md` | Capture assumptions, verification commands, and rollout risks in the required filename format | `ls docs/coding-with-agents` |

### Dead Code Cascade

| Symbol / behavior | Keep or remove | Reason |
| --- | --- | --- |
| Dedicated deploy trigger logic | Keep | The optimization should not alter which refs deploy |
| ECR login and repo bootstrap | Keep | Image push still depends on these steps |
| Docker Buildx setup | Remove | The workflow now packages a prebuilt local binary with plain `docker build` |
| Dockerfile builder stage | Remove | Compilation has moved to the GitHub Actions runner |

### Symbols To Keep

- Image tag resolution from git tag or commit SHA
- Runtime image base `gcr.io/pingcap-public/pingcap/alpine:alpine-3.14.6`
- Dedicated deploy job outputs consumed by `bump-version`
- The service binary output path `dist/dataflow`

### Symbols To Change

- Move Go compilation out of `deployments/docker/Dockerfile.service`
- Build and push the image as separate workflow steps
- Ensure private Go module settings are present in the actual runner build environment
- Verify the packaged binary is rebuilt for `linux/amd64` before Docker packaging
- Restore Go build cache on the runner for the new host-build path

## Execution Steps

1. Confirm the current dedicated image flow and artifact path.
   Verification:
   - `rg -n "Build service binary|Build service Latest Images|COPY ./dist/dataflow" .github/workflows/dedicated-cd.yaml deployments/docker/Dockerfile.service .dockerignore`
   Success criteria:
   - The workflow and Dockerfile references are identified before editing.

2. Keep the Dockerfile as a packaging-only runtime image and preserve the expected binary path in the build context.
   Verification:
   - `sed -n '1,40p' deployments/docker/Dockerfile.service`
   - `sed -n '1,20p' .dockerignore`
   Success criteria:
   - Docker copies `dist/dataflow` into `/dataflow`, and `.dockerignore` still exposes that artifact.

3. Update the dedicated CD workflow so the runner build can resolve private Go modules consistently.
   Verification:
   - `sed -n '20,170p' .github/workflows/dedicated-cd.yaml`
   Success criteria:
   - `GOPRIVATE` is available to the step that runs `make build-dataflow`, not only to `actions/setup-go`.
   - Git credential setup happens before `actions/setup-go`.
   - Runner Go build cache paths are restored before compiling.

4. Verify the changed path locally.
   Verification:
   - `GOOS=linux GOARCH=amd64 make build-dataflow`
   - `ls -lh dist/dataflow && file dist/dataflow`
   - `docker build -f deployments/docker/Dockerfile.service -t dataflow-service:local-optimize-test .`
   Success criteria:
   - The Linux amd64 binary is produced at `dist/dataflow`, verification prints the binary type, and the Docker image packages it successfully if Docker is available.

5. Confirm the branch contains only the intended PR fixes.
   Verification:
   - `git status --short`
   - `git diff -- .github/workflows/dedicated-cd.yaml docs/coding-with-agents/3306-ci-optimize-dedicated-build-path.md`
   Success criteria:
   - Only the workflow fix and plan-document rename/update remain in the branch.

## Risk Assessment

- Private modules may still fail to resolve if runner-global Git credentials drift.
  Mitigation:
  - Keep the explicit `git config --global url."https://${TOKEN}@github.com/".insteadOf "https://github.com/"` step and expose `GOPRIVATE` to the build command.

- The dedicated image now depends on `dist/dataflow` already existing before Docker packaging.
  Mitigation:
  - Keep `GOOS=linux GOARCH=amd64 make build-dataflow` immediately before `docker build`, remove any stale `dist/dataflow` first, and preserve `.dockerignore` inclusion for `dist/dataflow`.

- Runner behavior can differ from local macOS builds.
  Mitigation:
  - Verify with `GOOS=linux GOARCH=amd64 make build-dataflow` and `file dist/dataflow` so the produced artifact matches the Linux image runtime.
