-
Notifications
You must be signed in to change notification settings - Fork 141
Description
I ran into an interesting failure in our CI pipeline when the success lifecycle of the semantic-release/github plugin ran the other day. It didn't block our release but left the PR and issue updates incomplete. The error surfaced was:
Error: Field 'commit429fa6' has an argument conflict: {oid:"/"429fa60a84f7b59f9e4a20bfbea6b0fa977a1e1e/""} or {oid:"/"429fa667b462b60b31769e5268cfbc6835793c14/""}
This occurred due to two different commits within the release we were making sharing the same first 6 characters of their SHA (429fa6). It turns out the query builder, which builds the query to pass to GitHub's API, uses the first 6 characters of the SHA to create GraphQL aliases:
commit${sha.slice(0, 6)}: object(oid: "${sha}") { ... }This code is located at Line 460 in success.js.
Our CI pipeline failure
Background
This behaviour was introduced in PR #857, which rewrote the success lifecycle to use GitHub’s GraphQL API for better rate-limit handling.
The intention behind truncating to 6 characters was likely to keep aliases short and readable, but it introduces collisions in real-world repositories. As commits within a repo increase there is a higher likelihood of collision due to the birthday paradox effect.
In our case, we had a number of rapid changes occur and a larger than normal amount of commits generated that all wound up in the same release.
I ran some analysis on our repository of 2,724 commits (at the time of writing) and discovered we have two collision pairs of commits when considering the first 6 characters of the SHA. The first collision pair contains two commits two years apart. The offending collision pair that surfaced this issue contains two commits a few weeks apart.
Impact
- GraphQL requires unique aliases for fields with different arguments.
- When two commits share the same prefix, the query fails with an argument conflict error from the GitHub GraphQL API.
- This breaks the
successlifecycle and prevents associated PRs from being fetched.
Proposed Fix
Use a longer short SHA prefix, ≥7–12 chars. GitHub uses 7 digit short SHAs, however the longer the slice the smaller the collision space is.