ADR-007: Multi-platform VCS abstraction
Status: Accepted
Date: 2026-02-26
Authors: Anders Hassis
Context
Section titled “Context”Erode analyzes pull requests and merge requests from multiple version control platforms. GitHub calls them pull requests. GitLab calls them merge requests. Bitbucket calls them pull requests but uses a different API shape. Each platform has different APIs for fetching diffs, listing files, posting comments, and creating branches.
The analysis pipeline should not care which platform the change request came from. It needs diffs, file lists, and metadata in a consistent shape.
Decision
Section titled “Decision”Define two interfaces that split platform operations by direction:
SourcePlatformReader. Parses change request URLs into a platform-agnosticChangeRequestRef, fetches full change request data asChangeRequestData, and retrieves commit lists.SourcePlatformWriter. Creates or updates change requests, posts comments (with upsert support via markers), deletes comments, and closes change requests.
Platform-agnostic types (ChangeRequestRef, ChangeRequestData, ChangeRequestFile, ChangeAuthor, BranchRef) normalize the differences. PlatformId carries platform-specific identifiers (owner/repo) that only the platform’s own implementation accesses.
Three implementations exist: GitHub, GitLab, and Bitbucket. A PlatformFactory selects the implementation based on the change request URL.
Rationale
Section titled “Rationale”Splitting read and write interfaces follows the interface segregation principle. The analyze pipeline only needs SourcePlatformReader. The publish pipeline needs SourcePlatformWriter. Neither depends on capabilities it does not use.
URL-based platform detection means users do not need to configure which platform they use. The system infers it from the PR/MR URL.
Consequences
Section titled “Consequences”Positive
Section titled “Positive”- The pipeline processes GitHub PRs, GitLab MRs, and Bitbucket PRs with identical code paths.
- Adding a new platform requires implementing the reader/writer interfaces without changing pipeline code.
- Platform-specific API details stay encapsulated in their implementations.
Negative
Section titled “Negative”- The normalized
ChangeRequestDatatype must accommodate all platforms. Platform-specific fields that do not map cleanly get lost or require optional properties. - Comment upsert behavior (via
upsertMarker) works differently across platforms, requiring platform-specific logic inside each writer.
Related commits
Section titled “Related commits”8691ba8- chore(release): release 0.4.0 (#24)8687790- fix: support GitLab and Bitbucket repository URLs in adapters (#36)