Skip to content

feat(trogon-source-gitlab): scaffold GitLab webhook source#99

Merged
yordis merged 1 commit into
mainfrom
yordis/gitlab-source-scaffold
Apr 6, 2026
Merged

feat(trogon-source-gitlab): scaffold GitLab webhook source#99
yordis merged 1 commit into
mainfrom
yordis/gitlab-source-scaffold

Conversation

@yordis

@yordis yordis commented Apr 5, 2026

Copy link
Copy Markdown
Member

Summary

  • GitLab webhook receiver that validates X-Gitlab-Token (shared secret, constant-time comparison) and publishes events to NATS JetStream
  • Follows established source patterns: NatsToken-validated config, DLQ/unroutable with X-GitLab-Reject-Reason header, body size limiting, health check endpoint
  • Includes Docker Compose service, Dockerfile, ngrok tunnel, and local development README

Co-authored-by: Zach Bruhnke zach@ordinary.company
Co-authored-by: Dave dave@bruhnke.us

@cursor

cursor Bot commented Apr 5, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Medium risk: introduces a new externally-facing webhook ingestion service and JetStream publishing path, where misconfiguration or header/token handling could drop or misroute events.

Overview
Adds a new trogon-source-gitlab Rust service that receives GitLab webhooks, validates X-Gitlab-Token, normalizes X-GitLab-Event into NATS-safe subjects, and publishes the raw payload to NATS JetStream with relevant headers and optional dedup via Idempotency-Key.

Wires the new service into local Docker Compose (env template, service definition, healthcheck, and an ngrok tunnel), and extends acp-telemetry service naming plus lockfile dependencies to include the new binary.

Reviewed by Cursor Bugbot for commit 131fc3f. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitai Bot commented Apr 5, 2026

Copy link
Copy Markdown

Walkthrough

Adds a new GitLab webhook source: a Rust crate with HTTP webhook server, signature verification, JetStream publishing and provisioning, Docker Compose service and Dockerfile, ngrok integration, config/constants, telemetry enum update, and accompanying docs and tests.

Changes

Cohort / File(s) Summary
Compose & env
devops/docker/compose/.env.example, devops/docker/compose/compose.yml
Added commented GitLab env placeholders and new trogon-source-gitlab service; ngrok updated to expose a GitLab tunnel and wait for the new service health.
Dockerfile
devops/docker/compose/services/trogon-source-gitlab/Dockerfile
New multi-stage Dockerfile using cargo-chef to build and produce a minimal runtime image for trogon-source-gitlab.
Docs
devops/docker/compose/services/trogon-source-gitlab/README.md
New README documenting local ngrok-based webhook setup, env vars, and NATS subscription verification.
Crate manifest
rsworkspace/crates/trogon-source-gitlab/Cargo.toml
New crate manifest declaring binary target and dependencies.
Configuration & constants
rsworkspace/crates/trogon-source-gitlab/src/config.rs, rsworkspace/crates/trogon-source-gitlab/src/constants.rs
New GitlabConfig::from_env with parsing/validation/defaults and compile-time defaults/header constants.
Core crate wiring
rsworkspace/crates/trogon-source-gitlab/src/lib.rs, rsworkspace/crates/trogon-source-gitlab/src/main.rs
Crate module exports, binary entrypoint (connects to NATS, starts server), and telemetry initialization.
Server implementation
rsworkspace/crates/trogon-source-gitlab/src/server.rs
Full Axum server: JetStream provisioning, router (/webhook, /health), signature validation, event normalization, DLQ behavior, publish headers, graceful shutdown, and extensive tests.
Signature & secret types
rsworkspace/crates/trogon-source-gitlab/src/signature.rs, rsworkspace/crates/trogon-source-gitlab/src/webhook_secret.rs
Added constant-time token verification with errors, and WebhookSecret type with validation, redacted Debug, and error type.
Telemetry enum
rsworkspace/crates/acp-telemetry/src/service_name.rs
Added TrogonSourceGitlab variant and mapping to "trogon-source-gitlab" with tests.

Sequence Diagram(s)

