Skip to content

Commit 070a285

Browse files
committed
feat(vercel): Add API-driven pipeline backend for Vercel integration setup
Implement `get_pipeline_api_steps()` on `VercelIntegrationProvider` using a single OAuth2 step, mirroring the Slack pattern. Adds the `oauth_authorize_url` to `VercelIdentityProvider` (previously unset since the legacy flow is initiated externally). Updates `build_integration()` to handle both legacy `state["identity"]["data"]` and new `state["oauth_data"]` paths, and falls back to `state["uid"]` for `user_id` in the API flow. Note: Vercel currently has `can_add = False` so the API pipeline cannot be initialized from the frontend yet. This wiring prepares for the upcoming external install UI flow. Ref [VDY-44](https://linear.app/getsentry/issue/VDY-44/vercel-api-driven-integration-setup)
1 parent 94b7028 commit 070a285

File tree

2 files changed

+18
-2
lines changed

2 files changed

+18
-2
lines changed

src/sentry/identity/vercel/provider.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ class VercelIdentityProvider(OAuth2Provider):
88
key = "vercel"
99
name = "Vercel"
1010

11+
oauth_authorize_url = "https://vercel.com/oauth/authorize"
1112
# https://vercel.com/docs/integrations/reference#using-the-vercel-api/exchange-code-for-access-token
1213
oauth_access_token_url = "https://api.vercel.com/v2/oauth/access_token"
1314

src/sentry/integrations/vercel/integration.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from sentry import options
1313
from sentry.constants import ObjectStatus
1414
from sentry.identity.pipeline import IdentityPipeline
15+
from sentry.identity.vercel.provider import VercelIdentityProvider
1516
from sentry.integrations.base import (
1617
FeatureDescription,
1718
IntegrationData,
@@ -24,7 +25,7 @@
2425
from sentry.integrations.pipeline import IntegrationPipeline
2526
from sentry.integrations.services.integration import integration_service
2627
from sentry.organizations.services.organization.model import RpcOrganization
27-
from sentry.pipeline.views.base import PipelineView
28+
from sentry.pipeline.views.base import ApiPipelineSteps, PipelineView
2829
from sentry.pipeline.views.nested import NestedPipelineView
2930
from sentry.projects.services.project.model import RpcProject
3031
from sentry.projects.services.project_key import project_key_service
@@ -435,8 +436,22 @@ def _identity_pipeline_view(self) -> PipelineView[IntegrationPipeline]:
435436
def get_pipeline_views(self) -> Sequence[PipelineView[IntegrationPipeline]]:
436437
return [self._identity_pipeline_view()]
437438

439+
def get_pipeline_api_steps(self) -> ApiPipelineSteps[IntegrationPipeline]:
440+
provider = VercelIdentityProvider(
441+
redirect_url=absolute_uri(self.oauth_redirect_url),
442+
)
443+
return [
444+
provider.make_oauth_api_step(bind_key="oauth_data"),
445+
]
446+
438447
def build_integration(self, state: Mapping[str, Any]) -> IntegrationData:
439-
data = state["identity"]["data"]
448+
# TODO: legacy views write token data to state["identity"]["data"] via
449+
# NestedPipelineView. API steps write directly to state["oauth_data"].
450+
# Remove the legacy path once the old views are retired.
451+
if "oauth_data" in state:
452+
data = state["oauth_data"]
453+
else:
454+
data = state["identity"]["data"]
440455
access_token = data["access_token"]
441456
team_id = data.get("team_id")
442457
client = VercelClient(access_token, team_id)

0 commit comments

Comments
 (0)