buildbot: init #68
|
@ -37,6 +37,10 @@ in
|
||||||
services.nginx.virtualHosts.${cfg.domain} = {
|
services.nginx.virtualHosts.${cfg.domain} = {
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
|
extraConfig = ''
|
||||||
|
add_header Access-Control-Allow-Credentials 'true' always;
|
||||||
|
add_header Access-Control-Allow-Origin 'https://cl.forkos.org' always;
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
services.buildbot-nix.worker = {
|
services.buildbot-nix.worker = {
|
||||||
|
|
113
services/gerrit/checks.js
Normal file
113
services/gerrit/checks.js
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
/* Inspired from the Lix setup.
|
||||||
|
* Original-Author: puckipedia
|
||||||
|
*/
|
||||||
|
Gerrit.install((plugin) => {
|
||||||
|
// TODO: can we just use `plugin.serverInfo().plugin` and control the settings over there.
|
||||||
|
const configuration = {
|
||||||
|
baseUri: @BASE_URI@,
|
||||||
|
supportedProjects: @SUPPORTED_PROJECTS@,
|
||||||
|
};
|
||||||
|
|
||||||
|
function makeBuildbotUri(suffix) {
|
||||||
|
return `${configuration.baseUri}/${suffix}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
let builders = [];
|
||||||
|
let fetchBuilders = async () => {
|
||||||
|
if (builders.length > 0) return;
|
||||||
|
let data = await (await fetch(makeBuildbotUri(`api/v2/builders`), { credentials: 'include' })).json();
|
||||||
|
builders = data.builders;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
let checksProvider;
|
||||||
|
checksProvider = {
|
||||||
|
async fetch({ repo, patchsetSha, changeNumber, patchsetNumber }, runBefore = false) {
|
||||||
|
if (!configuration.supportedProjects.includes(repo)) {
|
||||||
|
return { responseCode: 'OK' };
|
||||||
|
}
|
||||||
|
|
||||||
|
let num = changeNumber.toString(10);
|
||||||
|
|
||||||
|
let branch = `refs/changes/${num.substr(-2)}/${num}/${patchsetNumber}`;
|
||||||
|
|
||||||
|
let changeFetch = await fetch(makeBuildbotUri(`api/v2/changes?limit=1&order=-changeid&revision=${patchsetSha}&branch=${branch}`), { credentials: 'include' });
|
||||||
|
if (changeFetch.status == 400) {
|
||||||
|
if ((await changeFetch.json()).error === 'invalid origin' && !runBefore) {
|
||||||
|
return await checksProvider.fetch({ repo, patchsetSha, changeNumber, patchsetNumber }, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return { responseCode: 'OK' };
|
||||||
|
} else if (changeFetch.status === 403) {
|
||||||
|
return { responseCode: 'NOT_LOGGED_IN', loginCallback() {
|
||||||
|
window.open(configuration.baseUri);
|
||||||
|
} };
|
||||||
|
}
|
||||||
|
|
||||||
|
let changes = await changeFetch.json();
|
||||||
|
if (changes.meta.total === 0) {
|
||||||
|
return { responseCode: 'OK' };
|
||||||
|
}
|
||||||
|
|
||||||
|
let { changeid } = changes.changes[0];
|
||||||
|
let { builds } = await (await fetch(makeBuildbotUri(`api/v2/changes/${changeid}/builds?property=owners&property=workername`), { credentials: 'include' })).json();
|
||||||
|
await fetchBuilders();
|
||||||
|
let links = [];
|
||||||
|
let runs = [];
|
||||||
|
for (let build of builds) {
|
||||||
|
let name = `unknown builder ${build.builderid}`;
|
||||||
|
for (let builder of builders) {
|
||||||
|
if (builder.builderid === build.builderid) {
|
||||||
|
name = builder.name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name === `${repo}/nix-eval`) {
|
||||||
|
links.push({
|
||||||
|
url: makeBuildbotUri(`#/builders/${build.builderid}/builds/${build.number}`),
|
||||||
|
primary: true,
|
||||||
|
icon: 'external',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let checkrun = {
|
||||||
|
attempt: build.buildrequestid,
|
||||||
|
// FIXME: generalize this accordingly once auto-discovery is available.
|
||||||
|
checkName: name.replace(/^hydraJobs\./, ''),
|
||||||
|
externalId: build.buildrequestid.toString(),
|
||||||
|
status: build.complete ? 'COMPLETED' : (typeof build.started_at !== 'number' ? 'SCHEDULED' : 'RUNNING'),
|
||||||
|
checkLink: makeBuildbotUri(`#/builders/${build.builderid}/builds/${build.number}`),
|
||||||
|
labelName: 'Verified',
|
||||||
|
results: [],
|
||||||
|
links: [{
|
||||||
|
url: makeBuildbotUri(`#/builders/${build.builderid}/builds/${build.number}`),
|
||||||
|
primary: true,
|
||||||
|
icon: 'external',
|
||||||
|
}],
|
||||||
|
};
|
||||||
|
|
||||||
|
if (build.started_at !== null) {
|
||||||
|
checkrun.startedTimestamp = new Date(build.started_at * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (build.complete_at !== null) {
|
||||||
|
checkrun.finishedTimestamp = new Date(build.complete_at * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (build.results !== null) {
|
||||||
|
checkrun.results = [{
|
||||||
|
category: build.results < 2 ? 'SUCCESS' : 'ERROR',
|
||||||
|
summary: build.state_string,
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
runs.push(checkrun);
|
||||||
|
}
|
||||||
|
|
||||||
|
return { responseCode: 'OK', runs, links };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
plugin.checks().register(checksProvider);
|
||||||
|
});
|
|
@ -72,6 +72,21 @@ in
|
||||||
plugins = with pkgs.gerritPlugins; [
|
plugins = with pkgs.gerritPlugins; [
|
||||||
oauth
|
oauth
|
||||||
metrics-reporter-prometheus
|
metrics-reporter-prometheus
|
||||||
|
# Buildbot checks plugin (writeText because services.gerrit.plugins expects packages)
|
||||||
|
(pkgs.runCommand "checks.js" {
|
||||||
|
BASE_URI = builtins.toJSON "https://buildbot.forkos.org";
|
||||||
|
SUPPORTED_PROJECTS = builtins.toJSON [
|
||||||
|
"infra"
|
||||||
|
"nixpkgs"
|
||||||
|
"buildbot-test"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
''
|
||||||
|
echo "configuring buildbot checks plugin for $BASE_URI with $SUPPORTED_PROJECTS project list"
|
||||||
|
substitute ${./checks.js} $out \
|
||||||
|
--replace-fail "@BASE_URI@" "$BASE_URI" \
|
||||||
|
--replace-fail "@SUPPORTED_PROJECTS@" "$SUPPORTED_PROJECTS"
|
||||||
|
'')
|
||||||
];
|
];
|
||||||
|
|
||||||
package = pkgs.gerrit;
|
package = pkgs.gerrit;
|
||||||
|
@ -126,7 +141,7 @@ in
|
||||||
# Other settings
|
# Other settings
|
||||||
log.jsonLogging = true;
|
log.jsonLogging = true;
|
||||||
log.textLogging = false;
|
log.textLogging = false;
|
||||||
sshd.advertisedAddress = "${cfg.canonicalDomain}:${cfg.port}";
|
sshd.advertisedAddress = "${cfg.canonicalDomain}:${toString cfg.port}";
|
||||||
cache.web_sessions.maxAge = "3 months";
|
cache.web_sessions.maxAge = "3 months";
|
||||||
plugins.allowRemoteAdmin = false;
|
plugins.allowRemoteAdmin = false;
|
||||||
change.enableAttentionSet = true;
|
change.enableAttentionSet = true;
|
||||||
|
|
Loading…
Reference in a new issue