Commit Graph
4 Commits
Author SHA1 Message Date
Josh FreeandCopilot 2acfe7e829 feat(coderd/externalauth/gitprovider): use conditional requests for GitHub JSON reads (#27628)
Fixes #27627.

## What

The chat diff-status gitsync worker polls open pull requests on a fixed
10s interval and re-downloads the full JSON body every tick, even when
nothing changed, because the GitHub client never sends `If-None-Match` /
ETag.

This adds a small, concurrency-safe, bounded in-memory ETag+body cache
(`coderd/externalauth/gitprovider/conditional.go`) and wires it into
`githubProvider.decodeJSON`. When an ETag is cached for a request, we
send `If-None-Match`; on `304 Not Modified` we decode the cached body;
on `200` we cache `{etag, body}` when an ETag is present and the body is
under a size cap.

## Why

`304` responses do not count against GitHub's primary rate limit, but
full `200`s do. Today every unchanged poll burns quota that the same
token also needs for interactive Git and API operations, so busy
instances can hit rate-limit errors and stalls elsewhere. Unchanged PRs
now revalidate for free with no behavior change; only genuine changes
transfer a body.

## Details

- Cache key = request URL + a hash of the token, so one token's response
is never served under another; raw tokens are not retained.
- Bounded by entry count (LRU eviction, default 2048) and per-body size
(1 MiB) to cap memory.
- Scope limited to the JSON reads through `decodeJSON`; the raw-diff
path (`fetchDiff`, up to `MaxDiffSize`) is intentionally left out to
avoid caching large bodies.

## Tests

`TestConditionalRequestReuse` in `github_test.go` covers:
- `NotModifiedReusesCachedBody` — a warm poll sends `If-None-Match` with
the prior ETag and reuses the cached body on `304`, yielding the same
result with exactly two upstream requests.
- `DifferentTokenDoesNotShareCache` — a different token never sends
another token's cached ETag.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4959e1f9-f8e6-4e97-a487-f395a0123c79
2026-07-30 17:36:39 +01:00
Cian Johnston 579daaff70 feat: add GitLab support to coderd/externalauth/gitprovider
Fixes CODAGT-146

Add GitLab support to the gitprovider package for gitsync/chatd PR
diff flows. This is a squashed stack of 3 PRs:

#25651 - refactor(coderd/externalauth): prepare gitprovider for multi-provider support
- Change gitprovider.New to return (Provider, error)
- Extract shared helpers (parseRetryAfter, checkRateLimitError,
  countDiffLines, escapePathPreserveSlashes) from github.go
- Update all callers (db2sdk, exp_chats, gitsync) for new signature
- Add error logging for provider construction failures
- Thread context through provider resolution

#25652 - feat(coderd/externalauth/gitprovider): add GitLab provider
- Implement full Provider interface: FetchPullRequestStatus,
  FetchPullRequestDiff, FetchBranchDiff, ResolveBranchPullRequest
- Handle nested groups, forks, and self-hosted instances
- Rate limit detection on both library and raw HTTP paths
- URL parsing/building with NormalizePullRequestURL support
- Unit tests covering error paths, URL parsing, state mapping
- Document GitLab configuration and known limitations

#25653 - test(coderd/externalauth/gitprovider): add GitLab VCR integration tests
- FetchPullRequestStatus: 4 fixtures (open, conflicts, merged, closed)
- FetchPullRequestDiff: 4 fixtures
- FetchBranchDiff: 3 fixtures (open, deleted, fork)
- ResolveBranchPullRequest: 3 fixtures
- go-vcr cassettes with sanitized GitLab API responses
2026-05-25 17:41:02 +01:00
Kyle Carberry 0d3e39a24e feat: add head_branch to pull request diff status (#23076)
Adds the `head_branch` field (the source/feature branch name of a PR) to
the diff status pipeline. Previously only `base_branch` (target branch)
and the head commit SHA were captured from the GitHub API, but not the
head branch name itself.

## Changes

- **Migration 438**: Add `head_branch` nullable TEXT column to
`chat_diff_statuses`
- **gitprovider**: Parse `head.ref` from the GitHub API response
(alongside `head.sha`) and add `HeadBranch` to `PRStatus`
- **gitsync**: Wire `HeadBranch` through `refreshOne()` into the DB
upsert params
- **worker**: Map `HeadBranch` in `chatDiffStatusFromRow()`
- **coderd**: Convert `HeadBranch` in `convertChatDiffStatus()`
- **codersdk**: Expose as `head_branch` (`*string`, omitempty) in
`ChatDiffStatus` API response
- **Tests**: Updated `github_test.go` pull JSON fixtures and assertions
2026-03-14 17:24:19 +00:00
Cian Johnston bc27274aba feat(coderd): refactors github pr sync functionality (#22715)
- Adds `_API_BASE_URL` to `CODER_EXTERNAL_AUTH_CONFIG_`
- Extracts and refactors existing GitHub PR sync logic to new packages
`coderd/gitsync` and `coderd/externalauth/gitprovider`
- Associated wiring and tests

Created using Opus 4.6
2026-03-10 18:46:01 +00:00