sequenceDiagram
    participant GitLab
    participant Ngrok
    participant Webhook as Trogon\nWebhook Server
    participant Signature as Signature\nVerifier
    participant JetStream as NATS\nJetStream
    participant DLQ as DLQ Topic

    GitLab->>Ngrok: POST /webhook (public URL)
    Ngrok->>Webhook: Forward POST /webhook
    Webhook->>Signature: verify(x-gitlab-token)
    alt token valid
        Signature-->>Webhook: ok
        Webhook->>Webhook: extract & normalize event
        alt event valid
            Webhook->>JetStream: Publish to gitlab.{event} (with headers)
            JetStream-->>Webhook: ack
            Webhook-->>GitLab: 200 OK
        else event invalid
            Webhook->>DLQ: Publish to gitlab.unroutable (with reject header)
            DLQ-->>Webhook: ack
            Webhook-->>GitLab: 200 OK
        end
    else token missing/invalid
        Signature-->>Webhook: err
        Webhook-->>GitLab: 401 Unauthorized
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • PR #79: Adds an analogous webhook-source crate (GitHub) with similar module layout and compose changes — closely matches structure and patterns used here.
  • PR #65: Introduces JetStream traits and NatsJetStream client abstractions that this crate depends on for provisioning and publishing.
  • PR #4: Adds foundational NATS abstractions/types (trogon-nats) used by the new GitLab source crate.

Suggested labels

rust:coverage-baseline-reset

Poem

🐰
I hopped through tunnels, secret and neat,
Tokens checked, events tidy and sweet;
To NATS I bounced each payload light,
Streams provisioned through day and night —
Hooray! The GitLab webhooks take flight.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 70.83% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(trogon-source-gitlab): scaffold GitLab webhook source' clearly and concisely describes the main change—introducing a new GitLab webhook source module with all necessary infrastructure.
Description check ✅ Passed The description is well-related to the changeset, covering the GitLab webhook receiver implementation, security features, established patterns, and developer tooling, all of which are reflected in the file changes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch yordis/gitlab-source-scaffold

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@yordis yordis force-pushed the yordis/gitlab-source-scaffold branch from 13023c5 to c94e918 Compare April 5, 2026 23:37
@github-actions

github-actions Bot commented Apr 5, 2026

Copy link
Copy Markdown

badge

Code Coverage Summary

