add auto updater

This commit is contained in:
Abel Luck 2026-02-24 15:47:21 +01:00
parent eac7453a0d
commit 1f8fd2e642
17 changed files with 424 additions and 55 deletions

View file

@ -0,0 +1,39 @@
name: Update Pins
on:
push:
branches:
- main
paths:
- rules.nix
schedule:
- cron: "0 6 * * *"
workflow_dispatch: {}
jobs:
update:
runs-on: docker
container:
image: ghcr.io/catthehacker/ubuntu:runner-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Nix
#uses: https://guardianproject.dev/actions/determinate-nix-action@v3
uses: https://guardianproject.dev/actions/install-nix-action@v31
- name: Run update
run: nix run .#update
- name: Commit and push
run: |
git config user.name "forgejo-actions[bot]"
git config user.email "forgejo-actions[bot]@noreply.guardianproject.dev"
git add -A
if ! git diff --cached --quiet; then
git commit -m "update matrix-synapse pins"
git push
else
echo "No changes to commit"
fi

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
result
*.swp

27
flake.lock generated Normal file
View file

@ -0,0 +1,27 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1771482645,
"narHash": "sha256-MpAKyXfJRDTgRU33Hja+G+3h9ywLAJJNRq4Pjbb4dQs=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "724cf38d99ba81fbb4a347081db93e2e3a9bc2ae",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

41
flake.nix Normal file
View file

@ -0,0 +1,41 @@
{
description = "Pinned matrix package versions";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
outputs =
{ self, nixpkgs, ... }:
let
forAllSystems = nixpkgs.lib.genAttrs [
"x86_64-linux"
"aarch64-linux"
];
in
{
packages = forAllSystems (
system:
let
pkgs = nixpkgs.legacyPackages.${system};
in
{
update = pkgs.writeShellApplication {
name = "update-pins";
runtimeInputs = [
pkgs.git
pkgs.nix
pkgs.jq
pkgs.coreutils
];
text = builtins.readFile ./update.sh;
};
}
);
apps = forAllSystems (system: {
update = {
type = "app";
program = "${self.packages.${system}.update}/bin/update-pins";
};
});
};
}

27
matrix-synapse@1.129.0/flake.lock generated Normal file
View file

@ -0,0 +1,27 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1746770286,
"narHash": "sha256-Y9s4o1rQlKuaYj4YxKlP7E2/e+FZaV5IjbSxxnF/Nxo=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "907e98d6cc08e3261b63e3f8d2831841817b0041",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "907e98d6cc08e3261b63e3f8d2831841817b0041",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

View file

@ -0,0 +1,30 @@
{
description = "matrix-synapse 1.129.0";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/907e98d6cc08e3261b63e3f8d2831841817b0041";
outputs =
{ nixpkgs, ... }:
let
forAllSystems = nixpkgs.lib.genAttrs [
"x86_64-linux"
"aarch64-linux"
];
in
{
packages = forAllSystems (system: {
default = nixpkgs.legacyPackages.${system}.matrix-synapse;
matrix-synapse = nixpkgs.legacyPackages.${system}.matrix-synapse;
matrix-synapse-unwrapped = nixpkgs.legacyPackages.${system}.matrix-synapse-unwrapped;
});
overlays.default = _final: prev:
let
pinned = nixpkgs.legacyPackages.${prev.stdenv.hostPlatform.system};
in
{
matrix-synapse = pinned.matrix-synapse;
matrix-synapse-unwrapped = pinned.matrix-synapse-unwrapped;
};
};
}

View file

@ -2,17 +2,17 @@
"nodes": { "nodes": {
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1765438979, "lastModified": 1764486604,
"narHash": "sha256-JhvoqrTua8UBiDagDi4RCY/FPs5XQM57KLPqGgpPgFA=", "narHash": "sha256-+gx4ZLPgJEmeMpeIvWynzspCyO0W7evB7irQfdC9gI8=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "5b219581ae96a4201ac189ce8f1671db863f3621", "rev": "ad70f6b3e7fe9b4945071617787feb4251657e66",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "5b219581ae96a4201ac189ce8f1671db863f3621", "rev": "ad70f6b3e7fe9b4945071617787feb4251657e66",
"type": "github" "type": "github"
} }
}, },

