-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Azure DevOps (Microsoft Entra ID OAuth) migrate components #19483
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
WalkthroughAdds OAuth-backed Azure DevOps API helpers and subscription management to the app component, introduces a new event source that creates/deletes webhook subscriptions and emits received events, and bumps the component package version and dependencies. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant Source as Event Source
participant App as AzureDevOps App
participant ADO as Azure DevOps API
participant DB as Database
participant Webhook as Webhook (HTTP endpoint)
User->>Source: Activate (select eventType, projectId)
Source->>App: call createSubscription(opts with http.endpoint)
App->>ADO: POST /hooks/subscriptions (Bearer token, api-version)
ADO-->>App: subscriptionId
App-->>Source: subscription response
Source->>DB: _setHookId(subscriptionId)
Webhook->>Source: Incoming webhook POST (event body)
Source->>Source: generateMeta(body)
Source->>User: emit(event, meta)
User->>Source: Deactivate
Source->>DB: _getHookId()
Source->>App: deleteSubscription(subscriptionId)
App->>ADO: DELETE /hooks/subscriptions/{subscriptionId}
ADO-->>App: success
Source->>DB: clear stored subscriptionId
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Pre-merge checks and finishing touches❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (3)
components/azure_devops_microsoft_entra_id_oauth/azure_devops_microsoft_entra_id_oauth.app.mjs(1 hunks)components/azure_devops_microsoft_entra_id_oauth/package.json(2 hunks)components/azure_devops_microsoft_entra_id_oauth/sources/new-event/new-event.mjs(1 hunks)
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2024-12-12T19:23:09.039Z
Learnt from: jcortes
Repo: PipedreamHQ/pipedream PR: 14935
File: components/sailpoint/package.json:15-18
Timestamp: 2024-12-12T19:23:09.039Z
Learning: When developing Pipedream components, do not add built-in Node.js modules like `fs` to `package.json` dependencies, as they are native modules provided by the Node.js runtime.
Applied to files:
components/azure_devops_microsoft_entra_id_oauth/package.json
📚 Learning: 2024-10-10T19:18:27.998Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 14265
File: components/the_magic_drip/sources/common.mjs:35-43
Timestamp: 2024-10-10T19:18:27.998Z
Learning: In `components/the_magic_drip/sources/common.mjs`, when processing items in `getAndProcessData`, `savedIds` is intentionally updated with IDs of both emitted and non-emitted items to avoid emitting retroactive events upon first deployment and ensure only new events are emitted as they occur.
Applied to files:
components/azure_devops_microsoft_entra_id_oauth/sources/new-event/new-event.mjs
📚 Learning: 2025-09-15T22:01:11.472Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 18362
File: components/leonardo_ai/actions/generate-image/generate-image.mjs:103-105
Timestamp: 2025-09-15T22:01:11.472Z
Learning: In Pipedream components, pipedream/platform's axios implementation automatically excludes undefined values from HTTP requests, so there's no need to manually check for truthiness before including properties in request payloads.
Applied to files:
components/azure_devops_microsoft_entra_id_oauth/azure_devops_microsoft_entra_id_oauth.app.mjs
📚 Learning: 2024-10-08T15:33:38.240Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 12697
File: components/salesforce_rest_api/sources/common-webhook-methods.mjs:1-71
Timestamp: 2024-10-08T15:33:38.240Z
Learning: The `common-webhook-methods.mjs` object is designed to be extended, similar to an abstract class, and intentionally does not implement certain methods like `generateWebhookMeta` and `getEventType` to enforce implementation in subclasses.
Applied to files:
components/azure_devops_microsoft_entra_id_oauth/azure_devops_microsoft_entra_id_oauth.app.mjs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Lint Code Base
- GitHub Check: Publish TypeScript components
- GitHub Check: Verify TypeScript components
- GitHub Check: pnpm publish
🔇 Additional comments (8)
components/azure_devops_microsoft_entra_id_oauth/azure_devops_microsoft_entra_id_oauth.app.mjs (5)
18-20: LGTM!The base URL construction correctly uses the organization from the auth configuration.
44-50: LGTM!The subscription creation method correctly delegates to the POST endpoint.
51-57: LGTM!The subscription deletion method correctly constructs the DELETE request.
21-36: No action needed. API version 7.1 is correct for Microsoft Entra ID OAuth with Azure DevOps REST API and is officially supported in 2024-2025. The implementation follows Microsoft's recommended approach for Entra ID OAuth integration.
37-43: No action needed on this endpoint.The
/hooks/publishers/tfs/eventtypesendpoint is the current, documented Azure DevOps REST API endpoint for retrieving webhook event types. The "tfs" publisher identifier is the standard publisher name for Azure DevOps (not a legacy identifier), and it works seamlessly with Microsoft Entra ID OAuth authentication. The endpoint compatibility is not affected by the authentication method used.components/azure_devops_microsoft_entra_id_oauth/sources/new-event/new-event.mjs (3)
1-20: LGTM!The component structure and prop definitions follow Pipedream conventions correctly.
44-50: LGTM!The hookId persistence methods correctly use the db service.
59-63: LGTM!The run method correctly emits webhook events with generated metadata, following standard Pipedream patterns.
components/azure_devops_microsoft_entra_id_oauth/azure_devops_microsoft_entra_id_oauth.app.mjs
Show resolved
Hide resolved
components/azure_devops_microsoft_entra_id_oauth/sources/new-event/new-event.mjs
Show resolved
Hide resolved
components/azure_devops_microsoft_entra_id_oauth/sources/new-event/new-event.mjs
Show resolved
Hide resolved
components/azure_devops_microsoft_entra_id_oauth/sources/new-event/new-event.mjs
Show resolved
Hide resolved
luancazarine
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @michelle0927, LGTM! Ready for QA!
For Integration QA: |
|
Hello everyone, I have tested this PR and there're some test cases failed or needed improvement. Please check test reports below for more information:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (3)
components/azure_devops_microsoft_entra_id_oauth/sources/new-event/new-event.mjs (2)
28-51: Fix subscription payload shape and harden deactivation against missing hook IDs.
- The subscription payload still includes a top-level
url(Line 30) in addition toconsumerInputs.url. Azure DevOps service hook subscriptions expecturlonly underconsumerInputs; the extra top-level field is unnecessary and can cause API validation issues.deactivatecallsdeleteSubscriptioneven when_getHookId()may return null/undefined, which will produce a bad DELETE call if activation failed or state is missing.Apply a change along these lines:
async activate() { const data = { - url: this.http.endpoint, publisherId: "tfs", resourceVersion: "1.0", consumerId: "webHooks", consumerActionId: "httpRequest", consumerInputs: { url: this.http.endpoint, }, @@ }, async deactivate() { const id = this._getHookId(); + if (!id) { + console.log("No subscription ID found; skipping deletion"); + return; + } await this.azureDevops.deleteSubscription(id); },Also verify that
"resourceVersion": "1.0"is valid for all supported event types (some examples use1.0-preview.1).For Azure DevOps service hook subscriptions, what is the documented request body schema for POST /_apis/hooks/subscriptions (specifically: where should the webhook URL be placed, and what resourceVersion values are valid for tfs publisher event types)?
53-67: Add minimal validation aroundgenerateMetapayload fields.
generateMetaassumesbody.idandbody.createdDateare always present and valid. A malformed or unexpected webhook payload will yieldundefinedIDs orNaNtimestamps, which can break dedupe and ordering.Consider guarding these fields and falling back to safe defaults or throwing a clear error, e.g.:
generateMeta(body) { + if (!body || !body.id || !body.createdDate) { + console.warn("Unexpected Azure DevOps event body structure:", body); + } + return { - id: body.id, + id: body?.id || String(Date.now()), summary: `New ${this.eventType} event with ID ${body?.id}`, - ts: Date.parse(body.createdDate), + ts: body?.createdDate ? Date.parse(body.createdDate) : Date.now(), }; },This keeps the source resilient if Azure DevOps changes the envelope slightly or if a test/misconfigured webhook hits the endpoint.
components/azure_devops_microsoft_entra_id_oauth/azure_devops_microsoft_entra_id_oauth.app.mjs (1)
6-29: ImproveeventTypeoptions UX and align shape withprojectIdoptions.
eventType.options()currently returns a plain array of IDs, whileprojectId.options()returns{ label, value }objects. For consistency and better UI, consider returning label/value pairs for event types as well:async options() { const types = await this.listEventTypes(); - return types.filter(({ id }) => id !== "tfvc.checkin" && id !== "build.complete").map(({ id }) => id); + return types + .filter(({ id }) => id !== "tfvc.checkin" && id !== "build.complete") + .map((type) => ({ + value: type.id, + label: type.name || type.id, + })); },This preserves the stored ID while showing a more descriptive label in the UI.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
components/azure_devops_microsoft_entra_id_oauth/azure_devops_microsoft_entra_id_oauth.app.mjs(1 hunks)components/azure_devops_microsoft_entra_id_oauth/sources/new-event/new-event.mjs(1 hunks)
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2025-08-27T17:25:10.425Z
Learnt from: jverce
Repo: PipedreamHQ/pipedream PR: 18187
File: packages/connect-react/src/utils/type-guards.ts:23-33
Timestamp: 2025-08-27T17:25:10.425Z
Learning: In the connect-react package, the isOptionWithLabel type guard intentionally restricts value types to string|number for runtime filtering purposes, even though LabelValueOption<T> allows any T. This runtime behavior should be preserved over type safety improvements.
Applied to files:
components/azure_devops_microsoft_entra_id_oauth/azure_devops_microsoft_entra_id_oauth.app.mjs
📚 Learning: 2025-09-15T22:01:11.472Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 18362
File: components/leonardo_ai/actions/generate-image/generate-image.mjs:103-105
Timestamp: 2025-09-15T22:01:11.472Z
Learning: In Pipedream components, pipedream/platform's axios implementation automatically excludes undefined values from HTTP requests, so there's no need to manually check for truthiness before including properties in request payloads.
Applied to files:
components/azure_devops_microsoft_entra_id_oauth/azure_devops_microsoft_entra_id_oauth.app.mjs
📚 Learning: 2024-10-10T19:18:27.998Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 14265
File: components/the_magic_drip/sources/common.mjs:35-43
Timestamp: 2024-10-10T19:18:27.998Z
Learning: In `components/the_magic_drip/sources/common.mjs`, when processing items in `getAndProcessData`, `savedIds` is intentionally updated with IDs of both emitted and non-emitted items to avoid emitting retroactive events upon first deployment and ensure only new events are emitted as they occur.
Applied to files:
components/azure_devops_microsoft_entra_id_oauth/sources/new-event/new-event.mjs
📚 Learning: 2025-10-20T01:01:02.970Z
Learnt from: js07
Repo: PipedreamHQ/pipedream PR: 18744
File: components/slack_v2/actions/send-large-message/send-large-message.mjs:49-64
Timestamp: 2025-10-20T01:01:02.970Z
Learning: In components/slack_v2/actions/send-large-message/send-large-message.mjs, the metadata_event_payload prop is typed as string, so the code only needs to handle string-to-JSON parsing and does not need to handle object inputs.
Applied to files:
components/azure_devops_microsoft_entra_id_oauth/sources/new-event/new-event.mjs
📚 Learning: 2025-07-09T18:07:12.426Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 17538
File: components/aircall/sources/new-sms/new-sms.mjs:19-25
Timestamp: 2025-07-09T18:07:12.426Z
Learning: In Aircall API webhook payloads, the `created_at` field is returned as an ISO 8601 string format (e.g., "2020-02-18T20:52:22.000Z"), not as milliseconds since epoch. For Pipedream components, this needs to be converted to milliseconds using `Date.parse()` before assigning to the `ts` field in `generateMeta()`.
Applied to files:
components/azure_devops_microsoft_entra_id_oauth/sources/new-event/new-event.mjs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Verify TypeScript components
- GitHub Check: pnpm publish
- GitHub Check: Publish TypeScript components
- GitHub Check: Lint Code Base
🔇 Additional comments (2)
components/azure_devops_microsoft_entra_id_oauth/sources/new-event/new-event.mjs (2)
1-26: Source definition and props wiring look correct.Importing the app, wiring
azureDevops,db,http, and usingpropDefinitionforeventTypeandprojectIdmatches Pipedream patterns; no issues here.
68-72: Event handling and emit flow are straightforward and appropriate.Extracting
bodyfrom the incoming event, building meta viagenerateMeta, and emitting{ body, meta }matches standard Pipedream source patterns; no changes needed.
components/azure_devops_microsoft_entra_id_oauth/azure_devops_microsoft_entra_id_oauth.app.mjs
Show resolved
Hide resolved
|
Hi everyone, all test cases are passed! Ready for release! Test reports
|
|
/approve |
Resolves #18106
Summary by CodeRabbit
New Features
Chores
✏️ Tip: You can customize this high-level summary in your review settings.