fix(gitlab): populate owner/repo metadata so project-target binding lookup succeeds by AnandSundar · Pull Request #58 · amplifthq/opentag · GitHub
Skip to content

fix(gitlab): populate owner/repo metadata so project-target binding lookup succeeds - #58

Merged
mingyooagi merged 5 commits into
amplifthq:mainfrom
AnandSundar:feat/gitlab-platform
Jul 1, 2026
Merged

fix(gitlab): populate owner/repo metadata so project-target binding lookup succeeds#58
mingyooagi merged 5 commits into
amplifthq:mainfrom
AnandSundar:feat/gitlab-platform

Conversation

@AnandSundar

@AnandSundar AnandSundar commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Summary

Round 3 on PR #58. Closes the mingyooagi follow-up comment: normalizeGitLabNote was emitting metadata.repoProvider but not metadata.owner / metadata.repo, so projectTargetRefFromEvent could not resolve a ref for a GitLab event and the local daemon routed every GitLab webhook into the "No local workspace mapping is configured" branch. Source change is gitlab-only; the @opentag/core project-target helper is unchanged.

What changed, grouped by concern

Correctness

  • normalizeGitLabNote now populates metadata.owner (the leading path_with_namespace segments joined by /) and metadata.repo (the trailing project segment) alongside the existing metadata.repoProvider: "gitlab". Mirrors the github normalizer shape (packages/github/src/normalize.ts:197-204, 263-270).
  • New private helper ownerRepoFromProjectPath(pathWithNamespace) in packages/gitlab/src/normalize.ts. Splits on /; for 2+ segments, returns { owner: leading-joined, repo: trailing }. Single-segment paths return undefined, so the metadata spread is a no-op — unreachable through PROJECT_PATH_NAMESPACE_PATTERN at the ingress boundary, defensive against direct unit-call with a malformed path.

Test coverage

  • packages/gitlab/test/normalize.test.ts — new describe("owner/repo projection from projectPathWithNamespace") block with 7 cases: single-level (acme/demo), nested-group (acme/team/demo, the example from the comment), three-deep (acme/team/sub/demo), defensive single-segment omission, plus regression assertions on existing callback.threadKey (pathWithNamespace|kind|iid) and WorkItemReference.ownerContainer.id (the full pathWithNamespace).
  • packages/core/test/project-target.test.ts — 2 new cases inside the existing describe("ProjectTargetRef") block: a gitlab-shaped event resolves to a { provider: "gitlab", owner: "acme/team", repo: "demo" } ref, and a gitlab-shaped event missing owner or repo returns null.

Untouched

  • WorkItemReference.ownerContainer.id, callback.threadKey, and workItem.externalId continue to carry the full path_with_namespace. The dispatcher admission gate depends on the threadKey shape, and the WorkItemReference reshape is still deferred.
  • metadata is the only event-shape field touched. The metadata schema is Record<string, unknown>, so the new keys are pure additions.

Tests

  • 58 gitlab package tests pass (51 after round 2; added 7 in this round).
  • 10 project-target tests pass in packages/core/test/project-target.test.ts (8 after round 2; added 2 in this round).
  • pnpm -r build, pnpm -r lint, pnpm -r typecheck all green.

Why this is not a wider change

The diagnosis in the comment was specific: missing owner / repo in metadata. Reshaping WorkItemReference.ownerContainer.id to carry just the project leaf, or changing callback.threadKey to owner|repo|kind|iid, would have been a heavier change with a seed-wipe requirement — any dispatcher state on feat/gitlab-platform is keyed by threadKey. Adding the two metadata keys fixes the binding lookup without invalidating in-flight dispatches against the round-2 shape.

Plan: docs/plans/2026-06-30-003-fix-pr58-round-3-maintainer-repo-target-mapping-plan.md