View file

@ -1,7 +1,7 @@
{ {
description = "Matrix Synapse 1.143.0"; description = "matrix-synapse 1.143.0";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/5b219581ae96a4201ac189ce8f1671db863f3621"; inputs.nixpkgs.url = "github:NixOS/nixpkgs/ad70f6b3e7fe9b4945071617787feb4251657e66";
outputs = outputs =
{ nixpkgs, ... }: { nixpkgs, ... }:
@ -18,10 +18,13 @@
matrix-synapse-unwrapped = nixpkgs.legacyPackages.${system}.matrix-synapse-unwrapped; matrix-synapse-unwrapped = nixpkgs.legacyPackages.${system}.matrix-synapse-unwrapped;
}); });
overlays.default = _final: prev: { overlays.default = _final: prev:
matrix-synapse = (import nixpkgs { inherit (prev.stdenv.hostPlatform) system; }).matrix-synapse; let
matrix-synapse-unwrapped = pinned = nixpkgs.legacyPackages.${prev.stdenv.hostPlatform.system};
(import nixpkgs { inherit (prev.stdenv.hostPlatform) system; }).matrix-synapse-unwrapped; in
}; {
matrix-synapse = pinned.matrix-synapse;
matrix-synapse-unwrapped = pinned.matrix-synapse-unwrapped;
};
}; };
} }

View file

@ -2,17 +2,17 @@
"nodes": { "nodes": {
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1768655852, "lastModified": 1768258539,
"narHash": "sha256-UWgsh00FQayVQwjHGC/JZ1ibm7Hp9S77tvqRurnrQMI=", "narHash": "sha256-W3K+HbQR/RmoFAVf5dlZUkgJZivWkqJA/v28L7nQmLQ=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "0e2c7355d17358d440adeadfe1a9cb77fccc5891", "rev": "1f4b80d5979922876dc652142c82e204bba28eb2",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "0e2c7355d17358d440adeadfe1a9cb77fccc5891", "rev": "1f4b80d5979922876dc652142c82e204bba28eb2",
"type": "github" "type": "github"
} }
}, },

View file

@ -1,7 +1,7 @@
{ {
description = "Matrix Synapse 1.144.0"; description = "matrix-synapse 1.144.0";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/0e2c7355d17358d440adeadfe1a9cb77fccc5891"; inputs.nixpkgs.url = "github:NixOS/nixpkgs/1f4b80d5979922876dc652142c82e204bba28eb2";
outputs = outputs =
{ nixpkgs, ... }: { nixpkgs, ... }:
@ -18,10 +18,13 @@
matrix-synapse-unwrapped = nixpkgs.legacyPackages.${system}.matrix-synapse-unwrapped; matrix-synapse-unwrapped = nixpkgs.legacyPackages.${system}.matrix-synapse-unwrapped;
}); });
overlays.default = _final: prev: { overlays.default = _final: prev:
matrix-synapse = (import nixpkgs { inherit (prev.stdenv.hostPlatform) system; }).matrix-synapse; let
matrix-synapse-unwrapped = pinned = nixpkgs.legacyPackages.${prev.stdenv.hostPlatform.system};
(import nixpkgs { inherit (prev.stdenv.hostPlatform) system; }).matrix-synapse-unwrapped; in
}; {
matrix-synapse = pinned.matrix-synapse;
matrix-synapse-unwrapped = pinned.matrix-synapse-unwrapped;
};
}; };
} }

View file

@ -2,17 +2,17 @@
"nodes": { "nodes": {
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1769620183, "lastModified": 1768858439,
"narHash": "sha256-wSLf1rVSGWCHBb/C6ZczLhjSDRnmte2B9HGlklD8qJY=", "narHash": "sha256-whxg9Sj5vOoQmClFgNPOK1njoPkNMZMYnm48FhVYmrs=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "9774bb59bd3bb978cf86b38afc70f9c6d5505983", "rev": "1c096d58809938b66df361d6e5b49a1c369d311a",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "9774bb59bd3bb978cf86b38afc70f9c6d5505983", "rev": "1c096d58809938b66df361d6e5b49a1c369d311a",
"type": "github" "type": "github"
} }
}, },