Details
Filename                                                                      Stmts    Miss  Cover    Missing
--------------------------------------------------------------------------  -------  ------  -------  ---------------------------------------------------------------------------------------------
crates/trogon-std/src/time/system.rs                                             27       3  88.89%   27-29
crates/trogon-std/src/time/mock.rs                                              129       0  100.00%
crates/acp-nats/src/req_id.rs                                                    39       0  100.00%
crates/acp-nats/src/ext_method_name.rs                                           70       0  100.00%
crates/acp-nats/src/acp_prefix.rs                                                51       0  100.00%
crates/acp-nats/src/client_proxy.rs                                             200       0  100.00%
crates/acp-nats/src/error.rs                                                     84       0  100.00%
crates/acp-nats/src/lib.rs                                                       73       0  100.00%
crates/acp-nats/src/pending_prompt_waiters.rs                                   141       0  100.00%
crates/acp-nats/src/config.rs                                                   204       0  100.00%
crates/acp-nats/src/jsonrpc.rs                                                    6       0  100.00%
crates/acp-nats/src/in_flight_slot_guard.rs                                      32       0  100.00%
crates/acp-nats/src/session_id.rs                                                72       0  100.00%
crates/acp-nats/src/nats/subjects/subscriptions/global_all.rs                    11       0  100.00%
crates/acp-nats/src/nats/subjects/subscriptions/one_agent.rs                     18       0  100.00%
crates/acp-nats/src/nats/subjects/subscriptions/one_client.rs                    18       0  100.00%
crates/acp-nats/src/nats/subjects/subscriptions/all_agent_ext.rs                 11       0  100.00%
crates/acp-nats/src/nats/subjects/subscriptions/one_session.rs                   18       0  100.00%
crates/acp-nats/src/nats/subjects/subscriptions/all_agent.rs                     11       0  100.00%
crates/acp-nats/src/nats/subjects/subscriptions/prompt_wildcard.rs               11       0  100.00%
crates/acp-nats/src/nats/subjects/subscriptions/all_session.rs                   11       0  100.00%
crates/acp-nats/src/nats/subjects/subscriptions/all_client.rs                    11       0  100.00%
crates/trogon-nats/src/nats_token.rs                                            161       0  100.00%
crates/trogon-nats/src/token.rs                                                   8       0  100.00%
crates/trogon-nats/src/auth.rs                                                  119       0  100.00%
crates/trogon-nats/src/connect.rs                                               105      11  89.52%   22-24, 37, 49, 68-73
crates/trogon-nats/src/messaging.rs                                             552       2  99.64%   132, 142
crates/trogon-nats/src/client.rs                                                 25      25  0.00%    50-89
crates/trogon-nats/src/mocks.rs                                                 304       0  100.00%
crates/trogon-source-linear/src/signature.rs                                     54       1  98.15%   16
crates/trogon-source-linear/src/main.rs                                           4       0  100.00%
crates/trogon-source-linear/src/server.rs                                       351       3  99.15%   175-177
crates/trogon-source-linear/src/config.rs                                       208       0  100.00%
crates/trogon-source-gitlab/src/config.rs                                       115       0  100.00%
crates/trogon-source-gitlab/src/server.rs                                       439       0  100.00%
crates/trogon-source-gitlab/src/webhook_secret.rs                                36       0  100.00%
crates/trogon-source-gitlab/src/signature.rs                                     30       0  100.00%
crates/trogon-source-gitlab/src/main.rs                                           4       0  100.00%
crates/acp-nats/src/nats/subjects/global/initialize.rs                            8       0  100.00%
crates/acp-nats/src/nats/subjects/global/logout.rs                                8       0  100.00%
crates/acp-nats/src/nats/subjects/global/authenticate.rs                          8       0  100.00%
crates/acp-nats/src/nats/subjects/global/ext.rs                                  12       0  100.00%
crates/acp-nats/src/nats/subjects/global/ext_notify.rs                           12       0  100.00%
crates/acp-nats/src/nats/subjects/global/session_list.rs                          8       0  100.00%
crates/acp-nats/src/nats/subjects/global/session_new.rs                           8       0  100.00%
crates/acp-nats-agent/src/connection.rs                                        1434       1  99.93%   686
crates/acp-nats/src/client/ext.rs                                               365       8  97.81%   193-204, 229-240
crates/acp-nats/src/client/terminal_output.rs                                   223       0  100.00%
crates/acp-nats/src/client/terminal_release.rs                                  357       0  100.00%
crates/acp-nats/src/client/fs_read_text_file.rs                                 384       0  100.00%
crates/acp-nats/src/client/mod.rs                                              2987       0  100.00%
crates/acp-nats/src/client/request_permission.rs                                338       0  100.00%
crates/acp-nats/src/client/terminal_create.rs                                   294       0  100.00%
crates/acp-nats/src/client/rpc_reply.rs                                          71       0  100.00%
crates/acp-nats/src/client/terminal_wait_for_exit.rs                            396       0  100.00%
crates/acp-nats/src/client/ext_session_prompt_response.rs                       157       0  100.00%
crates/acp-nats/src/client/fs_write_text_file.rs                                451       0  100.00%
crates/acp-nats/src/client/session_update.rs                                     55       0  100.00%
crates/acp-nats/src/client/terminal_kill.rs                                     309       0  100.00%
crates/acp-nats/src/nats/extensions.rs                                            3       0  100.00%
crates/acp-nats/src/nats/mod.rs                                                  23       0  100.00%
crates/acp-nats/src/nats/parsing.rs                                             285       1  99.65%   153
crates/trogon-source-slack/src/config.rs                                        163       0  100.00%
crates/trogon-source-slack/src/server.rs                                        925       3  99.68%   119-121
crates/trogon-source-slack/src/main.rs                                            4       0  100.00%
crates/trogon-source-slack/src/signature.rs                                      80       0  100.00%
crates/acp-nats-stdio/src/config.rs                                              72       0  100.00%
crates/acp-nats-stdio/src/main.rs                                               141      27  80.85%   62, 114-121, 127-129, 146, 177-198
crates/trogon-std/src/args.rs                                                    10       0  100.00%
crates/trogon-std/src/json.rs                                                    30       0  100.00%
crates/trogon-std/src/dirs/system.rs                                             98      11  88.78%   57, 65, 67, 75, 77, 85, 87, 96, 98, 109, 154
crates/trogon-std/src/dirs/fixed.rs                                              84       0  100.00%
crates/acp-nats-ws/src/config.rs                                                 83       0  100.00%
crates/acp-nats-ws/src/upgrade.rs                                                57       2  96.49%   59, 90
crates/acp-nats-ws/src/connection.rs                                            166      35  78.92%   75-82, 87-98, 114, 116-117, 122, 133-135, 142, 146, 150, 153-161, 172, 176, 179, 182-186, 220
crates/acp-nats-ws/src/main.rs                                                  187      18  90.37%   87, 204-225, 303
crates/acp-nats/src/jetstream/provision.rs                                       61       0  100.00%
crates/acp-nats/src/jetstream/consumers.rs                                       99       0  100.00%
crates/acp-nats/src/jetstream/streams.rs                                        194       4  97.94%   254-256, 266
crates/acp-nats/src/jetstream/ext_policy.rs                                      26       0  100.00%
crates/acp-nats/src/nats/subjects/client_ops/terminal_kill.rs                    15       0  100.00%
crates/acp-nats/src/nats/subjects/client_ops/session_request_permission.rs       15       0  100.00%
crates/acp-nats/src/nats/subjects/client_ops/terminal_release.rs                 15       0  100.00%
crates/acp-nats/src/nats/subjects/client_ops/terminal_wait_for_exit.rs           15       0  100.00%
crates/acp-nats/src/nats/subjects/client_ops/terminal_output.rs                  15       0  100.00%
crates/acp-nats/src/nats/subjects/client_ops/fs_read_text_file.rs                15       0  100.00%
crates/acp-nats/src/nats/subjects/client_ops/fs_write_text_file.rs               15       0  100.00%
crates/acp-nats/src/nats/subjects/client_ops/session_update.rs                   15       0  100.00%
crates/acp-nats/src/nats/subjects/client_ops/terminal_create.rs                  15       0  100.00%
crates/acp-nats/src/nats/subjects/mod.rs                                        380       0  100.00%
crates/acp-nats/src/nats/subjects/stream.rs                                      58       0  100.00%
crates/acp-nats/src/nats/subjects/responses/cancelled.rs                         18       0  100.00%
crates/acp-nats/src/nats/subjects/responses/response.rs                          20       0  100.00%
crates/acp-nats/src/nats/subjects/responses/update.rs                            27       0  100.00%
crates/acp-nats/src/nats/subjects/responses/prompt_response.rs                   27       0  100.00%
crates/acp-nats/src/nats/subjects/responses/ext_ready.rs                         15       0  100.00%
crates/acp-nats/src/agent/set_session_config_option.rs                           71       0  100.00%
crates/acp-nats/src/agent/cancel.rs                                             105       0  100.00%
crates/acp-nats/src/agent/test_support.rs                                       299       0  100.00%
crates/acp-nats/src/agent/initialize.rs                                          83       0  100.00%
crates/acp-nats/src/agent/set_session_model.rs                                   71       0  100.00%
crates/acp-nats/src/agent/mod.rs                                                 65       0  100.00%
crates/acp-nats/src/agent/load_session.rs                                       101       0  100.00%
crates/acp-nats/src/agent/resume_session.rs                                     102       0  100.00%
crates/acp-nats/src/agent/authenticate.rs                                        52       0  100.00%
crates/acp-nats/src/agent/ext_notification.rs                                    88       0  100.00%
crates/acp-nats/src/agent/list_sessions.rs                                       50       0  100.00%
crates/acp-nats/src/agent/js_request.rs                                         304       0  100.00%
crates/acp-nats/src/agent/prompt.rs                                             633       0  100.00%
crates/acp-nats/src/agent/fork_session.rs                                       106       0  100.00%
crates/acp-nats/src/agent/new_session.rs                                         91       0  100.00%
crates/acp-nats/src/agent/ext_method.rs                                          92       0  100.00%
crates/acp-nats/src/agent/set_session_mode.rs                                    71       0  100.00%
crates/acp-nats/src/agent/close_session.rs                                       67       0  100.00%
crates/acp-nats/src/agent/bridge.rs                                             123       4  96.75%   109-112
crates/acp-nats/src/agent/logout.rs                                              49       0  100.00%
crates/acp-nats/src/telemetry/metrics.rs                                         65       0  100.00%
crates/acp-telemetry/src/signal.rs                                                3       3  0.00%    4-43
crates/acp-telemetry/src/log.rs                                                  70       2  97.14%   39-40
crates/acp-telemetry/src/service_name.rs                                         36       0  100.00%
crates/acp-telemetry/src/lib.rs                                                 153      22  85.62%   39-46, 81, 86, 91, 105-120
crates/acp-telemetry/src/metric.rs                                               35       4  88.57%   30-31, 38-39
crates/acp-telemetry/src/trace.rs                                                32       4  87.50%   23-24, 31-32
crates/trogon-nats/src/jetstream/mocks.rs                                       474       0  100.00%
crates/trogon-nats/src/jetstream/publish.rs                                      57       0  100.00%
crates/trogon-source-github/src/server.rs                                       368       0  100.00%
crates/trogon-source-github/src/signature.rs                                     64       0  100.00%
crates/trogon-source-github/src/config.rs                                       104       0  100.00%
crates/trogon-source-github/src/main.rs                                           4       0  100.00%
crates/trogon-std/src/env/in_memory.rs                                           81       0  100.00%
crates/trogon-std/src/env/system.rs                                              17       0  100.00%
crates/trogon-std/src/fs/mem.rs                                                 220      10  95.45%   61-63, 77-79, 133-135, 158
crates/trogon-std/src/fs/system.rs                                               29      12  58.62%   17-19, 31-45
crates/acp-nats/src/nats/subjects/commands/prompt.rs                             18       0  100.00%
crates/acp-nats/src/nats/subjects/commands/set_mode.rs                           18       0  100.00%
crates/acp-nats/src/nats/subjects/commands/resume.rs                             18       0  100.00%
crates/acp-nats/src/nats/subjects/commands/load.rs                               18       0  100.00%
crates/acp-nats/src/nats/subjects/commands/set_model.rs                          18       0  100.00%
crates/acp-nats/src/nats/subjects/commands/close.rs                              18       0  100.00%
crates/acp-nats/src/nats/subjects/commands/fork.rs                               18       0  100.00%
crates/acp-nats/src/nats/subjects/commands/set_config_option.rs                  18       0  100.00%
crates/acp-nats/src/nats/subjects/commands/cancel.rs                             18       0  100.00%
TOTAL                                                                         19716     216  98.90%