Summary by CodeRabbit

  • New Features
    • Added GitLab as a supported platform, including platform ID/config validation and setup-guide generation behavior.
    • Introduced GitLab webhook ingress with token verification, note normalization, thread-action handling, and GitLab-specific rendering for run results.
    • Added GitLab URL helper utilities and a default GitLab webhook port.
  • Documentation
    • Added documentation for the GitLab integration package, including installation, usage, and authentication guidance.
  • Tests
    • Expanded test coverage for token verification, webhook ingress validation/routing, normalization, URL helpers, and GitLab rendering.

Adds @opentag/gitlab: a new adapter package for GitLab issue and
merge-request notes. Mirrors @opentag/github for normalize/render and
ships a Hono-based local webhook receiver with constant-time token
verification.

CLI: wires "gitlab" into the platforms catalog as
experimental_setup_pending (no setup wizard yet). Webhook port 3060
to avoid clash with 3050 (github).

Scope: MR creation falls back to pr:create / pr:update until the core
protocol grows MR-aware scopes.
@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new @opentag/gitlab package, which acts as a GitLab adapter helper for OpenTag, enabling the normalization of GitLab issue and merge request notes into OpenTag events and rendering GitLab-friendly callback text. It also updates the CLI to support GitLab as an experimental platform. The review feedback suggests enhancing the webhook ingress handler by adding defensive checks on the payload to prevent runtime crashes and verifying the webhook token before reading the request body to mitigate potential DoS attacks.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread packages/gitlab/src/ingress.ts Outdated
Comment thread packages/gitlab/src/ingress.ts Outdated
@AnandSundar

Copy link
Copy Markdown
Contributor Author

Hi! Before merging, I'd like to confirm the MVP scope is aligned with what you're willing to ship behind experimental_setup_pending. Three intentional narrowings in this PR:

In scope (this PR)

  • Auth: shared-secret via X-Gitlab-Token only. PAT issuance + project-hook configuration are the user's responsibility; we link to the GitLab settings page but do not automate it.
  • Events: Issue notes and Merge Request notes. Push, pipeline, issue title/body edits are ignored.
  • MR creation: falls back to the existing pr:create / pr:update scopes. The core protocol does not yet model "merge request" as distinct from "pull request", so I reused the closest matches rather than invent mr:create unilaterally. Happy to grow MR-aware scopes in @opentag/core in a follow-up if you want a clean cut there first.

Out of scope (intentionally)

  • opentag setup wizard for gitlab. Catalog entry is wired, status reflects this; full CLI onboarding comes later.
  • OAuth / user-token flow.
  • Beyond-issue/MR-note events.

Security choices worth a sanity check

  • verifyGitLabToken SHA-256-digests both inputs before timingSafeEqual so token length does not leak via the comparison.
  • startGitLabIngress binds to 127.0.0.1 by default (override available).
  • The Hono receiver binds the parsed rawBody to the note id parsed from the JSON, to reject replayed-but-mutated payloads.
  • callback.uri is rejected if its host is not api.gitlab.com. This is the MVP guard against the same machine-to-machine callback surface that bit some GitHub integrations; let me know if you want it relaxed to any allowed host list or removed in favor of caller responsibility.

Verification

  • pnpm -r build, lint, tsc -b all green.
  • packages/gitlab/: 19/19 tests passing.
  • Full vitest run shows 79 failures confined to packages/store's better-sqlite3 native bindings on Windows + Node 24 — confirmed pre-existing on main (21/21 store tests fail there too). Not caused by this branch.

Three questions before you merge:

  1. Are the three narrowings above the shape you want behind experimental_setup_pending, or should any of them move up into the first stable release?
  2. MR scopes: do you prefer pr:create / pr:update fallback now (this PR) or block on MR-aware scopes in @opentag/core first?
  3. The api.gitlab.com callback-host allowlist — keep as-is, broaden, or remove?

