From 0fb89ef74d41409d57c74d0828c37056ed95cb72 Mon Sep 17 00:00:00 2001 From: clerie Date: Tue, 19 Mar 2024 17:31:18 +0100 Subject: [PATCH] pkgs/clerie-update-nixfiles: Add script that merges back nixfiles updates --- flake.nix | 1 + .../clerie-merge-nixfiles-update.nix | 13 ++ .../clerie-merge-nixfiles-update.sh | 122 ++++++++++++++++++ pkgs/overlay.nix | 1 + 4 files changed, 137 insertions(+) create mode 100644 pkgs/clerie-update-nixfiles/clerie-merge-nixfiles-update.nix create mode 100755 pkgs/clerie-update-nixfiles/clerie-merge-nixfiles-update.sh diff --git a/flake.nix b/flake.nix index 192ddd4..aa46d87 100644 --- a/flake.nix +++ b/flake.nix @@ -113,6 +113,7 @@ in { inherit (pkgs) clerie-system-upgrade + clerie-merge-nixfiles-update clerie-update-nixfiles chromium-incognito iot-data diff --git a/pkgs/clerie-update-nixfiles/clerie-merge-nixfiles-update.nix b/pkgs/clerie-update-nixfiles/clerie-merge-nixfiles-update.nix new file mode 100644 index 0000000..ed37399 --- /dev/null +++ b/pkgs/clerie-update-nixfiles/clerie-merge-nixfiles-update.nix @@ -0,0 +1,13 @@ +{ pkgs, ... }: + +pkgs.writeShellApplication { + name = "clerie-merge-nixfiles-update"; + text = builtins.readFile ./clerie-merge-nixfiles-update.sh; + runtimeInputs = with pkgs; [ + curl + git + jq + openssh + ]; +} + diff --git a/pkgs/clerie-update-nixfiles/clerie-merge-nixfiles-update.sh b/pkgs/clerie-update-nixfiles/clerie-merge-nixfiles-update.sh new file mode 100755 index 0000000..7f402d3 --- /dev/null +++ b/pkgs/clerie-update-nixfiles/clerie-merge-nixfiles-update.sh @@ -0,0 +1,122 @@ +#!/usr/bin/env bash + +set -euo pipefail + +xgit() { + git -c "user.name=Flake Update Bot" -c "user.email=flake-update-bot@clerie.de" "$@" +} + +xgit_parent_commits() { + xgit show -q --format="%P" "$@" | sed "s/ /\n/g" +} + +xgit_refs_for_commit() { + xgit show -q --format="%D" "$@" | sed "s/, /\n/g" | sed -E "s/((.+) -> )?(.+)/\3/g" +} + +commit_is_head_of_branch() { + COMMIT="$1" + BRANCH="$2" + xgit_refs_for_commit "${COMMIT}" | grep -E "^${BRANCH}$" > /dev/null +} + +no_confirm="" + +while [[ $# -gt 0 ]]; do + case $1 in + --no-confirm) + no_confirm=1 + shift + ;; + *) + echo "unknown option: $1" + exit 1 + ;; + esac +done + +echo "[!] Init git repo" +xgit status > /dev/null || xgit clone gitea@git.clerie.de:clerie/nixfiles.git . + +echo "[!] Make sure git repo is up to date" +xgit fetch --all + +echo "[!] Checkout master" +xgit checkout master + +echo "[!] Update master" +xgit pull origin master + +echo "[!] Fetch git commit of last hydra run" +echo "[!] Checking https://hydra.clerie.de/jobset/nixfiles/nixfiles-updated-inputs/latest-eval" +GIT_REV_OF_LAST_HYDRA_RUN=$(curl --json "" -X GET -L https://hydra.clerie.de/jobset/nixfiles/nixfiles-updated-inputs/latest-eval 2> /dev/null | \ + jq -r .flake | sed -E "s/.+&rev=(.*)/\1/g") +echo "[!] Last hydra ran from ${GIT_REV_OF_LAST_HYDRA_RUN} (https://git.clerie.de/clerie/nixfiles/commit/${GIT_REV_OF_LAST_HYDRA_RUN})" + +echo "[!] Check if commit is current head of origin/updated-inputs" +set +e +if ! commit_is_head_of_branch "${GIT_REV_OF_LAST_HYDRA_RUN}" "origin/updated-inputs"; then + echo "[!] Commit is not head of origin/updated-inputs" + echo "[!] Hydra seem to still process the current head of origin/updated-inputs" + exit 0 +fi +set -e + +echo "[!] Find out update branch" +PARENT_COMMITS=$(xgit_parent_commits "${GIT_REV_OF_LAST_HYDRA_RUN}") + +update_branch= +for commit in $PARENT_COMMITS; do + set +e + if update_branch=$(xgit_refs_for_commit "${commit}" | sort -d | grep -E "^origin/updated-inputs-.+$" | head -1); then + break + fi + set -e +done + +if [[ -z "$update_branch" ]]; then + echo "[!] No update branch found" + exit 0 +fi + +echo "[!] Update branch $update_branch" + +echo "[!] Check if update branch forks from current master" +contains_current_master_head= +for commit in $(git rev-list "${update_branch}"); do + set +e + if xgit_refs_for_commit "${commit}" | sort -d | grep -E "^master$" | head -1 > /dev/null; then + contains_current_master_head=1 + break + fi + set -e +done + +if [[ -z "$contains_current_master_head" ]]; then + echo "[!] ${update_branch} does not contain the current master head" + echo "[!] Cannot merge ${update_branch}" + exit 0 +fi + +echo "[!] ${update_branch} can be merged into master" + +merge_diff=$(xgit diff --color master "${update_branch}") + +if [[ -z $merge_diff ]]; then + echo "[!] Nothing changes, nothing to merge" + exit 0 +fi + +echo "${merge_diff}" + +if [[ -z $no_confirm ]]; then + read -e -r -p "[?] Merge ${update_branch} into master?" confirm + echo "$confirm" > /dev/null +fi + +echo "[!] Merging ${update_branch} into master" + +xgit merge --ff-only "${update_branch}" + + +echo "[!] Merge successful" diff --git a/pkgs/overlay.nix b/pkgs/overlay.nix index 5a6c751..644a48c 100644 --- a/pkgs/overlay.nix +++ b/pkgs/overlay.nix @@ -1,5 +1,6 @@ final: prev: { clerie-system-upgrade = final.callPackage ./clerie-system-upgrade/clerie-system-upgrade.nix {}; + clerie-merge-nixfiles-update = final.callPackage ./clerie-update-nixfiles/clerie-merge-nixfiles-update.nix {}; clerie-update-nixfiles = final.callPackage ./clerie-update-nixfiles/clerie-update-nixfiles.nix {}; chromium-incognito = final.callPackage ./chromium-incognito {}; iot-data = final.python3.pkgs.callPackage ./iot-data {};