71ec9709a8
The payload (pure-stdlib bridge.py + a stock CPython closure) is fully Nix-expressible, so this is NOT an escape-hatch/buildkit repo: both arches build on emmett (amd64 native + arm64 pkgsCross of stock python3 from the binary cache) with no buildkit, qemu, docker daemon, or howard pin. Replace the partial amd64-only scaffold with parity-lib's mkNix2ContainerPublish, completing the arm64 leg + multi-arch index. The per-arch nix2container image derivations are kept verbatim; stage/publish/ publish-index/publish/push-staged now come from the shared builder so CI and local invoke identical code. Thin .woodpecker.yaml to a single nix run .#publish; retire the buildx/remote-builder steps. The Dockerfile is now unused (the cutover drops it) but kept in-tree so the server-side hadolint pre-receive hook does not crash on a file deletion. Refs cluster #192, emmett#44.
133 lines
5.4 KiB
Nix
133 lines
5.4 KiB
Nix
{
|
|
description = "alertmanager-gotify-bridge — pure-stdlib Python forwarder, containerized with Nix (nix2container), multi-arch via the shared parity-lib OCI builder.";
|
|
|
|
# ──────────────────────────────────────────────────────────────────────────
|
|
# LOCAL-PIPELINE PARITY (cluster #192, emmett#44). Archetype: nix2container OCI
|
|
# image (NOT a buildkit/escape-hatch repo — the whole payload is Nix-
|
|
# expressible). The payload is pure-stdlib `bridge.py` next to a stock CPython
|
|
# closure, so BOTH arches build on emmett with no buildkit / qemu / docker:
|
|
# amd64 = native, arm64 = pkgsCross of stock python3 from the binary cache.
|
|
# The per-arch image derivations are kept verbatim; the stage/publish/
|
|
# publish-index/publish/push-staged apps come from parity-lib's
|
|
# mkNix2ContainerPublish so CI and local invoke the SAME code and cannot drift.
|
|
# ci/MIGRATION.md is the design history.
|
|
# ──────────────────────────────────────────────────────────────────────────
|
|
|
|
inputs = {
|
|
fleet.url = "git+https://git.oleks.space/oleks/fleet-pins";
|
|
nixpkgs.follows = "fleet/nixpkgs-projects";
|
|
|
|
nix2container.url = "github:nlewo/nix2container";
|
|
nix2container.inputs.nixpkgs.follows = "nixpkgs";
|
|
|
|
parity.url = "git+https://git.oleks.space/oleks/parity-lib";
|
|
|
|
flake-utils.url = "github:numtide/flake-utils";
|
|
};
|
|
|
|
outputs =
|
|
{
|
|
nixpkgs,
|
|
nix2container,
|
|
parity,
|
|
flake-utils,
|
|
...
|
|
}:
|
|
flake-utils.lib.eachDefaultSystem (
|
|
system:
|
|
let
|
|
pkgs = import nixpkgs { inherit system; };
|
|
n2c = nix2container.packages.${system}.nix2container;
|
|
|
|
registry = "git.oleks.space/oleks/alertmanager-gotify-bridge";
|
|
|
|
# TAG is derived in shared code: CI exports CI_COMMIT_TAG (parity-lib
|
|
# strips the leading v / trailing -N), local dev may override $VERSION.
|
|
# No version.nix side-channel — the app is a static asset with no
|
|
# version-baked source build, so the tag lives purely in $VERSION/tag.
|
|
version = "0.0.0-dev";
|
|
|
|
# The whole payload: bridge.py + a python3 interpreter symlink under /app.
|
|
# The symlink keeps the (arch-correct) python3 Nix closure tracked while
|
|
# contributing no extra files. Parameterised over a pkg set so the SAME
|
|
# expression builds natively (amd64) and cross (arm64).
|
|
appRoot =
|
|
targetPkgs: arch:
|
|
pkgs.runCommand "app-root-${arch}" { } ''
|
|
mkdir -p $out/app
|
|
cp ${./bridge.py} $out/app/bridge.py
|
|
ln -s ${targetPkgs.python3}/bin/python3 $out/app/python3
|
|
'';
|
|
|
|
mkImage =
|
|
targetPkgs: arch:
|
|
n2c.buildImage {
|
|
name = registry;
|
|
tag = "${version}-${arch}";
|
|
inherit arch;
|
|
# reproducible = false materializes the layer tar so the image streams
|
|
# verbatim from any host (remote-builder + binary-cache safe). For a
|
|
# pure-stdlib interpreter closure the determinism risk is low, but the
|
|
# standard's caveat still applies: emmett+CI must resolve the identical
|
|
# python3 store path from the shared cache (fleet pin + flake.lock).
|
|
layers = [
|
|
(n2c.buildLayer {
|
|
copyToRoot = [
|
|
(appRoot targetPkgs arch)
|
|
pkgs.cacert
|
|
];
|
|
maxLayers = 25;
|
|
reproducible = false;
|
|
})
|
|
];
|
|
config = {
|
|
Cmd = [
|
|
"/app/python3"
|
|
"/app/bridge.py"
|
|
];
|
|
WorkingDir = "/app";
|
|
ExposedPorts = {
|
|
"8080/tcp" = { };
|
|
};
|
|
Env = [
|
|
"PORT=8080"
|
|
# urllib → Gotify over HTTPS needs an explicit CA bundle (the old
|
|
# Alpine base provided one via the distro; the Nix image ships it).
|
|
"SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt"
|
|
];
|
|
};
|
|
};
|
|
|
|
# amd64 = native; arm64 = cross-compiled (stock python3 closure from the
|
|
# binary cache, no qemu). Both are buildable on emmett (amd64).
|
|
imageAmd64 = mkImage pkgs "amd64";
|
|
imageArm64 = mkImage pkgs.pkgsCross.aarch64-multiplatform "arm64";
|
|
|
|
# ── Publish apps: shared parity-lib nix2container builder (cluster #192).
|
|
# Yields stage-<arch> / publish-<arch> / publish-index / publish /
|
|
# push-staged. copy-to (skopeo) pushes per-arch, regctl assembles the
|
|
# index; no buildkit / docker daemon. Dry-run by default (--publish to
|
|
# push); token from $REGISTRY_TOKEN (CI from_secret) → pass fallback,
|
|
# never echoed.
|
|
builders = parity.lib.mkParityBuilders pkgs;
|
|
publishApps = builders.mkNix2ContainerPublish {
|
|
imageName = registry;
|
|
inherit version;
|
|
images = {
|
|
amd64.copyTo = imageAmd64.copyTo;
|
|
arm64.copyTo = imageArm64.copyTo;
|
|
};
|
|
};
|
|
in
|
|
{
|
|
packages = {
|
|
image-amd64 = imageAmd64;
|
|
image-arm64 = imageArm64;
|
|
default = imageAmd64;
|
|
};
|
|
|
|
apps = publishApps;
|
|
}
|
|
);
|
|
}
|