Thanks!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/cli/src/platforms/gitlab/display.ts`:
- Around line 11-12: The gitlabProjectWebhooksSettingsUrl helper is building a
malformed hooks link when projectPathWithNamespace includes leading or trailing
slashes. Normalize the input inside gitlabProjectWebhooksSettingsUrl by trimming
surrounding slashes before interpolating it into the GitLab hooks URL so copied
paths like /group/project produce a valid settings link.

In `@packages/gitlab/README.md`:
- Around line 24-31: The README example is using the wrong field name for
normalizeGitLabNote input, so update the example to use workItemUrl instead of
issueUrl. Keep the rest of the normalizeGitLabNote call the same, and make sure
the documented object shape matches the actual function parameters so copied
TypeScript examples align with the implementation.

In `@packages/gitlab/src/ingress.ts`:
- Around line 153-158: The claimed raw-body binding is not implemented because
handleNoteCreated only builds approval_gitlab_note_${id} and never takes
rawBody, so the action ID cannot include the request body hash. Update the
GitLab note handling flow in handleNoteCreated and its callers to accept
rawBody, derive the action id from both the note id and a hash of the raw body,
and make sure any downstream use of that id (including submitThreadAction and
related note-created handling paths) consistently uses the new value.
- Around line 247-249: The webhook handler in ingress.ts reads the request body
before validating the GitLab token, which allows unauthenticated requests to
force body buffering. Move the token check in the request handler so
verifyGitLabToken is called before c.req.text(), and only read rawBody after
authentication succeeds; keep the existing invalid_token response path in the
same handler flow.
- Around line 174-182: The threadKey in the GitLab ingress callback is ambiguous
because issues and merge requests can share the same IID, so the current
`${payload.project.path_with_namespace}#${issueIid}` format can collide. Update
the callback construction in ingress.ts to include the noteable kind alongside
the existing project path and IID, using the same isMergeRequest check already
used for noteableType so issue and MR threads are uniquely distinguished.
- Around line 264-270: The Note Hook branch in ingress should not cast payload
as GitLabNoteHookPayload without validation, because an empty signed body can
reach handleNoteCreated and crash on payload.object_attributes. Add a payload
shape check in the Note Hook / note path before calling handleNoteCreated, and
return a controlled 400 when the required note fields are missing; use the
existing handleNoteCreated and eventName branch as the place to gate this.

In `@packages/gitlab/src/normalize.ts`:
- Around line 150-154: The normalization logic in normalize.ts is missing
support for the legacy MergeRequestNote noteable type, so it gets filtered out
even though ingress accepts it. Update the isMergeRequest check in the
normalization flow to treat MergeRequestNote the same as MergeRequest, alongside
the existing IssueNote handling, so supported merge request notes are not
returned as null.
- Around line 18-19: The `projectPathWithNamespace` docstring is misleading
because `normalize.ts` expects the raw GitLab namespace path, not a URL-encoded
value. Update the comment on `projectPathWithNamespace` to describe the raw path
format (for example, `acme/demo`) and make sure any related usage in the
normalization logic reflects that this field should not be encoded before
building owner URIs or thread keys.
- Around line 207-210: The callback thread key in normalize() currently uses
only projectPathWithNamespace and iid, which can collide between issues and
merge requests. Update the callback object’s threadKey to include the work-item
kind as part of the key so it matches the ingress callback key shape, using the
existing input data in normalize() and the callback construction near the
threadKey assignment.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 75ac2e7c-5d67-48eb-bf50-c2e05da6ca7c

📥 Commits

Reviewing files that changed from the base of the PR and between a4b07a2 and ea80b8b.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (16)
  • packages/cli/src/catalogs/platforms.ts
  • packages/cli/src/config.ts
  • packages/cli/src/platforms/gitlab/display.ts
  • packages/cli/src/platforms/ports.ts
  • packages/cli/src/setup/guides.ts
  • packages/gitlab/README.md
  • packages/gitlab/package.json
  • packages/gitlab/src/index.ts
  • packages/gitlab/src/ingress.ts
  • packages/gitlab/src/normalize.ts
  • packages/gitlab/src/render.ts
  • packages/gitlab/test/ingress.test.ts
  • packages/gitlab/test/normalize.test.ts
  • packages/gitlab/test/render.test.ts
  • packages/gitlab/tsconfig.json
  • packages/gitlab/tsup.config.ts

