Skip to content

feat(github): implement repository sync engine, paginated listing, commit tracking, and incremental sync - #4

Open
ChamathDilshanC wants to merge 1 commit into
developfrom
feature/github-sync
Open

feat(github): implement repository sync engine, paginated listing, commit tracking, and incremental sync#4
ChamathDilshanC wants to merge 1 commit into
developfrom
feature/github-sync

Conversation

@ChamathDilshanC

Copy link
Copy Markdown
Owner

Summary


Related Issue

Closes #


Type of Change

  • feat — New feature
  • fix — Bug fix
  • refactor — Refactoring (no functional change)
  • docs — Documentation only
  • test — Tests only
  • chore — Build, CI, dependencies

Pre-Merge Checklist

Quality Gates

  • cargo fmt --check passes
  • cargo clippy -- -D warnings passes (zero warnings)
  • cargo check passes
  • cargo test passes (all tests green)

Implementation

  • Feature is complete per the linked issue's Acceptance Criteria
  • No .unwrap() or .expect() in production code paths
  • No hardcoded secrets or credentials
  • Structured logging added (tracing::info! / tracing::error!)
  • Input validation implemented at the API boundary
  • Error types are typed (thiserror enum)

Tests

  • Unit tests added for new logic
  • Integration tests added for new API endpoints
  • Database tests added for new repository methods

Documentation

  • docs/ updated if API surface changed
  • docs/AI/API_CHECKLIST.md updated (mark endpoints ✅)
  • docs/FEATURES.md updated (mark feature ✅)
  • OpenAPI annotations added to new handlers

Architecture

  • No forbidden dependency boundaries violated (see docs/AI/ARCHITECTURE_RULES.md)
  • No duplicate functionality introduced
  • Author is ChamathDilshanC <dilshancolonne123@gmail.com>

Architecture Impact

None / [describe impact]


Testing Notes


Screenshots (if UI or API response)


Notes for Reviewer

Copilot AI review requested due to automatic review settings August 3, 2026 15:29

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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 / RepositorySyncReport and SyncType to 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() on response.text() hides the reason the body couldn't be read. Preserve that context so ApiError is 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.

Comment on lines +90 to +92
let status = response.status().as_u16();
let text = response.text().await.unwrap_or_default();
return Err(GitHubRepoError::ApiError(status, text));
Comment on lines +94 to +96
let status = response.status().as_u16();
let text = response.text().await.unwrap_or_default();
return Err(CommitSyncError::ApiError(status, text));
Comment thread crates/github/src/sync.rs
Comment on lines +56 to +61
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;
Comment thread crates/github/src/sync.rs
Comment on lines +75 to +81
if let Ok(commits) = self
.commit_client
.fetch_commits(token, owner, repo_name, since)
.await
{
total_commits += commits.len();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants