feat: git repository commit visibility (IFC-3101)
Why
When a user pushes a commit to a repository connected to Infrahub, nothing in the product tells them whether it was picked up. The repository page reports an "in sync" status reflecting only the default branch, and finding the commit Infrahub is actually running means copying hashes and comparing them by hand. For read-only repositories it is worse: Infrahub never looks at the remote unless something changes on the Infrahub side, so a tracked ref can advance or be rewritten entirely without a trace. Diagnosis falls to the Solution Architecture team at roughly two hours per incident.
Goal: a user can view, from the repository page in Infrahub, the recent commits of the branch they are on, which commit Infrahub has imported, which commit is at the head of the remote, and which commits are waiting to be imported. An operator of a read-only repository can rely on Infrahub to notice when a tracked ref moves upstream, without that changing which commit Infrahub runs.
This branch is the epic branch. Each part of the feature was reviewed and approved in its own pull request against this branch (listed under "Previously approved work"), so that the feature merges to develop as one change.
Jira: IFC-3101, first part of INFP-671.
Source PRD: Git repository commit visibility.
Sibling: IFC-3104 owns the Branches card that the per-branch drift query is built for.
Specification: dev/specs/ifc-3101-repo-commit-visibility/.
Todo
- feat: add the WORKER_TIMEOUT error code to the generated catalogue - We brought in this SDK commit as part of this: https://github.com/opsmill/infrahub-sdk-python/pull/1405, it should be coordinated so that we update it to the
infrahub-developbranch commit once merged.
Previously approved work
- feat: publish the repository git-state GraphQL contract [IFC-3146] (approved in #10566)
- feat(backend): bound every worker RPC by a configurable timeout [IFC-3148]- (approved in #10668)
- feat: detect upstream movement on read-only repository refs [IFC-3152] (approved in #10669)
- feat: answer repository branch drift with a row per branch [IFC-3147]- (approved in #10667)
- fix: make the refs-check broadcast worker-independent [IFC-3246]- (approved in #10835)
- feat(backend): read the repository commit log live from a worker [IFC-3149]- (approved in #10836)
- feat(backend): answer per-branch drift from one worker read [IFC-3154]- (approved in #10941)
- fix(backend): warm up a repository without resetting it [IFC-3345]- (approved in #10954)
What changed
Commits tab on the repository page
- The repository page has a new Commits tab. It lists the commits of the Infrahub branch the user is viewing, newest first, with the short hash, summary, author and date of each commit (#10805).
- The tab marks the commit Infrahub has imported and the head of the remote branch or tracked ref, and shows how many commits are pending import, also as a count on the tab.
- When the tracked ref was rebased or force-pushed so that the imported commit is no longer part of its history, the tab shows a notice instead of a pending count.
- The tab states when the worker's local copy was last updated and, for a read-only repository, when the remote was last checked.
- Each commit has a menu to copy its full hash or, for a repository hosted on GitHub, view the commit on GitHub.
- When no worker has a local copy yet, the tab says the commit log is not available. It retries every 10 seconds, up to 30 times (about five minutes), and then asks the user to refresh. The spec required the tab to resolve with no limit; the bounded retry is recorded under FR-014 in
spec.md.
Commit log read live from a task worker
- The
InfrahubRepositoryCommitsGraphQL query returns, for one repository and the branch being viewed, the ref it follows, the imported commit, and a paged commit log (#10566, #10836). - The log is read from a task worker's local copy over the message bus (
git.commit_log.get). The read never fetches from the remote, never clones and takes no lock. - Each commit carries a state:
HEAD,IMPORTED,PENDING,HISTORYorUNRELATED. The answer carries a condition:IN_SYNC,BEHIND,REWRITTEN,ORPHANED(the imported commit no longer exists in the local copy),REF_MISSING(a read-only repository's tracked branch or tag was deleted upstream),NO_REMOTE,NOT_TRACKEDorUNAVAILABLE. - A worker with no local copy answers
UNAVAILABLEwith reasonNOT_CLONEDand starts one warm-up clone, broadcast to every worker. The warm-up no longer resets an existing copy (#10954).
Upstream check for read-only repositories
- A scheduled check lists the remote refs of each read-only repository. When a tracked ref has moved, every worker fetches the new objects with the imported commit kept checked out (#10669). The check never writes the tracked commit, never starts an import, and never changes which commit a worker has checked out.
- Listing the remote refs holds no repository lock, so an unreachable remote cannot delay that repository's imports. A repository whose remote fails is recorded with the reason and retried before a full interval passes, without holding up the other repositories.
- Whether to broadcast the fetch is decided against the head the previous check listed, not against the checking worker's own copy, so the result does not depend on which worker ran the check (#10835).
- A user with permission to update the repository can start the check from the "Check remote now" button on the Commits tab (#10955) or through the
InfrahubReadOnlyRepositoryCheckRefsmutation. - Fixed: a read-only repository now follows a tracked tag that was moved upstream. Before, the import failed or kept the old commit, and other workers could not pick up the new commit.
Per-branch drift query
- The
InfrahubRepositoryBranchDriftGraphQL query returns one row per branch of a repository, with the ref and commit that branch resolves in Infrahub, the remote head, and the condition (#10667, #10941). - The Infrahub side is read with one database query for all branches (
RepositoryBranchValuesQuery). The remote head and condition for all branches come from one worker request (git.branch_heads.get). - When no worker answers in time, every row is still returned and only the comparison with the remote is reported as unavailable.
- No page in the UI uses this query yet. Its consumer is the Branches card owned by IFC-3104.
Time limit on every worker request
- Every message-bus RPC now waits at most
INFRAHUB_BROKER_RPC_TIMEOUTseconds (default 30) and then fails with the cataloguedWORKER_TIMEOUTerror, which names the operation and when to retry (#10668). This changes existing callers, such as the git file read and the repository connectivity check, which waited with no limit before. - When the connectivity check cannot complete while a repository is being added, the half-created repository is removed, so the user can add it again.
Specification
- The spec set under
dev/specs/ifc-3101-repo-commit-visibility/is the reference for the feature. It was updated as the parts landed: decisions taken during implementation are recorded inspec.md(for example the bounded retry under FR-014, andREF_MISSINGunder FR-029), and every departure from the PRD is listed under "Deviations from the source PRD".
What stayed the same: commits are read from Git when requested and are never stored as nodes, so they never appear in a diff or a merge. No new node kind, attribute or migration, and nothing in this branch writes to the graph. FR-030 (marking a deleted tracked ref on the branch's sync_status) is specified and signed off but not implemented here.
How to review
Each part was approved in its own pull request. For this pull request:
- The merge commits from
developinto this branch, which carry the conflict resolutions no earlier review covered. spec.md, for what the feature does and the "Deviations from the source PRD" register.quickstart.md, to run the feature end to end.
Impact & rollout
- Backward compatibility: the GraphQL changes are additive.
InfrahubReadOnlyRepositoryCheckRefsnow runs the check; before, it accepted a request and did nothing. Existing worker requests that took longer than 30 seconds now fail withWORKER_TIMEOUTinstead of waiting. - Config/env changes:
INFRAHUB_BROKER_RPC_TIMEOUT(default 30 seconds) andINFRAHUB_GIT_READ_ONLY_REFS_CHECK_INTERVAL_MINS(default 15 minutes), declared in both Docker Compose files. - Deployment notes: adds a scheduled background check whose load grows with the number of read-only repositories; an idle repository costs one refs listing per interval. No migration. The
python_sdkpointer must move to theinfrahub-developcommit before merge (see Todo).
Checklist
- Tests added/updated
- Changelog entry - five fragments under
changelog/ - External docs updated - not yet (T088)
- Internal .md docs updated - the spec set,
dev/knowledge/backend/git-sync.md,dev/knowledge/backend/message-bus.md,dev/knowledge/frontend/shared-components.md - I have reviewed AI generated content