Comment thread packages/cli/src/platforms/gitlab/display.ts Outdated
Comment thread packages/gitlab/README.md
Comment thread packages/gitlab/src/ingress.ts Outdated
Comment thread packages/gitlab/src/ingress.ts
Comment thread packages/gitlab/src/ingress.ts Outdated
Comment thread packages/gitlab/src/ingress.ts
Comment thread packages/gitlab/src/normalize.ts Outdated
Comment thread packages/gitlab/src/normalize.ts Outdated
Comment thread packages/gitlab/src/normalize.ts Outdated
Resolves the nine actionable bot comments plus the docstring-coverage
pre-merge check on PR amplifthq#58:

Correctness
- normalize.ts: gitlabWorkItem.externalId now encodes work-item kind
  (|issue|<iid> or |merge_request|<iid>) so issue #N and MR !N in
  the same project produce distinct externalIds. Same shape applied
  to callback.threadKey in normalize.ts and ingress.ts.
- normalize.ts: isMergeRequest check accepts both the modern
  "MergeRequest" and the legacy "MergeRequestNote" noteable type
  (symmetric with the existing IssueNote handling). Prevents
  silently-dropped legacy MR notes.

Hardening
- ingress.ts: added shape-predicate isGitLabNoteHookPayload that
  enforces a Content-Length cap (1 MiB -> 413 payload_too_large)
  before body read, runs the token check BEFORE c.req.text() (closes
  the unauthenticated DoS amplifier), and rejects malformed payloads
  with 422 instead of silently proceeding with synthesised
  URLs/IDs from undefined fields.
- ingress.ts: actionId now includes the first 12 hex chars of
  sha256(rawBody) for cross-package field-width uniformity with the
  dispatcher's stableHash. Reframed the comment from "replay
  protection" to the actual contract, which is idempotency for the
  apply-all decision.

Surface polish
- cli/display.ts: gitlabProjectWebhooksSettingsUrl now trims
  leading/trailing slashes from projectPathWithNamespace so
  inputs like "acme/demo/" produce "https://gitlab.com/acme/demo/-/hooks"
  rather than a double-slash.
- README + normalize.ts JSDoc: corrected issueUrl to workItemUrl in
  the README example and replaced the URL-encoded-project-path
  JSDoc with the accurate "raw slash-separated identifier" framing.

Docstring coverage
- Added JSDoc to every exported symbol in ingress.ts, normalize.ts,
  and render.ts (the index.ts barrel needs no docstrings).

Tests
- packages/cli/test/platforms/gitlab/display.test.ts: 3 slash-trim
  cases for gitlabProjectWebhooksSettingsUrl.
- packages/gitlab/test/ingress.test.ts: 5 new tests
  (token-before-body, invalid-payload 422, body-size 413,
  body-mutation changes actionId, same body same actionId,
  issue-vs-MR collision in callback.threadKey); updated 1 existing
  assertion to the new actionId shape.
- packages/gitlab/test/normalize.test.ts: 2 new tests
  (MergeRequestNote happy path, MergeRequestNote without
  mergeRequestIid falls back to issueIid) and 1 new collision test;
  updated 3 existing assertions to the new threadKey/externalId
  shape.