Diff against main

Filename                                             Stmts    Miss  Cover
-------------------------------------------------  -------  ------  --------
crates/trogon-source-gitlab/src/config.rs             +115       0  +100.00%
crates/trogon-source-gitlab/src/server.rs             +439       0  +100.00%
crates/trogon-source-gitlab/src/webhook_secret.rs      +36       0  +100.00%
crates/trogon-source-gitlab/src/signature.rs           +30       0  +100.00%
crates/trogon-source-gitlab/src/main.rs                 +4       0  +100.00%
crates/acp-telemetry/src/service_name.rs                +5       0  +100.00%
TOTAL                                                 +629       0  +0.04%

Results for commit: 131fc3f

Minimum allowed coverage is 95%

♻️ This comment has been updated with latest results

@yordis yordis force-pushed the yordis/gitlab-source-scaffold branch 3 times, most recently from 3a2fa6b to b704ca8 Compare April 5, 2026 23:48
Comment thread rsworkspace/crates/trogon-source-gitlab/src/signature.rs Outdated
Comment thread rsworkspace/crates/trogon-source-gitlab/src/config.rs
@yordis yordis force-pushed the yordis/gitlab-source-scaffold branch from b704ca8 to f15680e Compare April 5, 2026 23:59
Comment thread devops/docker/compose/.env.example

