aboutsummaryrefslogtreecommitdiff
path: root/mod/mod-ci-github.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'mod/mod-ci-github.cxx')
-rw-r--r--mod/mod-ci-github.cxx136
1 files changed, 24 insertions, 112 deletions
diff --git a/mod/mod-ci-github.cxx b/mod/mod-ci-github.cxx
index 60a6bae..035d81b 100644
--- a/mod/mod-ci-github.cxx
+++ b/mod/mod-ci-github.cxx
@@ -585,120 +585,25 @@ namespace brep
return true;
}
- // High-level description of pull request (PR) handling
+ // Miscellaneous pull request facts
//
- // @@ TODO Update these comments.
+ // - Although some of the GitHub documentation makes it sound like they
+ // expect check runs to be added to both the PR head commit and the merge
+ // commit, the PR UI does not react to the merge commit's check runs
+ // consistently. It actually seems to be quite broken. The only thing it
+ // does seem to do reliably is blocking the PR merge if the merge commit's
+ // check runs are not successful (i.e, overriding the PR head commit's
+ // check runs). But the UI looks quite messed up generally in this state.
//
- // - Some GitHub pull request terminology:
+ // - When new commits are added to a PR base branch, pull_request.base.sha
+ // does not change, but the test merge commit will be updated to include
+ // the new commits to the base branch.
//
- // - Fork and pull model: Pull requests are created in a forked
- // repository. Thus the head and base repositories are different.
+ // - When new commits are added to a PR head branch, pull_request.head.sha
+ // gets updated with the head commit's SHA and check_suite.pull_requests[]
+ // will contain all PRs with this branch as head.
//
- // - Shared repository model: The pull request head and base branches are
- // in the same repository. For example, from a feature branch onto
- // master.
- //
- // - CI the merge commit but add check runs to the pull request head commit
- //
- // Most of the major CI integrations build the merge commit instead of the
- // PR head commit.
- //
- // Adding the check runs to the PR head commit is recommended by the
- // following blog posts by a GitHub employee who is one of the best
- // sources on these topics:
- // https://www.kenmuse.com/blog/shared-commits-and-github-checks/ and
- // https://www.kenmuse.com/blog/creating-github-checks/.
- //
- // Do not add any check runs to the merge commit because:
- //
- // - The PR head commit is the only commit that can be relied upon to
- // exist throughout the PR's lifetime. The merge commit, on the other
- // hand, can change during the PR process. When that happens the PR will
- // look for check runs on the new merge commit, effectively discarding
- // the ones we had before.
- //
- // - Although some of the GitHub documentation makes it sound like they
- // expect check runs to be added to both the PR head commit and the
- // merge commit, the PR UI does not react to the merge commit's check
- // runs consistently. It actually seems to be quite broken.
- //
- // The only thing it seems to do reliably is blocking the PR merge if
- // the merge commit's check runs are not successful (i.e, overriding the
- // PR head commit's check runs). But the UI looks quite messed up
- // generally in this state.
- //
- // Note that, in the case of a PR from a forked repository (the so-called
- // "fork and pull" model), GitHub will copy the PR head commit from the
- // head repository (the forked one) into the base repository. So the check
- // runs must always be added to the base repository, whether the PR is
- // from within the same repository or from a forked repository. The merge
- // and head commits will be at refs/pull/<PR-number>/{merge,head}.
- //
- // - @@ TODO Shared repo model problems
- //
- // The root of all of these problems is that, in the shared repository
- // model, for every PR we also receive a check_suite for the commit to
- // the head branch. The situation is exacerbated by the fact that the
- // PR and CS can arrive in any order.
- //
- // - There will be two CIs running concurrently, building different
- // commits: the head commit (check_suite) vs merge commit
- // (pull_request).
- //
- // - The CS and PR check_runs will all be added to the same commit
- // SHA: pull_request.head.sha, check_suite.head_sha (see above for
- // the reasons we don't put the check_runs on the merge
- // commit).
- //
- // - Recall that creating a check_run named `A` will effectively
- // replace any existing check_runs with that name. They will still
- // exist on the GitHub servers but GitHub will only consider the
- // latest one (for display in the UI or in determining the
- // mergeability of a PR).
- //
- // - Some CS CRs may finish after the corresponding PR CRs, thus
- // potentially inverting the true status of a PR (e.g., allow the
- // merge of a PR with a bad merge commit).
- //
- // Thus we need a way to prevent any CS check_runs from being updated
- // after having received a PR.
- //
- // Problem 1: Create PR from feature branch
- //
- // - Receive check_suite for commit to feature branch
- // - Receive pull_request
- //
- // Solution: When receive a PR, fetch all check_suites with that head
- // SHA (curl REPO/commits/SHA/check-suites) and cancel their CI
- // jobs.
- //
- // Thus there will be no more CS check_run updates. Note however that in
- // most cases the PR will be received long enough after the CS for the
- // latter's check_runs to all have completed already.
- //
- // Note that there will not be a merge CR on the head yet so the PR will
- // never be green.
- //
- // Problem 2: New commits are added to PR head branch
- //
- // Note: The check_suite and pull_request can arrive in any order.
- //
- // - check_suite(requested, PR_head)
- //
- // Note: check_suite.pull_requests[] will contain all PRs with this
- // branch as head.
- //
- // Note: check_suite.pull_requests[i].head.sha will be the new,
- // updated PR head sha.
- //
- // - pull_request(synchronize)
- //
- // Solution: Ignore all check_suites with non-empty pull_requests[].
- //
- // - New commits are added to PR base branch
- //
- // Note: In this case pull_request.base.sha does not change, but the merge
- // commit will be updated to include the new commits to the base branch.
+ // Remaining TODOs
//
// - @@ TODO? PR base branch changed (to a different branch)
//
@@ -769,6 +674,12 @@ namespace brep
// Note that PR rebuilds (re-requested) are handled by check_suite().
//
+ // Note that, in the case of a remote PR, GitHub will copy the PR head
+ // commit from the head (forked) repository into the base repository. So
+ // the check runs must always be added to the base repository, whether the
+ // PR is local or remote. The head commit refs are located at
+ // refs/pull/<PR-number>/head.
+ //
service_data sd (warning_success,
move (iat->token),
iat->expires_at,
@@ -900,7 +811,8 @@ namespace brep
{
// Create the CI tenant.
- // Update service data's check_sha if this is a remote PR.
+ // Set the service data's check_sha if this is a remote PR. The test
+ // merge commit refs are located at refs/pull/<PR-number>/merge.
//
if (sd.kind == service_data::remote)
sd.check_sha = *pc->merge_commit_sha;
@@ -1098,7 +1010,7 @@ namespace brep
{
string ru; // Repository URL.
- // CI the merge test commit for remote PRs and the head commit for
+ // CI the test merge commit for remote PRs and the head commit for
// everything else (branch push or local PRs).
//
if (sd.kind == service_data::remote)