31/31 gitlab tests pass. pnpm -r build / lint / typecheck / test
all green.
@AnandSundar AnandSundar changed the title Add GitLab platform adapter Address inline review on @opentag/gitlab Jun 30, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/gitlab/src/ingress.ts`:
- Around line 195-217: The isGitLabNoteHookPayload guard is too permissive and
allows note payloads through that handleNoteCreated cannot safely use. Tighten
the checks in isGitLabNoteHookPayload to require every field consumed
downstream, including object_attributes.url, project.id, project.visibility,
user.username, and a valid supported-note IID/URL source, and reject payloads
that would otherwise fall back to an invalid iid value instead of passing them
through.
- Around line 170-177: The PROJECT_PATH_NAMESPACE_PATTERN in ingress.ts is too
restrictive because it only allows a single slash, so valid hierarchical
project.path_with_namespace values from GitLab webhook payloads are rejected.
Update the validation used by the path-with-namespace guard to accept nested
subgroup paths while still blocking pipe and whitespace characters, and keep the
check aligned with how WorkItemReference.ownerContainer.id and
callback.threadKey are derived.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a9c2fc1d-b566-4bde-97a9-169ec038f817

📥 Commits

Reviewing files that changed from the base of the PR and between ea80b8b and a7d425d.

📒 Files selected for processing (8)
  • packages/cli/src/platforms/gitlab/display.ts
  • packages/cli/test/platforms/gitlab/display.test.ts
  • packages/gitlab/README.md
  • packages/gitlab/src/ingress.ts
  • packages/gitlab/src/normalize.ts
  • packages/gitlab/src/render.ts
  • packages/gitlab/test/ingress.test.ts
  • packages/gitlab/test/normalize.test.ts
✅ Files skipped from review due to trivial changes (1)
  • packages/gitlab/README.md
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/cli/src/platforms/gitlab/display.ts
  • packages/gitlab/src/normalize.ts
  • packages/gitlab/src/render.ts

Comment thread packages/gitlab/src/ingress.ts Outdated
Comment thread packages/gitlab/src/ingress.ts
Round-2 PR amplifthq#58 review comments, addressed in three local changes:

Correctness
- isGitLabNoteHookPayload now requires every field handleNoteCreated reads:
  object_attributes.url, object_attributes.noteable_type, project.id,
  project.visibility (private|internal|public), and user.username.
  Signed payloads missing any of those now return 422 invalid_payload
  instead of leaking undefined into the dispatched event or collapsing
  onto an iid=0 conversation lane.

Hardening
- PROJECT_PATH_NAMESPACE_PATTERN now permits one-or-more
  slash-separated segments so nested-subgroup projects (group/sub/p)
  pass shape validation. Pipe and whitespace denials are preserved.
- handleNoteCreated returns 422 (not silent URL synthesis) when a
  supported-note payload carries iid <= 0 or a missing matching URL.

Tests
- 23 new assertions across 3 describe blocks: nested-subgroup paths,
  shape-predicate field coverage, supported-note integrity.
- 51/51 gitlab package tests pass; tsc --noEmit clean.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/gitlab/test/ingress.test.ts`:
- Around line 490-505: The test is tautological because it recomputes the
expected notes callback URL instead of checking what `createGitLabWebhookApp`
actually passed into `createRun`. Update `postNote` to return or expose the
`createRun` mock, then assert the callback URL from
`createRun.mock.calls[0]![0]` in the `ingress.test.ts` note-hook cases so
regressions in `buildApiNotesUrl` are caught.
- Around line 778-787: The merge-request fixture in this test is inconsistent
because only merge_request.url is unset while object_attributes.url still points
to the issue-note URL from supportedBase. Update the ingress test case around
postRaw in ingress.test.ts so object_attributes.url matches the merge-request
note URL, keeping the fixture aligned except for the single missing field. This
keeps the 422 assertion focused on the missing merge_request.url and avoids
unrelated URL/type consistency failures in the MergeRequest note path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8866169b-ba89-40b1-b1bf-fcb5f0548d1a

📥 Commits

Reviewing files that changed from the base of the PR and between a7d425d and b062d73.

📒 Files selected for processing (2)
  • packages/gitlab/src/ingress.ts
  • packages/gitlab/test/ingress.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/gitlab/src/ingress.ts

Comment thread packages/gitlab/test/ingress.test.ts Outdated
Comment thread packages/gitlab/test/ingress.test.ts
…teral

Two test-quality follow-ups on b062d73:

