Merge pull request #229 from MagicRB/support-other-caches

Generalize Cachix support to `post_build_steps`
This commit is contained in:
Jörg Thalheim 2024-07-19 17:27:23 +02:00 committed by GitHub
commit 5bdbb76096
Failed to generate hash of commit
3 changed files with 120 additions and 17 deletions

View file

@ -461,7 +461,7 @@ def do_register_gcroot_if(s: steps.BuildStep) -> Generator[Any, object, Any]:
def nix_build_config( def nix_build_config(
project: GitProject, project: GitProject,
worker_names: list[str], worker_names: list[str],
cachix: CachixConfig | None = None, post_build_steps: list[steps.BuildStep],
outputs_path: Path | None = None, outputs_path: Path | None = None,
retries: int = 1, retries: int = 1,
) -> BuilderConfig: ) -> BuilderConfig:
@ -493,19 +493,7 @@ def nix_build_config(
haltOnFailure=True, haltOnFailure=True,
), ),
) )
if cachix: factory.addSteps(post_build_steps)
factory.addStep(
steps.ShellCommand(
name="Upload cachix",
env=cachix.cachix_env(),
command=[
"cachix",
"push",
cachix.name,
util.Interpolate("result-%(prop:attr)s"),
],
),
)
factory.addStep( factory.addStep(
Trigger( Trigger(
@ -638,7 +626,7 @@ def config_for_project(
nix_eval_worker_count: int, nix_eval_worker_count: int,
nix_eval_max_memory_size: int, nix_eval_max_memory_size: int,
eval_lock: MasterLock, eval_lock: MasterLock,
cachix: CachixConfig | None = None, post_build_steps: list[steps.BuildStep],
outputs_path: Path | None = None, outputs_path: Path | None = None,
build_retries: int = 1, build_retries: int = 1,
) -> None: ) -> None:
@ -716,9 +704,9 @@ def config_for_project(
nix_build_config( nix_build_config(
project, project,
worker_names, worker_names,
cachix=cachix,
outputs_path=outputs_path, outputs_path=outputs_path,
retries=build_retries, retries=build_retries,
post_build_steps=post_build_steps,
), ),
nix_skipped_build_config(project, [SKIPPED_BUILDER_NAME]), nix_skipped_build_config(project, [SKIPPED_BUILDER_NAME]),
nix_register_gcroot_config(project, worker_names), nix_register_gcroot_config(project, worker_names),
@ -871,6 +859,7 @@ class NixConfigurator(ConfiguratorBase):
nix_supported_systems: list[str], nix_supported_systems: list[str],
nix_eval_worker_count: int | None, nix_eval_worker_count: int | None,
nix_eval_max_memory_size: int, nix_eval_max_memory_size: int,
post_build_steps: list[steps.BuildStep] | None = None,
nix_workers_secret_name: str = "buildbot-nix-workers", # noqa: S107 nix_workers_secret_name: str = "buildbot-nix-workers", # noqa: S107
cachix: CachixConfig | None = None, cachix: CachixConfig | None = None,
outputs_path: str | None = None, outputs_path: str | None = None,
@ -880,6 +869,7 @@ class NixConfigurator(ConfiguratorBase):
self.nix_eval_max_memory_size = nix_eval_max_memory_size self.nix_eval_max_memory_size = nix_eval_max_memory_size
self.nix_eval_worker_count = nix_eval_worker_count self.nix_eval_worker_count = nix_eval_worker_count
self.nix_supported_systems = nix_supported_systems self.nix_supported_systems = nix_supported_systems
self.post_build_steps = post_build_steps or []
self.auth_backend = auth_backend self.auth_backend = auth_backend
self.admins = admins self.admins = admins
self.github = github self.github = github
@ -928,6 +918,20 @@ class NixConfigurator(ConfiguratorBase):
eval_lock = util.MasterLock("nix-eval") eval_lock = util.MasterLock("nix-eval")
if self.cachix is not None:
self.post_build_steps.append(
steps.ShellCommand(
name="Upload cachix",
env=self.cachix.cachix_env(),
command=[
"cachix",
"push",
self.cachix.name,
util.Interpolate("result-%(prop:attr)s"),
],
)
)
for project in projects: for project in projects:
config_for_project( config_for_project(
config, config,
@ -937,7 +941,7 @@ class NixConfigurator(ConfiguratorBase):
self.nix_eval_worker_count or multiprocessing.cpu_count(), self.nix_eval_worker_count or multiprocessing.cpu_count(),
self.nix_eval_max_memory_size, self.nix_eval_max_memory_size,
eval_lock, eval_lock,
self.cachix, self.post_build_steps,
self.outputs_path, self.outputs_path,
self.build_retries, self.build_retries,
) )

View file

@ -42,6 +42,11 @@
}; };
in in
examplesFor "x86_64-linux" // examplesFor "aarch64-linux"; examplesFor "x86_64-linux" // examplesFor "aarch64-linux";
lib = {
interpolate = value:
{ _type = "interpolate"; inherit value; };
};
}; };
perSystem = { self', pkgs, system, ... }: { perSystem = { self', pkgs, system, ... }: {
packages.default = pkgs.mkShell { packages.default = pkgs.mkShell {

View file

@ -6,6 +6,25 @@
let let
cfg = config.services.buildbot-nix.master; cfg = config.services.buildbot-nix.master;
inherit (lib) mkRemovedOptionModule mkRenamedOptionModule; inherit (lib) mkRemovedOptionModule mkRenamedOptionModule;
interpolateType =
lib.mkOptionType {
name = "interpolate";
description = ''
A type represnting a Buildbot interpolation string, supports interpolations like `result-%(prop:attr)s`.
'';
check = x:
x ? "_type" && x._type == "interpolate" && x ? "value";
};
interpolateToString =
value:
if lib.isAttrs value && value ? "_type" && value._type == "interpolate" then
"util.Interpolate(${builtins.toJSON value.value})"
else
builtins.toJSON value;
in in
{ {
imports = [ imports = [
@ -80,6 +99,60 @@ in
default = 1; default = 1;
description = "Number of times a build is retried"; description = "Number of times a build is retried";
}; };
postBuildSteps = lib.mkOption {
default = [ ];
description = ''
A list of steps to execute after every successful build.
'';
type = lib.types.listOf (lib.types.submodule {
options = {
name = lib.mkOption {
type = lib.types.str;
description = ''
The name of the build step, will show up in Buildbot's UI.
'';
};
environment = lib.mkOption {
type = with lib.types; attrsOf (oneOf [ interpolateType str ]);
description = ''
Extra environment variables to add to the environment of this build step.
The base environment is the environment of the `buildbot-worker` service.
To access the properties of a build, use the `interpolate` function defined in
`inputs.buildbot-nix.lib.interpolate` like so `(interpolate "result-%(prop:attr)s")`.
'';
default = { };
};
command = lib.mkOption {
type = with lib.types; oneOf [ str (listOf (oneOf [ str interpolateType ])) ];
description = ''
The command to execute as part of the build step. Either a single string or
a list of strings. Be careful that neither variant is interpreted by a shell,
but is passed to `execve` verbatim. If you desire a shell, you must use
`writeShellScript` or similar functions.
To access the properties of a build, use the `interpolate` function defined in
`inputs.buildbot-nix.lib.interpolate` like so `(interpolate "result-%(prop:attr)s")`.
'';
};
};
});
example = lib.literalExpression ''
[
name = "upload-to-s3";
environment = {
S3_TOKEN = "%(secret:s3-token)";
S3_BUCKET = "bucket";
};
command = [ "nix" "copy" "%result%" ];
]
'';
};
cachix = { cachix = {
name = lib.mkOption { name = lib.mkOption {
type = lib.types.nullOr lib.types.str; type = lib.types.nullOr lib.types.str;
@ -323,6 +396,10 @@ in
CachixConfig, CachixConfig,
GiteaConfig, GiteaConfig,
) )
from buildbot.plugins import (
steps,
util,
)
from buildbot_nix.github.auth._type import ( from buildbot_nix.github.auth._type import (
AuthTypeLegacy, AuthTypeLegacy,
AuthTypeApp, AuthTypeApp,
@ -389,6 +466,23 @@ in
}, },
nix_supported_systems=${builtins.toJSON cfg.buildSystems}, nix_supported_systems=${builtins.toJSON cfg.buildSystems},
outputs_path=${if cfg.outputsPath == null then "None" else builtins.toJSON cfg.outputsPath}, outputs_path=${if cfg.outputsPath == null then "None" else builtins.toJSON cfg.outputsPath},
post_build_steps=[
${lib.concatMapStringsSep ",\n" ({ name, environment, command }: ''
steps.ShellCommand(
name=${builtins.toJSON name},
env={
${lib.concatMapStringsSep ",\n" ({name, value}: ''
${name}: ${interpolateToString value}
'') (lib.mapAttrsToList lib.nameValuePair environment)}
},
command=[
${lib.concatMapStringsSep ",\n" (value:
interpolateToString value
) (if lib.isList command then command else [ command ])}
]
)
'') cfg.postBuildSteps}
]
) )
'' ''
]; ];