fix(integrations): CLI sends remote_url + cron backfills unmatched deploys#48
Merged
Merged
Conversation
…ploys Two halves of the same gap. The Datadog sync only matches a deploy's dd_repository_id to an Iris repo at insertion time. If `repositories. remote_url` is NULL when the cron ingests an event, the row lands with `repository_id = null` and stays unmatched forever — the per-repo DORA section never renders. Two reasons remote_url ends up NULL: 1. The CLI's `push_metrics` call never passed `remote_url`. The parameter exists on the platform side (and on the underlying `push_metrics(...)` Python signature), but `_push_after_analysis` and `_run_push` both omitted it, so /api/ingest had nothing to write into the column. 2. Even after the CLI is fixed, all existing rows that were ingested before the repo had a remote_url stay null — the cron only fetches events with started_at >= last_sync_at, and the UNIQUE (provider, provider_event_id) upsert touches only new ids. Fixes: - `iris/cli.py`: factors out `_git_remote_url(repo_path)` and passes its result through to `push_metrics(remote_url=...)` from both the post-analysis push and the standalone `iris push <file>`. The standalone path detects from cwd (best-effort). - `platform/lib/integrations/datadog/sync.ts`: new `rematchUnlinkedDeployments(supabase, orgId)`. Loads the current repo lookup, pages through `external_deployments WHERE repository_id IS NULL AND dd_repository_id IS NOT NULL`, normalizes each slug, and updates rows in batches of 100 whose slug matches a current repo. Idempotent — only flips null → set, never overwrites. - `platform/src/app/api/cron/sync-integrations/route.ts`: runs the rematch after each successful sync. Failures don't fail the run; they're logged and the per-org outcome includes the new `rematched` count. Once this lands, a manual cron trigger (`curl -H "Authorization: Bearer $CRON_SECRET" .../api/cron/sync-integrations`) will retroactively match the existing ~773 null-repository_id rows on the customer org — the per-repo DORA sections that depend on `repository_id` will start showing data without a re-sync from Datadog. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
trentas
added a commit
that referenced
this pull request
May 14, 2026
Bumps pyproject.toml (1.0.6 → 1.0.7), iris/cli.py:VERSION (v1.0.6 → v1.0.7), and platform/package.json (1.0.6 → 1.0.7). Adds the CHANGELOG entry covering the five fix PRs that landed after the v1.0.6 release as the customer's real Datadog integration came online: - #44 credentials_encrypted BYTEA → TEXT - #45 dedupe DORA events before upsert + cron retries errored integrations - #46 chunk commits .in() to stay under PostgREST URL ceiling - #47 direct-from-tables DORA aggregation + per-repo section - #48 CLI sends remote_url + cron backfills unmatched deploys Plus #43 gitignore fix that was missed by the v1.0.6 squash. Tag v1.0.7 cut from main triggers the Release workflow to build the wheel + publish the GitHub Release, so `iris upgrade` will pick up the fixes (most notably the CLI sending remote_url) on the next run. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
trentas
added a commit
that referenced
this pull request
May 14, 2026
) The schema validated `remote_url` with Zod's `.url()`, which only accepts WHATWG URLs (scheme://...). The CLI's new \`remote_url\` plumbing (#48 / v1.0.7) sends whatever \`git remote get-url origin\` returns; on machines configured with SSH that's \`git@github.com:org/repo.git\` — no scheme, rejected by Zod with: "remote_url":["Invalid URL"] So the v1.0.7 CLI sends the value as intended, the server rejects the whole push, and \`repositories.remote_url\` stays NULL — defeating the fix entirely on SSH-configured machines. Relax the schema to `z.string().min(1).optional()`. The value is informational metadata: it never gets fetched, never embedded as HTML, only normalized via `normalizeRepoSlug` for DORA matching (which already understands the SSH form: `^git@([^:]+):` → `host/$1`). Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The per-repo DORA section depends on `external_deployments.repository_id` being set, which only happens at ingestion time when the Datadog `dd_repository_id` slug normalizes to a known `repositories.remote_url`. Two reasons this match was failing:
CLI never sent `remote_url`. `_push_after_analysis` and `_run_push` both omitted the parameter, so `repositories.remote_url` stayed NULL — even after `iris . --push` ran successfully from inside a git repo. Confirmed locally on `benefits-club-service`: row exists, `remote_url IS NULL`, but Datadog has matching deploys at `github.com/rocketbus/benefits-club-service`.
Cron never re-matched existing rows. Even with the CLI fix, the ~773 unmatched rows already in `external_deployments` stayed null — the cron only fetches NEW events (`started_at >= last_sync_at`) and the upsert touches only new ids.
What changed
CLI
Platform
Verified
`tsc --noEmit` clean. `vitest` 186 passed. `pytest` 115 passed. `eslint` clean.
Test plan
🤖 Generated with Claude Code