View file

@ -1,7 +1,7 @@
{ {
description = "Matrix Synapse 1.145.0"; description = "matrix-synapse 1.145.0";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/9774bb59bd3bb978cf86b38afc70f9c6d5505983"; inputs.nixpkgs.url = "github:NixOS/nixpkgs/1c096d58809938b66df361d6e5b49a1c369d311a";
outputs = outputs =
{ nixpkgs, ... }: { nixpkgs, ... }:
@ -18,10 +18,13 @@
matrix-synapse-unwrapped = nixpkgs.legacyPackages.${system}.matrix-synapse-unwrapped; matrix-synapse-unwrapped = nixpkgs.legacyPackages.${system}.matrix-synapse-unwrapped;
}); });
overlays.default = _final: prev: { overlays.default = _final: prev:
matrix-synapse = (import nixpkgs { inherit (prev.stdenv.hostPlatform) system; }).matrix-synapse; let
matrix-synapse-unwrapped = pinned = nixpkgs.legacyPackages.${prev.stdenv.hostPlatform.system};
(import nixpkgs { inherit (prev.stdenv.hostPlatform) system; }).matrix-synapse-unwrapped; in
}; {
matrix-synapse = pinned.matrix-synapse;
matrix-synapse-unwrapped = pinned.matrix-synapse-unwrapped;
};
}; };
} }

View file

@ -2,17 +2,17 @@
"nodes": { "nodes": {
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1770995673, "lastModified": 1769621888,
"narHash": "sha256-VSVDo5G9ZXFJ9Y9B7CBxhUU7BD07CV/ROuE0BF1a5+Q=", "narHash": "sha256-FP6ewnpdkQoNDlNDukiNevbi+NAvOvZAz4a08q2y8hs=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "0a4980de41791938187f7001afff13f872fa6bf6", "rev": "90c4130e5b1396c3c1cf733b547029b4edfa6cf0",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "0a4980de41791938187f7001afff13f872fa6bf6", "rev": "90c4130e5b1396c3c1cf733b547029b4edfa6cf0",
"type": "github" "type": "github"
} }
}, },

View file

@ -1,7 +1,7 @@
{ {
description = "Matrix Synapse 1.146.0"; description = "matrix-synapse 1.146.0";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/0a4980de41791938187f7001afff13f872fa6bf6"; inputs.nixpkgs.url = "github:NixOS/nixpkgs/90c4130e5b1396c3c1cf733b547029b4edfa6cf0";
outputs = outputs =
{ nixpkgs, ... }: { nixpkgs, ... }:
@ -18,10 +18,13 @@
matrix-synapse-unwrapped = nixpkgs.legacyPackages.${system}.matrix-synapse-unwrapped; matrix-synapse-unwrapped = nixpkgs.legacyPackages.${system}.matrix-synapse-unwrapped;
}); });
overlays.default = _final: prev: { overlays.default = _final: prev:
matrix-synapse = (import nixpkgs { inherit (prev.stdenv.hostPlatform) system; }).matrix-synapse; let
matrix-synapse-unwrapped = pinned = nixpkgs.legacyPackages.${prev.stdenv.hostPlatform.system};
(import nixpkgs { inherit (prev.stdenv.hostPlatform) system; }).matrix-synapse-unwrapped; in
}; {
matrix-synapse = pinned.matrix-synapse;
matrix-synapse-unwrapped = pinned.matrix-synapse-unwrapped;
};
}; };
} }

View file

@ -2,17 +2,17 @@
"nodes": { "nodes": {
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1771679794, "lastModified": 1770995860,
"narHash": "sha256-7h8rLD33qRJe/mzp72WqgATbFPUbw+Vhz+QWJiunRIU=", "narHash": "sha256-pw2Sdtd4afTcxhG7oyQI1+XbORoO8T5ZWtniWY3T5i0=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "b3e92cc8c843d8a964ce48d46a28e674aa695a62", "rev": "e751ac9e4c6d30349f4c0f1c27f9f6365f905e44",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "b3e92cc8c843d8a964ce48d46a28e674aa695a62", "rev": "e751ac9e4c6d30349f4c0f1c27f9f6365f905e44",
"type": "github" "type": "github"
} }
}, },

View file

@ -1,7 +1,7 @@
{ {
description = "Matrix Synapse 1.147.1"; description = "matrix-synapse 1.147.1";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/b3e92cc8c843d8a964ce48d46a28e674aa695a62"; inputs.nixpkgs.url = "github:NixOS/nixpkgs/e751ac9e4c6d30349f4c0f1c27f9f6365f905e44";
outputs = outputs =
{ nixpkgs, ... }: { nixpkgs, ... }:
@ -18,10 +18,13 @@
matrix-synapse-unwrapped = nixpkgs.legacyPackages.${system}.matrix-synapse-unwrapped; matrix-synapse-unwrapped = nixpkgs.legacyPackages.${system}.matrix-synapse-unwrapped;
}); });
overlays.default = _final: prev: { overlays.default = _final: prev:
matrix-synapse = (import nixpkgs { inherit (prev.stdenv.hostPlatform) system; }).matrix-synapse; let
matrix-synapse-unwrapped = pinned = nixpkgs.legacyPackages.${prev.stdenv.hostPlatform.system};
(import nixpkgs { inherit (prev.stdenv.hostPlatform) system; }).matrix-synapse-unwrapped; in
}; {
matrix-synapse = pinned.matrix-synapse;
matrix-synapse-unwrapped = pinned.matrix-synapse-unwrapped;
};
}; };
} }

188
update.sh Normal file
View file

