aboutsummaryrefslogtreecommitdiff
path: root/mod/mod-ci-github.hxx
blob: e9190656e1da7985d921a136660a72b7a4ad1491 (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
// file      : mod/mod-ci-github.hxx -*- C++ -*-
// license   : MIT; see accompanying LICENSE file

#ifndef MOD_MOD_CI_GITHUB_HXX
#define MOD_MOD_CI_GITHUB_HXX

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

#include <mod/module-options.hxx>
#include <mod/database-module.hxx>

#include <mod/ci-common.hxx>
#include <mod/tenant-service.hxx>

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

namespace brep
{
  struct service_data;

  class ci_github: public database_module,
                   private ci_start,
                   public tenant_service_build_unloaded,
                   public tenant_service_build_queued,
                   public tenant_service_build_building,
                   public tenant_service_build_built
  {
  public:
    explicit
    ci_github (tenant_service_map&);

    // Create a shallow copy (handling instance) if initialized and a deep
    // copy (context exemplar) otherwise.
    //
    explicit
    ci_github (const ci_github&, tenant_service_map&);

    virtual bool
    handle (request&, response&);

    virtual const cli::options&
    cli_options () const {return options::ci_github::description ();}

    virtual function<optional<string> (const tenant_service&)>
    build_unloaded (tenant_service&&,
                    const diag_epilogue& log_writer) const noexcept override;

    function<optional<string> (const tenant_service&)>
    build_unloaded_pre_check (tenant_service&&,
                              service_data&&,
                              const diag_epilogue&) const noexcept;

    function<optional<string> (const tenant_service&)>
    build_unloaded_load (tenant_service&&,
                         service_data&&,
                         const diag_epilogue&) const noexcept;

    virtual function<optional<string> (const tenant_service&)>
    build_queued (const tenant_service&,
                  const vector<build>&,
                  optional<build_state> initial_state,
                  const build_queued_hints&,
                  const diag_epilogue& log_writer) const noexcept override;

    virtual function<optional<string> (const tenant_service&)>
    build_building (const tenant_service&, const build&,
                    const diag_epilogue& log_writer) const noexcept override;

    virtual function<optional<string> (const tenant_service&)>
    build_built (const tenant_service&, const build&,
                 const diag_epilogue& log_writer) const noexcept override;

  private:
    virtual void
    init (cli::scanner&);

    // Handle the check_suite event `requested` and `rerequested` actions.
    //
    // If warning_success is true, then map result_status::warning to SUCCESS
    // and to FAILURE otherwise.
    //
    bool
    handle_check_suite_request (gh_check_suite_event, bool warning_success);

    // Handle the pull_request event `opened` and `synchronize` actions.
    //
    // If warning_success is true, then map result_status::warning to SUCCESS
    // and to FAILURE otherwise.
    //
    bool
    handle_pull_request (gh_pull_request_event, bool warning_success);

    // Create an unloaded CI request for a pull request. If `cancel_first` is
    // true, cancel its existing CI request first.
    //
    // Return true if an unloaded CI request was created. Ignore failure to
    // cancel because the CI request may already have been cancelled for other
    // reasons.
    //
    // After this call we will start getting the build_unloaded()
    // notifications until (1) we load the request, (2) we cancel it, or (3)
    // it gets archived after some timeout.
    //
    bool
    create_pull_request_ci (const basic_mark& error,
                            const basic_mark& warn,
                            const basic_mark& trace,
                            const service_data&,
                            const string& pull_request_node_id,
                            bool cancel_first) const;

    // Build a check run details_url for a build.
    //
    string
    details_url (const build&) const;

    optional<string>
    generate_jwt (const basic_mark& trace, const basic_mark& error) const;

    // Authenticate to GitHub as an app installation.
    //
    optional<gh_installation_access_token>
    obtain_installation_access_token (uint64_t install_id,
                                      string jwt,
                                      const basic_mark& error) const;

  private:
    shared_ptr<options::ci_github> options_;

    tenant_service_map& tenant_service_map_;
  };
}

#endif // MOD_MOD_CI_GITHUB_HXX