machines/magenta: add woodpecker ci service
This commit is contained in:
parent
2526dd47e3
commit
25854bc608
38 changed files with 535 additions and 31 deletions
Binary file not shown.
|
@ -6,7 +6,7 @@
|
||||||
./hardware-configuration.nix
|
./hardware-configuration.nix
|
||||||
../modules/common.nix
|
../modules/common.nix
|
||||||
../modules/sound.nix
|
../modules/sound.nix
|
||||||
../modules/window_manager.nix
|
../modules/window-manager.nix
|
||||||
../modules/fonts.nix
|
../modules/fonts.nix
|
||||||
../modules/gnupg.nix
|
../modules/gnupg.nix
|
||||||
../modules/nix.nix
|
../modules/nix.nix
|
||||||
|
|
|
@ -10,6 +10,7 @@ in
|
||||||
|
|
||||||
../modules/common.nix
|
../modules/common.nix
|
||||||
../modules/fail2ban.nix
|
../modules/fail2ban.nix
|
||||||
|
../modules/docker-swarm.nix
|
||||||
|
|
||||||
./services/wireguard.nix
|
./services/wireguard.nix
|
||||||
];
|
];
|
||||||
|
|
|
@ -6,4 +6,8 @@
|
||||||
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "xen_blkfront" "vmw_pvscsi" ];
|
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "xen_blkfront" "vmw_pvscsi" ];
|
||||||
boot.initrd.kernelModules = [ "nvme" ];
|
boot.initrd.kernelModules = [ "nvme" ];
|
||||||
fileSystems."/" = { device = "/dev/sda1"; fsType = "ext4"; };
|
fileSystems."/" = { device = "/dev/sda1"; fsType = "ext4"; };
|
||||||
|
swapDevices = [
|
||||||
|
{ device = "/dev/zram0"; }
|
||||||
|
{ device = "/var/swapfile"; size = 1536; }
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
./hardware-configuration.nix
|
./hardware-configuration.nix
|
||||||
../modules/common.nix
|
../modules/common.nix
|
||||||
../modules/sound.nix
|
../modules/sound.nix
|
||||||
../modules/window_manager.nix
|
../modules/window-manager.nix
|
||||||
../modules/fonts.nix
|
../modules/fonts.nix
|
||||||
../modules/gnupg.nix
|
../modules/gnupg.nix
|
||||||
../modules/nix.nix
|
../modules/nix.nix
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{ config, pkgs, ... }:
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
data = import ../../data.nix;
|
data = import ../../data.nix;
|
||||||
|
@ -9,13 +9,14 @@ in
|
||||||
./networking.secret.nix # generated at runtime by nixos-infect
|
./networking.secret.nix # generated at runtime by nixos-infect
|
||||||
|
|
||||||
../modules/common.nix
|
../modules/common.nix
|
||||||
../modules/nix.nix
|
|
||||||
../modules/fail2ban.nix
|
../modules/fail2ban.nix
|
||||||
../modules/garbage-collector.nix
|
../modules/garbage-collector.nix
|
||||||
|
../modules/docker-swarm.nix
|
||||||
|
|
||||||
./services/traefik.nix
|
|
||||||
./services/mailserver.nix
|
./services/mailserver.nix
|
||||||
./services/gitea.nix
|
./services/gitea.nix
|
||||||
|
./services/traefik.nix
|
||||||
|
./services/woodpecker
|
||||||
];
|
];
|
||||||
|
|
||||||
boot.kernelPackages = pkgs.linuxPackages_6_1;
|
boot.kernelPackages = pkgs.linuxPackages_6_1;
|
||||||
|
@ -33,10 +34,4 @@ in
|
||||||
defaults.email = "dmitriy@pleshevski.ru";
|
defaults.email = "dmitriy@pleshevski.ru";
|
||||||
};
|
};
|
||||||
|
|
||||||
# Enable docker
|
|
||||||
virtualisation.docker = {
|
|
||||||
enable = true;
|
|
||||||
liveRestore = false;
|
|
||||||
};
|
|
||||||
networking.firewall.allowedTCPPorts = [ 2377 ];
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,4 +6,8 @@
|
||||||
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "xen_blkfront" ];
|
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "xen_blkfront" ];
|
||||||
boot.initrd.kernelModules = [ "nvme" ];
|
boot.initrd.kernelModules = [ "nvme" ];
|
||||||
fileSystems."/" = { device = "/dev/sda1"; fsType = "ext4"; };
|
fileSystems."/" = { device = "/dev/sda1"; fsType = "ext4"; };
|
||||||
|
swapDevices = [
|
||||||
|
{ device = "/dev/zram0"; }
|
||||||
|
{ device = "/var/swapfile"; size = 1536; }
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ let
|
||||||
robotsTxt = pkgs.writeText "robots.txt" ''
|
robotsTxt = pkgs.writeText "robots.txt" ''
|
||||||
User-agent: *
|
User-agent: *
|
||||||
Disallow: /github
|
Disallow: /github
|
||||||
|
Disallow: /external
|
||||||
'';
|
'';
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
@ -105,13 +106,11 @@ in
|
||||||
'';
|
'';
|
||||||
|
|
||||||
services.traefik.dynamicConfigOptions.http = {
|
services.traefik.dynamicConfigOptions.http = {
|
||||||
routers = {
|
routers.to_gitea = {
|
||||||
to_gitea = {
|
rule = "Host(`${hostname}`)";
|
||||||
rule = "Host(`${hostname}`)";
|
entryPoints = [ "https" ];
|
||||||
entryPoints = [ "https" ];
|
tls.certResolver = "le";
|
||||||
tls.certResolver = "le";
|
service = "gitea";
|
||||||
service = "gitea";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
services.gitea = {
|
services.gitea = {
|
||||||
loadBalancer.servers = [
|
loadBalancer.servers = [
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{ config, ... }:
|
{ config, lib, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
traefikCfg = config.services.traefik;
|
traefikCfg = config.services.traefik;
|
||||||
|
@ -14,6 +14,8 @@ in
|
||||||
inherit (traefikCfg) group;
|
inherit (traefikCfg) group;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
users.groups.docker.members = [ "traefik" ];
|
||||||
|
|
||||||
services.traefik = {
|
services.traefik = {
|
||||||
enable = true;
|
enable = true;
|
||||||
staticConfigOptions = {
|
staticConfigOptions = {
|
||||||
|
@ -36,21 +38,26 @@ in
|
||||||
email = "dmitriy@pleshevski.ru";
|
email = "dmitriy@pleshevski.ru";
|
||||||
tlschallenge = true;
|
tlschallenge = true;
|
||||||
};
|
};
|
||||||
|
providers.docker = {
|
||||||
|
network = "rp_public";
|
||||||
|
constraints = "Label(`traefik.constraint-label`, `${config.networking.hostName}_public`)";
|
||||||
|
exposedByDefault = false;
|
||||||
|
swarmMode = true;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
dynamicConfigOptions = {
|
dynamicConfigOptions.http = {
|
||||||
http = {
|
routers.to_traefik_dashboard = {
|
||||||
routers.to_traefik_dashboard = {
|
rule = "Host(`${magentaData.addr}`)";
|
||||||
rule = "Host(`${magentaData.addr}`)";
|
entryPoints = [ "dashboard" ];
|
||||||
entryPoints = [ "dashboard" ];
|
middlewares = [ "traefik_dashboard_auth" ];
|
||||||
middlewares = [ "traefik_dashboard_auth" ];
|
service = "api@internal";
|
||||||
service = "api@internal";
|
};
|
||||||
};
|
middlewares = {
|
||||||
middlewares = {
|
traefik_dashboard_auth.basicAuth = {
|
||||||
traefik_dashboard_auth.basicAuth = {
|
usersFile = config.age.secrets.traefik-dashboard-basicauth-users.path;
|
||||||
usersFile = config.age.secrets.traefik-dashboard-basicauth-users.path;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
37
machines/magenta/services/woodpecker/agent-docker.nix
Normal file
37
machines/magenta/services/woodpecker/agent-docker.nix
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
{ pkgs, config, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
nextPkgs = pkgs.callPackage ../../../../packages/woodpecker { };
|
||||||
|
|
||||||
|
canigouData = import ../../data.secret.nix;
|
||||||
|
|
||||||
|
data = import ./data.secret.nix;
|
||||||
|
inherit (data) userAgent group grpcPort;
|
||||||
|
|
||||||
|
dockerSockVolume = "/var/run/docker.sock:/var/run/docker.sock";
|
||||||
|
dockerConfVolume = "${config.age.secrets.woodpecker-docker-config.path}:/root/.docker/config.json";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
systemd.services.woodpecker-agent = {
|
||||||
|
enable = true;
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "woodpecker-server.service" ];
|
||||||
|
restartIfChanged = true;
|
||||||
|
serviceConfig = {
|
||||||
|
EnvironmentFile = [
|
||||||
|
config.age.secrets.woodpecker-common-env.path
|
||||||
|
];
|
||||||
|
Environment = [
|
||||||
|
"WOODPECKER_DEBUG_PRETTY=true"
|
||||||
|
"WOODPECKER_LOG_LEVEL=trace"
|
||||||
|
"WOODPECKER_SERVER=${canigouData.addr}:${toString grpcPort}"
|
||||||
|
"WOODPECKER_MAX_WORKFLOWS=2"
|
||||||
|
"WOODPECKER_BACKEND=docker"
|
||||||
|
"WOODPECKER_BACKEND_DOCKER_VOLUMES=${dockerSockVolume},${dockerConfVolume}"
|
||||||
|
];
|
||||||
|
ExecStart = "${nextPkgs.woodpecker-agent}/bin/woodpecker-agent";
|
||||||
|
User = userAgent;
|
||||||
|
Group = group;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
28
machines/magenta/services/woodpecker/common.nix
Normal file
28
machines/magenta/services/woodpecker/common.nix
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
let
|
||||||
|
data = import ./data.secret.nix;
|
||||||
|
inherit (data) userServer userAgent group;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
users.groups.${group} = { };
|
||||||
|
|
||||||
|
users.users.${userServer} = {
|
||||||
|
description = "Woodpecker CI Server";
|
||||||
|
isSystemUser = true;
|
||||||
|
createHome = true;
|
||||||
|
inherit group;
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users.${userAgent} = {
|
||||||
|
isSystemUser = true;
|
||||||
|
inherit group;
|
||||||
|
};
|
||||||
|
users.groups.docker.members = [ userAgent userServer ];
|
||||||
|
|
||||||
|
age.secrets.woodpecker-common-env.file = ../../../../secrets/woodpecker-common-env.age;
|
||||||
|
age.secrets.woodpecker-server-env.file = ../../../../secrets/woodpecker-server-env.age;
|
||||||
|
age.secrets.woodpecker-docker-config = {
|
||||||
|
file = ../../../../secrets/docker-config.json.age;
|
||||||
|
mode = "440";
|
||||||
|
inherit group;
|
||||||
|
};
|
||||||
|
}
|
BIN
machines/magenta/services/woodpecker/data.secret.nix
Normal file
BIN
machines/magenta/services/woodpecker/data.secret.nix
Normal file
Binary file not shown.
9
machines/magenta/services/woodpecker/default.nix
Normal file
9
machines/magenta/services/woodpecker/default.nix
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{ ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./common.nix
|
||||||
|
./agent-docker.nix
|
||||||
|
./server.nix
|
||||||
|
];
|
||||||
|
}
|
69
machines/magenta/services/woodpecker/server.nix
Normal file
69
machines/magenta/services/woodpecker/server.nix
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
# https://github.com/Mic92/dotfiles/tree/035a2c22e161f4fbe4fcbd038c6464028ddce619/nixos/eve/modules/woodpecker
|
||||||
|
{ pkgs, config, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
nextPkgs = pkgs.callPackage ../../../../packages/woodpecker { };
|
||||||
|
|
||||||
|
data = import ./data.secret.nix;
|
||||||
|
inherit (data) hostname port grpcPort userServer group database;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
networking.firewall.allowedTCPPorts = [ port grpcPort ];
|
||||||
|
|
||||||
|
services.postgresql.enable = true;
|
||||||
|
|
||||||
|
systemd.services.woodpecker-server = {
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "network.target" "postgresql.service" ];
|
||||||
|
serviceConfig = {
|
||||||
|
# See: https://woodpecker-ci.org/docs/administration/server-config
|
||||||
|
EnvironmentFile = [
|
||||||
|
config.age.secrets.woodpecker-common-env.path
|
||||||
|
config.age.secrets.woodpecker-server-env.path
|
||||||
|
];
|
||||||
|
Environment = [
|
||||||
|
"WOODPECKER_DEBUG_PRETTY=true"
|
||||||
|
"WOODPECKER_LOG_LEVEL=trace"
|
||||||
|
"WOODPECKER_HOST=https://${hostname}"
|
||||||
|
"WOODPECKER_SERVER_ADDR=:${toString port}"
|
||||||
|
"WOODPECKER_GRPC_ADDR=:${toString grpcPort}"
|
||||||
|
"WOODPECKER_ADMIN=pleshevskiy"
|
||||||
|
"WOODPECKER_DATABASE_DRIVER=postgres"
|
||||||
|
"WOODPECKER_DATABASE_DATASOURCE=postgres://${userServer}@:${toString config.services.postgresql.port}/${database}?host=/run/postgresql"
|
||||||
|
"WOODPECKER_GITEA=true"
|
||||||
|
"WOODPECKER_GITEA_URL=https://git.pleshevski.ru"
|
||||||
|
"WOODPECKER_DOCKER_CONFIG=${config.age.secrets.woodpecker-docker-config.path}"
|
||||||
|
"WOODPECKER_AUTHENTICATE_PUBLIC_REPOS=true"
|
||||||
|
];
|
||||||
|
ExecStart = "${nextPkgs.woodpecker-server}/bin/woodpecker-server";
|
||||||
|
User = userServer;
|
||||||
|
Group = group;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.postgresql = {
|
||||||
|
ensureDatabases = [ database ];
|
||||||
|
ensureUsers = [
|
||||||
|
{
|
||||||
|
name = userServer;
|
||||||
|
ensurePermissions = {
|
||||||
|
"DATABASE ${database}" = "ALL PRIVILEGES";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.traefik.dynamicConfigOptions.http = {
|
||||||
|
routers.to_woodpecker_server = {
|
||||||
|
rule = "Host(`${hostname}`)";
|
||||||
|
entryPoints = [ "https" ];
|
||||||
|
tls.certResolver = "le";
|
||||||
|
service = "woodpecker_server";
|
||||||
|
};
|
||||||
|
services.woodpecker_server = {
|
||||||
|
loadBalancer.servers = [
|
||||||
|
{ url = "http://localhost:${toString port}"; }
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
14
machines/modules/docker-swarm.nix
Normal file
14
machines/modules/docker-swarm.nix
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{ ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# Enable docker
|
||||||
|
virtualisation.docker = {
|
||||||
|
enable = true;
|
||||||
|
liveRestore = false;
|
||||||
|
};
|
||||||
|
# Source: https://forums.docker.com/t/error-response-from-daemon-rpc-error-code-unavailable-desc-grpc-the-connection-is-unavailable/39066/12
|
||||||
|
networking.firewall = {
|
||||||
|
allowedTCPPorts = [ 2376 2377 7946 ];
|
||||||
|
allowedUDPPorts = [ 7946 4789 ];
|
||||||
|
};
|
||||||
|
}
|
70
machines/modules/traefik.nix
Normal file
70
machines/modules/traefik.nix
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.local.traefik;
|
||||||
|
|
||||||
|
traefikCfg = config.services.traefik;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.local.traefik = with lib; {
|
||||||
|
enable = mkEnableOption "Enable traefik service";
|
||||||
|
dashboard = {
|
||||||
|
enable = mkEnableOption "Enable traefik dashboard";
|
||||||
|
host = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
description = "Traefik dashboard host";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
networking.firewall.allowedTCPPorts = [ 80 443 ] ++ lib.optional cfg.dashboard.enable 8080;
|
||||||
|
|
||||||
|
services.traefik = {
|
||||||
|
enable = true;
|
||||||
|
staticConfigOptions = {
|
||||||
|
entryPoints = {
|
||||||
|
http = {
|
||||||
|
address = ":80";
|
||||||
|
http.redirections.entryPoint = {
|
||||||
|
to = "https";
|
||||||
|
scheme = "https";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
https.address = ":443";
|
||||||
|
};
|
||||||
|
log = { };
|
||||||
|
accessLog = { };
|
||||||
|
certificatesResolvers.le.acme = {
|
||||||
|
storage = "${traefikCfg.dataDir}/acme.json";
|
||||||
|
email = "dmitriy@pleshevski.ru";
|
||||||
|
tlschallenge = true;
|
||||||
|
};
|
||||||
|
providers.docker = {
|
||||||
|
network = "rp_public";
|
||||||
|
constraints = "Label(`traefik.constraint-label`, `${config.networking.hostName}_public`)";
|
||||||
|
exposedByDefault = false;
|
||||||
|
swarmMode = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} // lib.mkIf cfg.dashboard.enable {
|
||||||
|
staticConfigOptions = {
|
||||||
|
api = { };
|
||||||
|
entryPoints.dashboard.address = ":8080";
|
||||||
|
};
|
||||||
|
dynamicConfigOptions.http = {
|
||||||
|
routers.to_traefik_dashboard = {
|
||||||
|
rule = "Host(`${cfg.dashboard.host}`)";
|
||||||
|
entryPoints = [ "dashboard" ];
|
||||||
|
middlewares = [ "traefik_dashboard_auth" ];
|
||||||
|
service = "api@internal";
|
||||||
|
};
|
||||||
|
middlewares = {
|
||||||
|
traefik_dashboard_auth.basicAuth = {
|
||||||
|
usersFile = config.age.secrets.traefik-dashboard-basicauth-users.path;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
17
packages/woodpecker/agent.nix
Normal file
17
packages/woodpecker/agent.nix
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
{ lib, buildGoModule, callPackage, fetchFromGitHub }:
|
||||||
|
let
|
||||||
|
common = callPackage ./common.nix { };
|
||||||
|
in
|
||||||
|
buildGoModule {
|
||||||
|
pname = "woodpecker-agent";
|
||||||
|
inherit (common) version src ldflags postBuild;
|
||||||
|
vendorSha256 = null;
|
||||||
|
|
||||||
|
subPackages = "cmd/agent";
|
||||||
|
|
||||||
|
CGO_ENABLED = 0;
|
||||||
|
|
||||||
|
meta = common.meta // {
|
||||||
|
description = "Woodpecker Continuous Integration agent";
|
||||||
|
};
|
||||||
|
}
|
17
packages/woodpecker/cli.nix
Normal file
17
packages/woodpecker/cli.nix
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
{ lib, buildGoModule, callPackage, fetchFromGitHub }:
|
||||||
|
let
|
||||||
|
common = callPackage ./common.nix { };
|
||||||
|
in
|
||||||
|
buildGoModule {
|
||||||
|
pname = "woodpecker-cli";
|
||||||
|
inherit (common) version src ldflags postBuild;
|
||||||
|
vendorSha256 = null;
|
||||||
|
|
||||||
|
subPackages = "cmd/cli";
|
||||||
|
|
||||||
|
CGO_ENABLED = 0;
|
||||||
|
|
||||||
|
meta = common.meta // {
|
||||||
|
description = "Command line client for the Woodpecker Continuous Integration server";
|
||||||
|
};
|
||||||
|
}
|
37
packages/woodpecker/common.nix
Normal file
37
packages/woodpecker/common.nix
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
{ lib, fetchFromGitea }:
|
||||||
|
let
|
||||||
|
version = "13f878c10ac77d16ddae994b9253fa8c23c4d5be";
|
||||||
|
srcSha256 = "sha256-ifyQK3eCThNPu3Qnfy6WUYba5qvop+6VJmwpWcpWJVE=";
|
||||||
|
yarnSha256 = "sha256-XsyMw2xqTjng4DoeiUb2+pJ9rGtHw2yZgy7pzLSDkas=";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
inherit version yarnSha256;
|
||||||
|
|
||||||
|
src = fetchFromGitea {
|
||||||
|
domain = "git.pleshevski.ru";
|
||||||
|
owner = "infra";
|
||||||
|
repo = "woodpecker";
|
||||||
|
rev = version;
|
||||||
|
sha256 = srcSha256;
|
||||||
|
};
|
||||||
|
|
||||||
|
postBuild = ''
|
||||||
|
cd $GOPATH/bin
|
||||||
|
for f in *; do
|
||||||
|
mv -- "$f" "woodpecker-$f"
|
||||||
|
done
|
||||||
|
cd -
|
||||||
|
'';
|
||||||
|
|
||||||
|
ldflags = [
|
||||||
|
"-s"
|
||||||
|
"-w"
|
||||||
|
"-X github.com/woodpecker-ci/woodpecker/version.Version=next"
|
||||||
|
];
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
homepage = "https://woodpecker-ci.org/";
|
||||||
|
license = licenses.asl20;
|
||||||
|
maintainers = with maintainers; [ ambroisie techknowlogick ];
|
||||||
|
};
|
||||||
|
}
|
11
packages/woodpecker/default.nix
Normal file
11
packages/woodpecker/default.nix
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{ callPackage }:
|
||||||
|
|
||||||
|
{
|
||||||
|
woodpecker-agent = callPackage ./agent.nix { };
|
||||||
|
|
||||||
|
woodpecker-cli = callPackage ./cli.nix { };
|
||||||
|
|
||||||
|
woodpecker-server = callPackage ./server.nix {
|
||||||
|
woodpecker-frontend = callPackage ./frontend.nix { };
|
||||||
|
};
|
||||||
|
}
|
40
packages/woodpecker/frontend.nix
Normal file
40
packages/woodpecker/frontend.nix
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
{ lib, callPackage, fetchFromGitHub, fetchYarnDeps, mkYarnPackage }:
|
||||||
|
let
|
||||||
|
common = callPackage ./common.nix { };
|
||||||
|
in
|
||||||
|
mkYarnPackage {
|
||||||
|
pname = "woodpecker-frontend";
|
||||||
|
inherit (common) version;
|
||||||
|
|
||||||
|
src = "${common.src}/web";
|
||||||
|
|
||||||
|
packageJSON = ./woodpecker-package.json;
|
||||||
|
offlineCache = fetchYarnDeps {
|
||||||
|
yarnLock = "${common.src}/web/yarn.lock";
|
||||||
|
sha256 = common.yarnSha256;
|
||||||
|
};
|
||||||
|
|
||||||
|
buildPhase = ''
|
||||||
|
runHook preBuild
|
||||||
|
|
||||||
|
yarn build
|
||||||
|
|
||||||
|
runHook postBuild
|
||||||
|
'';
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
runHook preInstall
|
||||||
|
|
||||||
|
cp -R deps/woodpecker-ci/dist $out
|
||||||
|
echo "${common.version}" > "$out/version"
|
||||||
|
|
||||||
|
runHook postInstall
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Do not attempt generating a tarball for woodpecker-frontend again.
|
||||||
|
doDist = false;
|
||||||
|
|
||||||
|
meta = common.meta // {
|
||||||
|
description = "Woodpecker Continuous Integration server frontend";
|
||||||
|
};
|
||||||
|
}
|
27
packages/woodpecker/server.nix
Normal file
27
packages/woodpecker/server.nix
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{ lib, buildGoModule, callPackage, fetchFromGitHub, woodpecker-frontend }:
|
||||||
|
let
|
||||||
|
common = callPackage ./common.nix { };
|
||||||
|
in
|
||||||
|
buildGoModule {
|
||||||
|
pname = "woodpecker-server";
|
||||||
|
inherit (common) version src ldflags postBuild;
|
||||||
|
vendorSha256 = null;
|
||||||
|
|
||||||
|
postPatch = ''
|
||||||
|
cp -r ${woodpecker-frontend} web/dist
|
||||||
|
'';
|
||||||
|
|
||||||
|
subPackages = "cmd/server";
|
||||||
|
|
||||||
|
CGO_ENABLED = 1;
|
||||||
|
|
||||||
|
passthru = {
|
||||||
|
inherit woodpecker-frontend;
|
||||||
|
|
||||||
|
updateScript = ./update.sh;
|
||||||
|
};
|
||||||
|
|
||||||
|
meta = common.meta // {
|
||||||
|
description = "Woodpecker Continuous Integration server";
|
||||||
|
};
|
||||||
|
}
|
47
packages/woodpecker/update.sh
Executable file
47
packages/woodpecker/update.sh
Executable file
|
@ -0,0 +1,47 @@
|
||||||
|
#!/usr/bin/env nix-shell
|
||||||
|
#!nix-shell -i bash -p wget prefetch-yarn-deps nix-prefetch-git jq
|
||||||
|
|
||||||
|
# shellcheck shell=bash
|
||||||
|
|
||||||
|
if [ -n "$GITHUB_TOKEN" ]; then
|
||||||
|
TOKEN_ARGS=(--header "Authorization: token $GITHUB_TOKEN")
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $# -gt 1 || $1 == -* ]]; then
|
||||||
|
echo "Regenerates packaging data for the woodpecker packages."
|
||||||
|
echo "Usage: $0 <rev>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
set -x
|
||||||
|
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
version="$1"
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if [ -z "$version" ]; then
|
||||||
|
echo "Usage: $0 <rev>"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Woodpecker repository
|
||||||
|
src_hash=$(nix-prefetch-git --url https://git.pleshevski.ru/infra/woodpecker --rev "${version}" | jq -r .sha256)
|
||||||
|
|
||||||
|
# Front-end dependencies
|
||||||
|
woodpecker_src="https://git.pleshevski.ru/infra/woodpecker/raw/$version"
|
||||||
|
wget "${TOKEN_ARGS[@]}" "$woodpecker_src/web/package.json" -O woodpecker-package.json
|
||||||
|
|
||||||
|
web_tmpdir=$(mktemp -d)
|
||||||
|
trap 'rm -rf "$web_tmpdir"' EXIT
|
||||||
|
pushd "$web_tmpdir"
|
||||||
|
wget "${TOKEN_ARGS[@]}" "$woodpecker_src/web/yarn.lock"
|
||||||
|
yarn_hash=$(prefetch-yarn-deps yarn.lock)
|
||||||
|
popd
|
||||||
|
|
||||||
|
# Use friendlier hashes
|
||||||
|
src_hash=$(nix hash to-sri --type sha256 "$src_hash")
|
||||||
|
yarn_hash=$(nix hash to-sri --type sha256 "$yarn_hash")
|
||||||
|
|
||||||
|
sed -i -E -e "s#version = \".*\"#version = \"$version\"#" common.nix
|
||||||
|
sed -i -E -e "s#srcSha256 = \".*\"#srcSha256 = \"$src_hash\"#" common.nix
|
||||||
|
sed -i -E -e "s#yarnSha256 = \".*\"#yarnSha256 = \"$yarn_hash\"#" common.nix
|
71
packages/woodpecker/woodpecker-package.json
Normal file
71
packages/woodpecker/woodpecker-package.json
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
{
|
||||||
|
"name": "woodpecker-ci",
|
||||||
|
"author": "Woodpecker CI",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"start": "vite",
|
||||||
|
"build": "vite build",
|
||||||
|
"serve": "vite preview",
|
||||||
|
"lint": "eslint --max-warnings 0 --ext .js,.ts,.vue,.json .",
|
||||||
|
"formatcheck": "prettier -c .",
|
||||||
|
"format:fix": "prettier --write .",
|
||||||
|
"typecheck": "vue-tsc --noEmit",
|
||||||
|
"test": "echo 'No tests configured' && exit 0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@intlify/vite-plugin-vue-i18n": "^6.0.3",
|
||||||
|
"@kyvg/vue3-notification": "^2.4.1",
|
||||||
|
"@vueuse/core": "^9.3.1",
|
||||||
|
"ansi_up": "^5.1.0",
|
||||||
|
"dayjs": "^1.11.5",
|
||||||
|
"floating-vue": "^2.0.0-beta.20",
|
||||||
|
"fuse.js": "^6.6.2",
|
||||||
|
"humanize-duration": "^3.27.3",
|
||||||
|
"javascript-time-ago": "^2.5.7",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
|
"node-emoji": "^1.11.0",
|
||||||
|
"pinia": "^2.0.23",
|
||||||
|
"prismjs": "^1.29.0",
|
||||||
|
"vue": "^3.2.41",
|
||||||
|
"vue-i18n": "^9.2.2",
|
||||||
|
"vue-router": "^4.1.5"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@iconify/json": "^2.1.123",
|
||||||
|
"@types/humanize-duration": "^3.27.1",
|
||||||
|
"@types/javascript-time-ago": "^2.0.3",
|
||||||
|
"@types/lodash": "^4.14.186",
|
||||||
|
"@types/node": "^18.11.2",
|
||||||
|
"@types/node-emoji": "^1.8.2",
|
||||||
|
"@types/prismjs": "^1.26.0",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^5.40.1",
|
||||||
|
"@typescript-eslint/parser": "^5.40.1",
|
||||||
|
"@vitejs/plugin-vue": "^3.1.2",
|
||||||
|
"@vue/compiler-sfc": "^3.2.41",
|
||||||
|
"eslint": "^8.25.0",
|
||||||
|
"eslint-config-airbnb-base": "^15.0.0",
|
||||||
|
"eslint-config-airbnb-typescript": "^17.0.0",
|
||||||
|
"eslint-config-prettier": "^8.5.0",
|
||||||
|
"eslint-plugin-import": "^2.26.0",
|
||||||
|
"eslint-plugin-prettier": "^4.2.1",
|
||||||
|
"eslint-plugin-promise": "^6.1.0",
|
||||||
|
"eslint-plugin-simple-import-sort": "^8.0.0",
|
||||||
|
"eslint-plugin-vue": "^9.6.0",
|
||||||
|
"eslint-plugin-vue-scoped-css": "^2.2.0",
|
||||||
|
"prettier": "^2.7.1",
|
||||||
|
"typescript": "4.8.3",
|
||||||
|
"unplugin-icons": "^0.14.12",
|
||||||
|
"unplugin-vue-components": "^0.22.8",
|
||||||
|
"vite": "^3.1.8",
|
||||||
|
"vite-plugin-prismjs": "^0.0.8",
|
||||||
|
"vite-plugin-windicss": "^1.8.8",
|
||||||
|
"vite-svg-loader": "^3.6.0",
|
||||||
|
"vue-eslint-parser": "^9.1.0",
|
||||||
|
"vue-tsc": "^0.40.13",
|
||||||
|
"windicss": "^3.5.6"
|
||||||
|
}
|
||||||
|
}
|
BIN
secrets/docker-config.json.age
Normal file
BIN
secrets/docker-config.json.age
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
secrets/woodpecker-common-env.age
Normal file
BIN
secrets/woodpecker-common-env.age
Normal file
Binary file not shown.
BIN
secrets/woodpecker-server-env.age
Normal file
BIN
secrets/woodpecker-server-env.age
Normal file
Binary file not shown.
Loading…
Reference in a new issue