aboutsummaryrefslogtreecommitdiff
path: root/mod/mod-ci-github-gq.hxx
blob: c3be5006f840c9c2312d5208564d6f70c607280e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// file      : mod/mod-ci-github-gq.hxx -*- C++ -*-
// license   : MIT; see accompanying LICENSE file

#ifndef MOD_MOD_CI_GITHUB_GQ_HXX
#define MOD_MOD_CI_GITHUB_GQ_HXX

#include <libbrep/types.hxx>
#include <libbrep/utility.hxx>

#include <libbrep/build.hxx>

#include <mod/tenant-service.hxx> // build_hints

#include <mod/mod-ci-github-gh.hxx>
#include <mod/mod-ci-github-service-data.hxx>

namespace brep
{
  // GraphQL functions (all start with gq_).
  //

  // Create a new check run on GitHub for each build. Update `check_runs` with
  // the new data (node id, state, and state_synced). Return false and issue
  // diagnostics if the request failed.
  //
  // Note: no details_url yet since there will be no entry in the build result
  // search page until the task starts building.
  //
  // Note that creating a check_run named `foo` 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).
  //
  bool
  gq_create_check_runs (const basic_mark& error,
                        vector<check_run>& check_runs,
                        const string& installation_access_token,
                        const string& repository_id,
                        const string& head_sha,
                        build_state);

  // Create a new check run on GitHub for a build. Update `cr` with the new
  // data (node id, state, and state_synced). Return false and issue
  // diagnostics if the request failed.
  //
  // If the details_url is absent GitHub will use the app's homepage.
  //
  // The gq_built_result is required if the build_state is built because
  // GitHub does not allow a check run status of `completed` without at least
  // a conclusion.
  //
  struct gq_built_result
  {
    string conclusion;
    string title;
    string summary;
  };

  bool
  gq_create_check_run (const basic_mark& error,
                       check_run& cr,
                       const string& installation_access_token,
                       const string& repository_id,
                       const string& head_sha,
                       const optional<string>& details_url,
                       build_state,
                       optional<gq_built_result> = nullopt);

  // Update a check run on GitHub.
  //
  // Send a GraphQL request that updates an existing check run. Update `cr`
  // with the new data (state and state_synced). Return false and issue
  // diagnostics if the request failed.
  //
  // Note that GitHub allows any state transitions except from built (but
  // built to built is allowed). The latter case is signalled by setting the
  // check_run state_synced member to false and the state member to built.
  //
  // If the details_url is absent GitHub will use the app's homepage.
  //
  // The gq_built_result is required if the build_state is built because
  // GitHub does not allow a check run status of `completed` without at least
  // a conclusion.
  //
  bool
  gq_update_check_run (const basic_mark& error,
                       check_run& cr,
                       const string& installation_access_token,
                       const string& repository_id,
                       const string& node_id,
                       const optional<string>& details_url,
                       build_state,
                       optional<gq_built_result> = nullopt);

  // Update a check run on GitHub if node_id is present, otherwise create a
  // new check run associated with head_sha.
  //
  // This is a wrapper of gq_update_check_run() and gq_create_check_run() for
  // convenience.
  //
  bool
  gq_update_or_create_check_run (const basic_mark& error,
                                 check_run& cr,
                                 const string& installation_access_token,
                                 const string& repository_id,
                                 const optional<string>& node_id,
                                 const string& head_sha,
                                 const optional<string>& details_url,
                                 build_state,
                                 optional<gq_built_result> = nullopt);

  // Fetch pre-check information for a pull request from GitHub. This
  // information is used to decide whether or not to CI the PR and is
  // comprised of the PR's head commit SHA, whether its head branch is behind
  // its base branch, and its mergeability and test merge commit SHA.
  //
  // Return absent value if the merge commit is still being generated (which
  // means PR head branch behindness is not yet known either). See the
  // gq_pr_pre_check struct's member comments for non-absent return value
  // semantics.
  //
  // Issue diagnostics and return absent if the request failed (which means it
  // will be treated by the caller as still being generated).
  //
  // Note that the first request causes GitHub to start preparing the test
  // merge commit.
  //
  // For details regarding the test merge commit and how to check/poll for PR
  // mergeability see
  // https://docs.github.com/en/rest/pulls/pulls?#get-a-pull-request and
  // https://docs.github.com/en/rest/guides/using-the-rest-api-to-interact-with-your-git-database?#checking-mergeability-of-pull-requests
  //
  struct gq_pr_pre_check_info
  {
    // The PR head commit id.
    //
    string head_sha;

    // True if the PR's head branch is behind its base branch.
    //
    bool behind;

    // The commit id of the test merge commit. Absent if behind or the PR is
    // not auto-mergeable.
    //
    optional<string> merge_commit_sha;
  };

  optional<gq_pr_pre_check_info>
  gq_fetch_pull_request_pre_check_info (
    const basic_mark& error,
    const string& installation_access_token,
    const string& node_id);
}

#endif // MOD_MOD_CI_GITHUB_GQ_HXX