@ -0,0 +1,188 @@
#!/usr/bin/env bash
set -euo pipefail
shopt -s nullglob
REPO_ROOT="$(git rev-parse --show-toplevel)"
RULES_FILE="$REPO_ROOT/rules.nix"
if [[ ! -f "$RULES_FILE" ]]; then
echo "ERROR: rules.nix not found at $RULES_FILE" >&2
exit 1
fi
# --- Locate or clone nixpkgs ---
cleanup_nixpkgs=false
if [[ -z "${NIXPKGS_REPO:-}" ]]; then
NIXPKGS_REPO=$(mktemp -d)
cleanup_nixpkgs=true
echo "Cloning nixpkgs (partial clone, may take a moment)..."
git clone --filter=blob:none --single-branch --branch nixpkgs-unstable \
https://github.com/NixOS/nixpkgs.git "$NIXPKGS_REPO" --quiet
fi
cleanup() {
if "$cleanup_nixpkgs"; then
rm -rf "$NIXPKGS_REPO"
fi
}
trap cleanup EXIT
# Determine the ref to walk. For a fresh clone we use HEAD (which is
# nixpkgs-unstable). For a user-supplied repo we prefer the remote tracking
# branch so the result is independent of which branch is checked out locally.
if git -C "$NIXPKGS_REPO" rev-parse --verify origin/nixpkgs-unstable >/dev/null 2>&1; then
NIXPKGS_REF="origin/nixpkgs-unstable"
else
NIXPKGS_REF="HEAD"
fi
# --- Map package name to the nixpkgs file whose version we track ---
nixpkgs_path_for() {
case "$1" in
matrix-synapse)
echo "pkgs/by-name/ma/matrix-synapse-unwrapped/package.nix"
;;
*)
echo "ERROR: no nixpkgs path mapping for package '$1'" >&2
return 1
;;
esac
}
# --- Extract version string from package.nix at a given commit ---
version_at_commit() {
local commit="$1" pkg_path="$2"
git -C "$NIXPKGS_REPO" show "${commit}:${pkg_path}" 2>/dev/null \
| grep -m1 'version = ' \
| sed 's/.*"\(.*\)".*/\1/'
}
# --- Generate flake.nix for a matrix-synapse pin ---
generate_flake_nix() {
local pkg="$1" version="$2" commit="$3" outfile="$4"
cat > "$outfile" << FLAKE_EOF
{
description = "${pkg} ${version}";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/${commit}";
outputs =
{ nixpkgs, ... }:
let
forAllSystems = nixpkgs.lib.genAttrs [
"x86_64-linux"
"aarch64-linux"
];
in
{
packages = forAllSystems (system: {
default = nixpkgs.legacyPackages.\${system}.matrix-synapse;
matrix-synapse = nixpkgs.legacyPackages.\${system}.matrix-synapse;
matrix-synapse-unwrapped = nixpkgs.legacyPackages.\${system}.matrix-synapse-unwrapped;
});
overlays.default = _final: prev:
let
pinned = nixpkgs.legacyPackages.\${prev.stdenv.hostPlatform.system};
in
{
matrix-synapse = pinned.matrix-synapse;
matrix-synapse-unwrapped = pinned.matrix-synapse-unwrapped;
};
};
}
FLAKE_EOF
}
# --- Read rules ---
RULES_JSON=$(nix eval --json --file "$RULES_FILE")
mapfile -t packages < <(echo "$RULES_JSON" | jq -r 'keys[]')
for pkg in "${packages[@]}"; do
latest_n=$(echo "$RULES_JSON" | jq -r ".[\"$pkg\"].\"latest-revisions\"")
mapfile -t pins < <(echo "$RULES_JSON" | jq -r ".[\"$pkg\"].pin // [] | .[]")
pkg_path=$(nixpkgs_path_for "$pkg")
echo "=== $pkg: latest $latest_n + ${#pins[@]} pin(s) ==="
# Collect commits that touched the package file (newest first, first-parent only)
mapfile -t commits < <(
git -C "$NIXPKGS_REPO" log --first-parent --format="%H" "$NIXPKGS_REF" -- "$pkg_path" \
| head -300
)
echo " Scanning ${#commits[@]} commits..."
# Build version -> commit map. First occurrence (newest) wins.
declare -A version_commit=()
declare -a version_order=()
for commit in "${commits[@]}"; do
ver=$(version_at_commit "$commit" "$pkg_path") || true
[[ -n "${ver:-}" ]] || continue
if [[ -z "${version_commit[$ver]:-}" ]]; then
version_commit["$ver"]="$commit"
version_order+=("$ver")
fi
done
echo " Found ${#version_order[@]} unique versions"
# Decide which versions to keep
declare -A keep_versions=()
for ((i = 0; i < latest_n && i < ${#version_order[@]}; i++)); do
ver="${version_order[$i]}"
keep_versions["$ver"]=1
echo " [latest] $ver ${version_commit[$ver]:0:12}"
done
for pin_ver in "${pins[@]}"; do
if [[ -n "${version_commit[$pin_ver]:-}" ]]; then
keep_versions["$pin_ver"]=1
echo " [pinned] $pin_ver ${version_commit[$pin_ver]:0:12}"
else
echo " WARNING: pinned version $pin_ver not found in nixpkgs history" >&2
fi
done
# Create or update pin directories
for ver in "${!keep_versions[@]}"; do
dir="$REPO_ROOT/${pkg}@${ver}"
commit="${version_commit[$ver]}"
flake_file="$dir/flake.nix"
if [[ -f "$flake_file" ]]; then
existing_commit=$(sed -n 's|.*github:NixOS/nixpkgs/\([a-f0-9]*\).*|\1|p' "$flake_file" | head -1)
if [[ "$existing_commit" == "$commit" ]]; then
echo " $ver: up to date"
continue
fi
echo " $ver: updating commit"
else
echo " $ver: creating"
fi
mkdir -p "$dir"
generate_flake_nix "$pkg" "$ver" "$commit" "$flake_file"
# flake.nix must be tracked by git before nix flake lock can see it
git add "$flake_file"
echo " $ver: locking flake inputs..."
nix flake lock "$dir"
git add "$dir/flake.lock"
done
# Remove directories no longer required by rules
for dir in "$REPO_ROOT/${pkg}@"*/; do
[[ -d "$dir" ]] || continue
dir_name=$(basename "$dir")
ver="${dir_name#"${pkg}@"}"
if [[ -z "${keep_versions[$ver]:-}" ]]; then
echo " Removing: $ver"
rm -rf "$dir"
fi
done
unset version_commit version_order keep_versions
done
echo "Done."