@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

🧹 Nitpick comments (2)
devops/docker/compose/services/trogon-source-gitlab/README.md (1)

53-55: Consider using a more portable NATS address in the example.

The nats.trogonai.orb.local hostname appears to be OrbStack-specific and won't resolve for users running Docker Compose without OrbStack. Consider using localhost:4222 (with appropriate port mapping) or documenting that this address is specific to OrbStack environments.

Suggested change
 ```bash
-nats sub -s nats://nats.trogonai.orb.local:4222 "gitlab.>"
+nats sub -s nats://localhost:4222 "gitlab.>"
Note: This requires exposing port 4222 from the nats container, or you can document the OrbStack-specific hostname usage.
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @devops/docker/compose/services/trogon-source-gitlab/README.md around lines
53 - 55, Update the example NATS command string "nats sub -s
nats://nats.trogonai.orb.local:4222 "gitlab.>"" to use a portable address
(e.g., change to "nats://localhost:4222") and either document that this requires
exposing port 4222 from the nats container or explicitly note that the original
hostname is OrbStack-specific; modify the README example and accompanying note
to mention the port-mapping requirement or the OrbStack-only hostname so users
know which option applies.


</details>

</blockquote></details>
<details>
<summary>devops/docker/compose/.env.example (1)</summary><blockquote>

`19-19`: **Inconsistent timeout unit naming across services.**

`GITLAB_NATS_ACK_TIMEOUT_MS` uses milliseconds (matching Linear), while GitHub and Slack use `_SECS` suffix. The default value of `10000` is correct (10 seconds), but the naming inconsistency could cause confusion when configuring multiple services.

Consider aligning on one convention across all sources for maintainability.

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @devops/docker/compose/.env.example at line 19, Summary: The environment
variable name GITLAB_NATS_ACK_TIMEOUT_MS is inconsistent with GitHub/Slack which
use a _SECS suffix; align naming and default units across services. Fix: rename
GITLAB_NATS_ACK_TIMEOUT_MS to GITLAB_NATS_ACK_TIMEOUT_SECS in the .env.example
(and any env files) and change its default from 10000 to 10, or alternatively
convert the other services to _MS—pick the seconds convention to match
GitHub/Slack; then update all code references that read the variable (search for
GITLAB_NATS_ACK_TIMEOUT_MS) to use GITLAB_NATS_ACK_TIMEOUT_SECS and ensure
parsing treats the value as seconds (adjust any parseInt/timeout multipliers
accordingly). Ensure documentation and README mention the chosen unit.


</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>🤖 Prompt for all review comments with AI agents</summary>

Verify each finding against the current code and only fix it if needed.

Inline comments:
In @rsworkspace/crates/trogon-source-gitlab/src/config.rs:

  • Around line 13-22: GitlabConfig currently stores webhook_secret as a raw
    String and performs multi-field validation at aggregate construction; create a
    domain value object (e.g., WebhookSecret) that encapsulates the secret string
    and performs its own validation via TryFrom<&str> or a
    WebhookSecret::try_from_str / WebhookSecret::new returning Result, then change
    GitlabConfig::new (or the struct field) to use WebhookSecret instead of String
    and remove webhook-specific validation from the aggregate constructor so only
    cross-field invariants remain in GitlabConfig creation; update any uses of
    GitlabConfig::webhook_secret to call WebhookSecret.as_str() (or similar) where
    raw string is needed.

In @rsworkspace/crates/trogon-source-gitlab/src/server.rs:

  • Around line 140-142: Replace the unchecked cast config.max_body_size.as_u64()
    as usize with an explicit conversion using
    usize::try_from(config.max_body_size.as_u64()) and handle the Result instead of
    casting; update the call site that constructs RequestBodyLimitLayer::new(...) to
    pass the converted usize (or return/log a clear error or apply a safe fallback)
    so overflow is detected and handled – look for RequestBodyLimitLayer::new and
    config.max_body_size.as_u64() in server.rs and ensure the TryFrom error is
    propagated or handled rather than using a raw as cast.

Nitpick comments:
In @devops/docker/compose/.env.example:

  • Line 19: Summary: The environment variable name GITLAB_NATS_ACK_TIMEOUT_MS is
    inconsistent with GitHub/Slack which use a _SECS suffix; align naming and
    default units across services. Fix: rename GITLAB_NATS_ACK_TIMEOUT_MS to
    GITLAB_NATS_ACK_TIMEOUT_SECS in the .env.example (and any env files) and change
    its default from 10000 to 10, or alternatively convert the other services to
    _MS—pick the seconds convention to match GitHub/Slack; then update all code
    references that read the variable (search for GITLAB_NATS_ACK_TIMEOUT_MS) to use
    GITLAB_NATS_ACK_TIMEOUT_SECS and ensure parsing treats the value as seconds
    (adjust any parseInt/timeout multipliers accordingly). Ensure documentation and
    README mention the chosen unit.

In @devops/docker/compose/services/trogon-source-gitlab/README.md:

  • Around line 53-55: Update the example NATS command string "nats sub -s
    nats://nats.trogonai.orb.local:4222 "gitlab.>"" to use a portable address
    (e.g., change to "nats://localhost:4222") and either document that this requires
    exposing port 4222 from the nats container or explicitly note that the original
    hostname is OrbStack-specific; modify the README example and accompanying note
    to mention the port-mapping requirement or the OrbStack-only hostname so users
    know which option applies.

</details>

<details>
<summary>🪄 Autofix (Beta)</summary>

Fix all unresolved CodeRabbit comments on this PR:

- [ ] <!-- {"checkboxId": "4b0d0e0a-96d7-4f10-b296-3a18ea78f0b9"} --> Push a commit to this branch (recommended)
- [ ] <!-- {"checkboxId": "ff5b1114-7d8c-49e6-8ac1-43f82af23a33"} --> Create a new PR with the fixes

</details>

---

<details>
<summary>ℹ️ Review info</summary>

<details>
<summary>⚙️ Run configuration</summary>

**Configuration used**: Organization UI

**Review profile**: CHILL

**Plan**: Pro

**Run ID**: `26a3d023-db71-4f09-8363-137206da5e8b`

</details>

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 1c17914cc34739a36d373de8eb28590e86884358 and f15680eba3ece68d983b35fecaea4a9d676c490d.

</details>

<details>
<summary>⛔ Files ignored due to path filters (1)</summary>

* `rsworkspace/Cargo.lock` is excluded by `!**/*.lock`

</details>

<details>
<summary>📒 Files selected for processing (12)</summary>

* `devops/docker/compose/.env.example`
* `devops/docker/compose/compose.yml`
* `devops/docker/compose/services/trogon-source-gitlab/Dockerfile`
* `devops/docker/compose/services/trogon-source-gitlab/README.md`
* `rsworkspace/crates/acp-telemetry/src/service_name.rs`
* `rsworkspace/crates/trogon-source-gitlab/Cargo.toml`
* `rsworkspace/crates/trogon-source-gitlab/src/config.rs`
* `rsworkspace/crates/trogon-source-gitlab/src/constants.rs`
* `rsworkspace/crates/trogon-source-gitlab/src/lib.rs`
* `rsworkspace/crates/trogon-source-gitlab/src/main.rs`
* `rsworkspace/crates/trogon-source-gitlab/src/server.rs`
* `rsworkspace/crates/trogon-source-gitlab/src/signature.rs`

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

Comment thread rsworkspace/crates/trogon-source-gitlab/src/config.rs
Comment thread rsworkspace/crates/trogon-source-gitlab/src/server.rs
Co-authored-by: Zach Bruhnke <zach@ordinary.company>
Co-authored-by: Dave <dave@bruhnke.us>
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
@yordis yordis force-pushed the yordis/gitlab-source-scaffold branch from f15680e to 131fc3f Compare April 6, 2026 01:21

@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.

🧹 Nitpick comments (1)
rsworkspace/crates/trogon-source-gitlab/src/webhook_secret.rs (1)

19-23: Consider rejecting whitespace-only secrets.

Current validation accepts " ", which is usually accidental misconfiguration and hard to diagnose at runtime.

♻️ Suggested tweak
     pub fn new(s: impl AsRef<str>) -> Result<Self, EmptyWebhookSecret> {
         let s = s.as_ref();
-        if s.is_empty() {
+        if s.trim().is_empty() {
             return Err(EmptyWebhookSecret);
         }
         Ok(Self(Arc::from(s)))
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rsworkspace/crates/trogon-source-gitlab/src/webhook_secret.rs` around lines
19 - 23, The new constructor for WebhookSecret currently only checks
s.is_empty() and therefore accepts whitespace-only strings; update
WebhookSecret::new to trim the input (e.g., let trimmed = s.as_ref().trim()) and
return Err(EmptyWebhookSecret) if trimmed.is_empty(); then construct the
WebhookSecret using the trimmed value (or fail if you must preserve original,
but still reject whitespace-only by checking trimmed) so that inputs like "   "
are rejected.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@rsworkspace/crates/trogon-source-gitlab/src/webhook_secret.rs`:
- Around line 19-23: The new constructor for WebhookSecret currently only checks
s.is_empty() and therefore accepts whitespace-only strings; update
WebhookSecret::new to trim the input (e.g., let trimmed = s.as_ref().trim()) and
return Err(EmptyWebhookSecret) if trimmed.is_empty(); then construct the
WebhookSecret using the trimmed value (or fail if you must preserve original,
but still reject whitespace-only by checking trimmed) so that inputs like "   "
are rejected.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 450ab0bd-9b18-45d4-a244-04b61b64c20d

📥 Commits

Reviewing files that changed from the base of the PR and between f15680e and 131fc3f.

⛔ Files ignored due to path filters (1)
  • rsworkspace/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (13)
  • devops/docker/compose/.env.example
  • devops/docker/compose/compose.yml
  • devops/docker/compose/services/trogon-source-gitlab/Dockerfile
  • devops/docker/compose/services/trogon-source-gitlab/README.md
  • rsworkspace/crates/acp-telemetry/src/service_name.rs
  • rsworkspace/crates/trogon-source-gitlab/Cargo.toml
  • rsworkspace/crates/trogon-source-gitlab/src/config.rs
  • rsworkspace/crates/trogon-source-gitlab/src/constants.rs
  • rsworkspace/crates/trogon-source-gitlab/src/lib.rs
  • rsworkspace/crates/trogon-source-gitlab/src/main.rs
  • rsworkspace/crates/trogon-source-gitlab/src/server.rs
  • rsworkspace/crates/trogon-source-gitlab/src/signature.rs
  • rsworkspace/crates/trogon-source-gitlab/src/webhook_secret.rs
✅ Files skipped from review due to trivial changes (5)
  • devops/docker/compose/.env.example
  • devops/docker/compose/services/trogon-source-gitlab/README.md
  • rsworkspace/crates/trogon-source-gitlab/Cargo.toml
  • rsworkspace/crates/trogon-source-gitlab/src/constants.rs
  • rsworkspace/crates/trogon-source-gitlab/src/server.rs
🚧 Files skipped from review as they are similar to previous changes (5)
  • rsworkspace/crates/acp-telemetry/src/service_name.rs
  • devops/docker/compose/services/trogon-source-gitlab/Dockerfile
  • rsworkspace/crates/trogon-source-gitlab/src/signature.rs
  • rsworkspace/crates/trogon-source-gitlab/src/main.rs
  • rsworkspace/crates/trogon-source-gitlab/src/lib.rs

@cursor cursor 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 131fc3f. Configure here.

Comment thread devops/docker/compose/compose.yml
@yordis yordis merged commit dea4118 into main Apr 6, 2026
7 checks passed
@yordis yordis deleted the yordis/gitlab-source-scaffold branch April 6, 2026 01:26
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.

1 participant