Review: Harbor URL fix (Woodpecker pushing to external Harbor URL)

review-1042-2026-04-21 Review

review ready

Verdict: APPROVED

Scope is solid. File target verified. SOP violation is real and the fix is single-line, single-file, testable. Ready to advance from backlog to next_up (this project uses backlog as the todo gate).

Template Completeness

Bug template (template-issue-bug) — all required sections present:
  • [x] Type: Bug
  • [x] Lineage (standalone, cross-referenced to service-onboarding-sop)
  • [x] Repo: forgejo_admin/notion-mcp-remote
  • [x] What Broke (with offending snippet quoted)
  • [x] Repro Steps (3 concrete steps)
  • [x] Expected Behavior (explicit target value + SOP reference)
  • [x] Environment (cluster/namespace, commit SHA, alerts state)
  • [x] Acceptance Criteria (4 items, all testable)
  • [x] Related (project, SOP, story)

Traceability

  • [x] story:ops-deploy-gitops label — GitOps Deploy via pal-e Platform
  • [x] story note verified — story-notion-mcp-remote-ops-deploy-gitops listed in project-notion-mcp-remote user-stories section. First AC on that story is literally "Woodpecker pipeline builds on push to main, pushes to internal Harbor URL" — this ticket fulfills that AC.
  • [x] arch:woodpecker label — Woodpecker CI component
  • [~] arch note — no dedicated arch-woodpecker note in pal-e-docs. Shared Woodpecker architecture is documented in arch-ci-pipeline (pal-e-platform) and the service-specific deployment wiring is in arch-deployment-notion-mcp-remote (which explicitly calls out "must use internal Harbor URL per SOP" for Woodpecker). Non-blocking — consistent with prior review precedent (see review-882-2026-04-07-v2).
  • [x] Forgejo issue — forgejo_admin/notion-mcp-remote#5, open

File Targets

  • [x] .woodpecker.yaml — verified exists at repo root. Offending value confirmed: registry: harbor.tail5b443a.ts.net.
  • [~] Line reference mismatch — issue body says .woodpecker.yaml:15 but the actual line is :22 (line 15 is ruff format --check .). Trivial — an implementing agent will find it via the quoted snippet or grep. Not worth blocking.

Repo Placement

Correct. .woodpecker.yaml lives in forgejo_admin/notion-mcp-remote, which is where the issue is filed. No multi-repo spread.

Dependencies

No blocking dependencies. This ticket is a leaf — nothing in in_progress blocks it. It logically unblocks the rest of story-ops-deploy-gitops:
  • #1043 (pal-e-services var.services entry) — wants a working CI push target
  • #1044 (pal-e-deployments kustomize overlay) — needs images in Harbor to reference
  • #1048 (another Woodpecker-tagged item) — adjacent CI work
Recommend keeping this at the head of the ops-deploy-gitops ordering.

Acceptance Criteria

All 4 AC are verifiable by an agent:
  • AC1/AC2 — grep-checkable (harbor-core.harbor.svc.cluster.local present, harbor.tail5b443a.ts.net absent in .woodpecker.yaml).
  • AC3 — requires an actual Woodpecker pipeline run on a test branch. Implementing agent should open a test branch, push, and observe the build-and-push step succeed. Note: this assumes the Woodpecker agent can resolve harbor-core.harbor.svc.cluster.local (i.e., it runs inside the cluster). That is the documented assumption per SOP; if it turns out the agent runs externally, AC3 will fail and the fix needs a different shape (e.g., a $HARBOR_INTERNAL secret). The issue already lists $HARBOR_INTERNAL as an acceptable alternative, so the scope covers this contingency.
  • AC4 — regression check on lint/test steps, observable from pipeline output.

Blast Radius

One out-of-scope reference to the external Harbor URL elsewhere in the repo:
  • k8s/deployment.yaml:23image: harbor.tail5b443a.ts.net/notion-mcp-remote/notion-mcp-remote:latest
This is the runtime image reference for the Deployment manifest (resolved by kubelet / ArgoCD Image Updater), not a CI push target. The SOP "CI registry URL" check applies only to .woodpecker.yaml. Whether deployment.yaml should also switch to the internal URL is a separate design question (depends on whether kubelet/ArgoCD can resolve cluster-internal DNS for image pulls, and on Image Updater's configured registry). Flagging as informational — do NOT expand this ticket's scope. If it needs fixing, file a separate issue.
No similar pattern in sibling repos within this project (shared infra repos out of scope).

Decomposition Assessment

1 file modified, 4 AC, estimated <5 min agent work. Well under the decomposition threshold. No decomposition needed.

Recommendation

APPROVED — no blocking changes required. Two optional polish items the implementing agent may handle inline without re-review:
  • [BODY-OPTIONAL] Update the line reference in the issue body from .woodpecker.yaml:15 to .woodpecker.yaml:22. Trivial; the quoted snippet makes the target unambiguous regardless.
  • [SCOPE-FUTURE] Consider filing a follow-up ticket to evaluate whether k8s/deployment.yaml should also use the internal Harbor URL for image pulls. Out of scope for this bug; do not bundle.
Item #1042 is ready to advance from backlog to next_up.