feat(github): implement repository sync engine, paginated listing, commit tracking, and incremental sync - #4
Conversation
…raction, and incremental sync engine
There was a problem hiding this comment.
🟡 Not ready to approve
The sync engine currently only fetches one repo page and silently ignores commit-fetch errors, which can lead to incomplete/incorrect “successful” sync reports.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.
Pull request overview
This PR introduces a GitHub repository sync layer in the crates/github crate, adding typed clients for listing repositories and fetching commits, plus a sync engine that aggregates results into a report.
Changes:
- Added
RepositorySyncEngine/RepositorySyncReportandSyncTypeto orchestrate repo + commit syncing. - Introduced typed error enums for repository and commit API interactions and refactored clients to return
Result. - Added pagination-related options (
SyncOptions) and commit models, plus basic unit tests.
File summaries
| File | Description |
|---|---|
| crates/github/tests/sync_tests.rs | Adds basic serialization and helper-function tests for new GitHub types. |
| crates/github/src/sync.rs | Implements the repository sync engine and reporting types. |
| crates/github/src/repositories.rs | Adds typed repo client errors, sync options, pagination parameters, and single-repo fetch. |
| crates/github/src/lib.rs | Re-exports new sync and commit/repo client symbols from the crate root. |
| crates/github/src/commits.rs | Adds commit client, typed errors, commit models, and caps commit impact score. |
| crates/github/Cargo.toml | Adds urlencoding workspace dependency for query encoding. |
| Cargo.lock | Locks the new urlencoding dependency. |
Review details
Suppressed comments (1)
crates/github/src/repositories.rs:120
- Same as above:
unwrap_or_default()onresponse.text()hides the reason the body couldn't be read. Preserve that context soApiErroris actionable in logs and error reports.
if !response.status().is_success() {
let status = response.status().as_u16();
let text = response.text().await.unwrap_or_default();
return Err(GitHubRepoError::ApiError(status, text));
- Files reviewed: 6/7 changed files
- Comments generated: 4
- Review effort level: Lite
We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.
| let status = response.status().as_u16(); | ||
| let text = response.text().await.unwrap_or_default(); | ||
| return Err(GitHubRepoError::ApiError(status, text)); |
| let status = response.status().as_u16(); | ||
| let text = response.text().await.unwrap_or_default(); | ||
| return Err(CommitSyncError::ApiError(status, text)); |
| let start = std::time::Instant::now(); | ||
| let opts = SyncOptions::default(); | ||
|
|
||
| let repos: Vec<GithubRepo> = self.repo_client.fetch_repositories(token, &opts).await?; | ||
| let repo_count = repos.len(); | ||
| let mut total_commits = 0; |
| if let Ok(commits) = self | ||
| .commit_client | ||
| .fetch_commits(token, owner, repo_name, since) | ||
| .await | ||
| { | ||
| total_commits += commits.len(); | ||
| } |
Summary
Related Issue
Closes #
Type of Change
feat— New featurefix— Bug fixrefactor— Refactoring (no functional change)docs— Documentation onlytest— Tests onlychore— Build, CI, dependenciesPre-Merge Checklist
Quality Gates
cargo fmt --checkpassescargo clippy -- -D warningspasses (zero warnings)cargo checkpassescargo testpasses (all tests green)Implementation
.unwrap()or.expect()in production code pathstracing::info!/tracing::error!)thiserrorenum)Tests
Documentation
docs/updated if API surface changeddocs/AI/API_CHECKLIST.mdupdated (mark endpoints ✅)docs/FEATURES.mdupdated (mark feature ✅)Architecture
docs/AI/ARCHITECTURE_RULES.md)ChamathDilshanC <dilshancolonne123@gmail.com>Architecture Impact
None / [describe impact]
Testing Notes
Screenshots (if UI or API response)
Notes for Reviewer