- nested-subgroup 'encodes REST callback URL' test now reads the URI
  createRun received (event.callback.uri) instead of asserting against a
  locally recomputed expectedPath() helper. The previous form was
  tautological — it proved encodeURIComponent('acme/team/demo') matches
  the hard-coded literal, not that buildApiNotesUrl() produced it.

- 'returns 422 when MR note is missing merge_request.url' test now aligns
  object_attributes.url to the MR-note URL so the only missing field is
  merge_request.url. The previous form left object_attributes.url as the
  issue-note URL, which would mask the real gap if URL/type consistency
  validation were tightened later.
@AnandSundar AnandSundar changed the title Address inline review on @opentag/gitlab fix(gitlab): close round-2 review comments on pr #58 Jun 30, 2026
@mingyooagi

mingyooagi commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Thanks for closing the previous GitLab review threads. I pulled the latest head locally, merged it onto current main (including #52), and the local gates passed for me: pnpm typecheck, pnpm test, pnpm build, and pnpm lint.

One remaining blocker before merge: the GitLab normalized event does not currently populate the repository identity fields the local daemon uses to resolve a workspace binding. normalizeGitLabNote sets metadata.repoProvider = "gitlab" and carries projectPathWithNamespace / projectId, but projectTargetRefFromEvent only resolves a repo target from metadata.owner and metadata.repo (plus optional repoProvider). As a result, a GitLab webhook can create a run, but the local daemon will not match it to a configured repository binding and will complete with the "No local workspace mapping is configured" path.

Could you add a small follow-up to bridge that mapping? Suggested shape:

  • Derive owner and repo from projectPathWithNamespace in the GitLab normalizer, e.g. acme/demo -> owner: "acme", repo: "demo", and nested groups like acme/team/demo -> owner: "acme/team", repo: "demo".
  • Include those fields in event metadata alongside repoProvider: "gitlab".
  • Add a regression test showing a normalized GitLab event resolves to a { provider: "gitlab", owner, repo } repository binding through the local-runtime/core project-target path.

I think the rest of the PR is in good shape for the current experimental adapter scope; this is the main integration gap I would want fixed before merging.

@AnandSundar

Copy link
Copy Markdown
Contributor Author

@mingyooagi Thank you for reviewing my PR. I'm working on the changes you suggested. I will update the PR soon.

…lookup

normalizeGitLabNote was emitting metadata.repoProvider + projectPathWithNamespace + projectId, but projectTargetRefFromEvent (packages/core/src/project-target.ts) only resolves a ref from metadata.owner and metadata.repo. As a result, the local daemon could not match GitLab webhooks to a configured repoBindings row and routed runs through the No local workspace mapping is configured branch.

Add a private ownerRepoFromProjectPath helper in packages/gitlab/src/normalize.ts that splits path_with_namespace on /, treating the trailing segment as the project leaf and the joined leading segments as the nested namespace owner. Wire it into the metadata block in normalizeGitLabNote so the event carries owner + repo alongside repoProvider, mirroring the github normalizer shape in packages/github/src/normalize.ts.

Existing fields stay untouched: callback.threadKey and WorkItemReference.ownerContainer.id continue to carry the full path_with_namespace (the dispatcher admission gate depends on this format, and the WorkItemReference reshape is deferred to a follow-up).

Add a new describe block in packages/gitlab/test/normalize.test.ts covering single-level, nested, three-deep paths, defensive single-segment omission, and regressions on the existing metadata fields and callback.threadKey / ownerContainer.id. Add two cases to the existing describe block in packages/core/test/project-target.test.ts: a gitlab-shaped event resolves to { provider, owner, repo } with a nested owner, and a gitlab event missing owner or repo returns null.
@AnandSundar AnandSundar changed the title fix(gitlab): close round-2 review comments on pr #58 fix(gitlab): populate owner/repo metadata so project-target binding lookup succeeds Jun 30, 2026
@AnandSundar

Copy link
Copy Markdown
Contributor Author

@mingyooagi
mingyooagi merged commit 711bdb5 into amplifthq:main Jul 1, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants