Support per installation tokens directly in GitHubStatusPush

Signed-off-by: magic_rb <richard@brezak.sk>
This commit is contained in:
magic_rb 2024-07-11 20:55:12 +02:00 committed by mergify[bot]
parent 4b8c544db8
commit c3346978d5
3 changed files with 86 additions and 113 deletions

View file

@ -2,7 +2,6 @@ import json
import os
import signal
from abc import ABC, abstractmethod
from collections.abc import Callable
from dataclasses import dataclass
from itertools import starmap
from pathlib import Path
@ -257,114 +256,6 @@ class ReloadGithubProjects(ThreadDeferredBuildStep):
return util.SUCCESS
class GitHubAppStatusPush(GitHubStatusPush):
token_source: Callable[[int], RepoToken]
project_id_source: Callable[[str], int]
saved_args: dict[str, Any]
saved_kwargs: dict[str, Any]
def checkConfig(
self,
token_source: Callable[[int], RepoToken],
project_id_source: Callable[[str], int],
context: Any = None,
baseURL: Any = None,
verbose: Any = False,
debug: Any = None,
verify: Any = None,
generators: Any = None,
**kwargs: dict[str, Any],
) -> Any:
if generators is None:
generators = self._create_default_generators()
if "token" in kwargs:
del kwargs["token"]
super().checkConfig(
token="",
context=context,
baseURL=baseURL,
verbose=verbose,
debug=debug,
verify=verify,
generators=generators,
**kwargs,
)
def reconfigService(
self,
token_source: Callable[[int], RepoToken],
project_id_source: Callable[[str], int],
context: Any = None,
baseURL: Any = None,
verbose: Any = False,
debug: Any = None,
verify: Any = None,
generators: Any = None,
**kwargs: dict[str, Any],
) -> Any:
if "saved_args" not in self or self.saved_args is None:
self.saved_args = {}
self.token_source = token_source
self.project_id_source = project_id_source
self.saved_kwargs = kwargs
self.saved_args["context"] = context
self.saved_args["baseURL"] = baseURL
self.saved_args["verbose"] = verbose
self.saved_args["debug"] = debug
self.saved_args["verify"] = verify
self.saved_args["generators"] = generators
if generators is None:
generators = self._create_default_generators()
if "token" in kwargs:
del kwargs["token"]
super().reconfigService(
token="",
context=context,
baseURL=baseURL,
verbose=verbose,
debug=debug,
verify=verify,
generators=generators,
**kwargs,
)
def sendMessage(self, reports: Any) -> Any:
build = reports[0]["builds"][0]
sourcestamps = build["buildset"].get("sourcestamps")
if not sourcestamps:
return None
for sourcestamp in sourcestamps:
build["buildset"]["sourcestamps"] = [sourcestamp]
token: str
if "project" in sourcestamp and sourcestamp["project"] != "":
token = self.token_source(
self.project_id_source(sourcestamp["project"])
).get()
else:
token = ""
super().reconfigService(
token,
context=self.saved_args["context"],
baseURL=self.saved_args["baseURL"],
verbose=self.saved_args["verbose"],
debug=self.saved_args["debug"],
verify=self.saved_args["verify"],
generators=self.saved_args["generators"],
**self.saved_kwargs,
)
return super().sendMessage(reports)
return None
class GithubAuthBackend(ABC):
@abstractmethod
def get_general_token(self) -> RepoToken:
@ -496,9 +387,10 @@ class GithubAppAuthBackend(GithubAuthBackend):
return [GitHubAppSecretService(self.installation_tokens, self.jwt_token)]
def create_reporter(self) -> ReporterBase:
return GitHubAppStatusPush(
token_source=lambda iid: self.installation_tokens[iid],
project_id_source=lambda project: self.project_id_map[project],
return GitHubStatusPush(
token=lambda project: self.installation_tokens[
self.project_id_map[project]
].get(),
# Since we dynamically create build steps,
# we use `virtual_builder_name` in the webinterface
# so that we distinguish what has beeing build

View file

@ -0,0 +1,66 @@
From 65dd3e63dc0dc34a531eee703baff715ba04d0a0 Mon Sep 17 00:00:00 2001
From: magic_rb <richard@brezak.sk>
Date: Wed, 10 Jul 2024 13:00:48 +0200
Subject: [PATCH 1/3] Support per installation tokens in `GithubStatusPush`
reporter
Signed-off-by: magic_rb <richard@brezak.sk>
---
master/buildbot/reporters/github.py | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/master/buildbot/reporters/github.py b/master/buildbot/reporters/github.py
index 3873c2676..e61e6495a 100644
--- a/master/buildbot/reporters/github.py
+++ b/master/buildbot/reporters/github.py
@@ -70,7 +70,14 @@ class GitHubStatusPush(ReporterBase):
generators=None,
**kwargs,
):
- token = yield self.renderSecrets(token)
+ headers = {}
+ if not callable(token):
+ token = yield self.renderSecrets(token)
+ headers['Authorization'] = 'token ' + token
+ else:
+ self.token_cache = {}
+ self.token_source = token
+
self.debug = debug
self.verify = verify
self.verbose = verbose
@@ -89,7 +96,7 @@ class GitHubStatusPush(ReporterBase):
self._http = yield httpclientservice.HTTPClientService.getService(
self.master,
baseURL,
- headers={'Authorization': 'token ' + token, 'User-Agent': 'Buildbot'},
+ headers={'User-Agent': 'Buildbot'} | headers,
debug=self.debug,
verify=self.verify,
)
@@ -135,6 +142,11 @@ class GitHubStatusPush(ReporterBase):
txgithub is based on twisted's webclient agent, which is much less reliable and featureful
as txrequest (support for proxy, connection pool, keep alive, retry, etc)
"""
+ headers = {}
+
+ if hasattr(self, 'token_source'):
+ headers['Authorization'] = 'token ' + self.token_source(f"{repo_user}/{repo_name}")
+
payload = {'state': state}
if description is not None:
@@ -147,7 +159,9 @@ class GitHubStatusPush(ReporterBase):
payload['context'] = context
return self._http.post(
- '/'.join(['/repos', repo_user, repo_name, 'statuses', sha]), json=payload
+ '/'.join(['/repos', repo_user, repo_name, 'statuses', sha]),
+ json=payload,
+ headers=headers,
)
def is_status_2xx(self, code):
--
2.44.1

View file

@ -409,7 +409,22 @@ in
in
"${if hasSSL then "https" else "http"}://${cfg.domain}/";
dbUrl = config.services.buildbot-nix.master.dbUrl;
package = cfg.package;
package =
let
fixPatch = { patch, name }:
pkgs.runCommand "${name}.patch" { } ''
sed -r \
's~^(---|\+\+\+) (a|b)/master/(.+)$~\1 \2/\3~' \
${patch} >$out
'';
in
cfg.package.overrideAttrs (old: {
patches =
old.patches ++ [
./0001-Support-per-installation-tokens-in-GithubStatusPush-.patch #;
];
});
pythonPackages = ps: [
ps.requests
ps.treq