Author SHA1 Message Date
github-actions[bot] e3e99c9072 chore(nix): update nixpkgs-unstable to 0267914b 2026-07-28 20:01:10 +00:00
moons-14andgithub-actions[bot] 28620c1d03 chore(nix): update nixpkgs to d2f1d98b (#54)
NixOS CI / Validate flake (push) Has been cancelled
NixOS CI / Build ${{ matrix.host }} (push) Has been cancelled
NixOS CI / Report main status (push) Has been cancelled
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-07-28 05:04:25 +09:00
moons-14andgithub-actions[bot] 1971108a7f chore(nix): update noctalia to 0cd9b22e (#52)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-07-28 05:04:14 +09:00
moons-14andgithub-actions[bot] 849e79e124 chore(nix): update niri-flake to ef7a2a3d (#51)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-07-28 05:03:37 +09:00
moons-14andgithub-actions[bot] 057c3cc5a3 chore(nix): update ghostty to 4c725242 (#49)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-07-28 05:03:16 +09:00
moons-14andgithub-actions[bot] 6cb15f3a54 chore(nix): update nixpkgs-unstable to d4221905 (#44)
NixOS CI / Validate flake (push) Has been cancelled
NixOS CI / Build ${{ matrix.host }} (push) Has been cancelled
NixOS CI / Report main status (push) Has been cancelled
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-07-27 04:43:36 +09:00
moons-14andgithub-actions[bot] 99132ef43f chore(nix): update nixpkgs to c76cb9d6 (#46)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-07-27 04:43:35 +09:00
moons-14andgithub-actions[bot] d40b5b4b00 chore(nix): update nixpkgs to 8db7e9c9 (#45)
NixOS CI / Validate flake (push) Has been cancelled
NixOS CI / Build ${{ matrix.host }} (push) Has been cancelled
NixOS CI / Report main status (push) Has been cancelled
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-07-26 04:42:32 +09:00
moons-14 4487c38f0b update action
NixOS CI / Validate flake (push) Has been cancelled
NixOS CI / Build ${{ matrix.host }} (push) Has been cancelled
NixOS CI / Report main status (push) Has been cancelled
2026-07-24 11:44:14 +09:00
moons-14 873223cb78 update
NixOS CI / Validate flake (push) Has been cancelled
NixOS CI / Build ${{ matrix.host }} (push) Has been cancelled
NixOS CI / Report main status (push) Has been cancelled
2026-07-24 06:19:02 +09:00
moons-14 3022acb412 jq
NixOS CI / Validate flake (push) Has been cancelled
NixOS CI / Build ${{ matrix.host }} (push) Has been cancelled
NixOS CI / Report main status (push) Has been cancelled
2026-07-24 06:04:21 +09:00
moons-14 18d30bd490 update 2026-07-24 05:59:01 +09:00
moons-14 f2d9eafefa dns
NixOS CI / Validate flake (push) Has been cancelled
NixOS CI / Build ${{ matrix.host }} (push) Has been cancelled
NixOS CI / Report main status (push) Has been cancelled
2026-07-23 20:13:02 +09:00
moons-14 85a4458376 nix update
NixOS CI / Validate flake (push) Has been cancelled
NixOS CI / Build ${{ matrix.host }} (push) Has been cancelled
NixOS CI / Report main status (push) Has been cancelled
2026-07-21 18:37:22 +09:00
moons-14 b60a840a3d update 2026-07-21 18:34:15 +09:00
moons-14 e1c9beb362 remove nix pkg oci 2026-07-21 18:34:14 +09:00
moons-14 45957d0b40 waylock fingerprint 2026-07-21 18:34:05 +09:00
moons-14 455512ec8a zed 2026-07-21 18:34:04 +09:00
moons-14 754af0a68a Merge pull request #39 from moons-14/renovate/actions-checkout-7.x
chore(deps): update actions/checkout action to v7.0.1
2026-07-21 18:28:54 +09:00
moons-14 475b1432d0 Merge pull request #40 from moons-14/renovate/renovatebot-github-action-46.x
chore(deps): update renovatebot/github-action action to v46.1.20
2026-07-21 18:28:41 +09:00
Renovate Bot e51480e692 chore(deps): update renovatebot/github-action action to v46.1.20 2026-07-20 19:41:45 +00:00
Renovate Bot e09d2d525f chore(deps): update actions/checkout action to v7.0.1 2026-07-20 19:41:42 +00:00
moons-14 6ec1f5762a imutable zed settings
NixOS CI / Validate flake (push) Has been cancelled
Publish Nix cache / Build and publish uncached paths (push) Has been cancelled
NixOS CI / Build ${{ matrix.host }} (push) Has been cancelled
NixOS CI / Report main status (push) Has been cancelled
2026-07-20 07:10:25 +09:00
moons-14 ac6d333af8 zed 2026-07-20 06:50:11 +09:00
moons-14 ad8d66cde1 zoom
Publish Nix cache / Build and publish uncached paths (push) Has been cancelled
NixOS CI / Validate flake (push) Has been cancelled
NixOS CI / Build ${{ matrix.host }} (push) Has been cancelled
NixOS CI / Report main status (push) Has been cancelled
2026-07-20 06:28:35 +09:00
moons-14 b2283ba328 nix cache
NixOS CI / Validate flake (push) Has been cancelled
Publish Nix cache / Build and publish uncached paths (push) Has been cancelled
NixOS CI / Build ${{ matrix.host }} (push) Has been cancelled
NixOS CI / Report main status (push) Has been cancelled
2026-07-18 20:09:04 +09:00
moons-14 1e38d17dba grok
NixOS CI / Validate flake (push) Has been cancelled
NixOS CI / Build ${{ matrix.host }} (push) Has been cancelled
NixOS CI / Report main status (push) Has been cancelled
2026-07-18 19:52:38 +09:00
moons-14 e67dd6a791 grok 2026-07-18 19:07:47 +09:00
moons-14 0c6b2f41b9 vicinae
NixOS CI / Validate flake (push) Has been cancelled
NixOS CI / Build ${{ matrix.host }} (push) Has been cancelled
NixOS CI / Report main status (push) Has been cancelled
2026-07-18 19:05:30 +09:00
moons-14 1091e790db Merge pull request #35 from moons-14/renovate/lock-file-maintenance-nix-flake-inputs
chore(deps): lock file maintenance
2026-07-18 19:04:08 +09:00
Renovate Bot 6c053486a7 chore(deps): lock file maintenance 2026-07-16 19:07:23 +00:00
moons-14 60b64c89b9 Merge pull request #33 from moons-14/renovate/lock-file-maintenance-nix-flake-inputs
NixOS CI / Validate flake (push) Has been cancelled
NixOS CI / Build ${{ matrix.host }} (push) Has been cancelled
NixOS CI / Report main status (push) Has been cancelled
chore(deps): lock file maintenance
2026-07-17 01:12:56 +09:00
Renovate Bot f264649782 chore(deps): lock file maintenance 2026-07-16 16:12:29 +00:00
moons-14 5370e864e1 Update renovate.json 2026-07-17 01:10:00 +09:00
moons-14 9302d1e50f Merge pull request #31 from moons-14/renovate/cachix-install-nix-action-31.x
chore(deps): update cachix/install-nix-action action to v31.11.0
2026-07-17 01:05:48 +09:00
moons-14 8616aacd7f Merge pull request #32 from moons-14/renovate/actions-checkout-7.x
chore(deps): update actions/checkout action to v7
2026-07-17 01:05:29 +09:00
Renovate Bot 21947ba06a chore(deps): update actions/checkout action to v7 2026-07-16 16:03:57 +00:00
Renovate Bot d75528c712 chore(deps): update cachix/install-nix-action action to v31.11.0 2026-07-16 16:03:54 +00:00
moons-14 afcbe77e98 Add lockFileMaintenance configuration
NixOS CI / Validate flake (push) Has been cancelled
NixOS CI / Build ${{ matrix.host }} (push) Has been cancelled
NixOS CI / Report main status (push) Has been cancelled
Enable lock file maintenance with scheduling.
2026-07-17 00:52:53 +09:00
moons-14 4ff5ae8883 feat
NixOS CI / Validate flake (push) Has been cancelled
NixOS CI / Build ${{ matrix.host }} (push) Has been cancelled
NixOS CI / Report main status (push) Has been cancelled
2026-07-15 14:38:59 +09:00
moons-14 166b6f2492 gitea update
Update Nix binary cache / Build every host and publish new cache objects (push) Has been cancelled
2026-07-15 00:37:41 +09:00
moons-14 703e24fcdf gitea update
Update Nix binary cache / Build every host and publish new cache objects (push) Failing after 24s
Bootstrap Nix binary cache / Build every host and bootstrap the cache (push) Waiting to run
2026-07-14 22:34:07 +09:00
moons-14 04622b921f gitea update
Update Nix binary cache / Build every host and publish new cache objects (push) Failing after 25s
Bootstrap Nix binary cache / Build every host and bootstrap the cache (push) Waiting to run
2026-07-14 21:19:31 +09:00
29 changed files with 815 additions and 1085 deletions
-612
View File
@@ -1,612 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
# Gitea Releases are used as an append-only object store. The cache-latest
# release contains the HTTP binary-cache index, while generation releases
# contain immutable NAR payloads.
mode=${CACHE_MODE:-}
server_url=${CACHE_SERVER_URL:-}
repository=${CACHE_REPOSITORY:-}
commit=${CACHE_COMMIT:-}
ref_name=${CACHE_REF_NAME:-unknown}
index_tag=${CACHE_INDEX_TAG:-cache-latest}
generation_prefix=${CACHE_GENERATION_PREFIX:-nix-cache-generation-}
upload_jobs=${CACHE_UPLOAD_JOBS:-4}
key_file=${NIX_CACHE_KEY_FILE:-}
for command in curl jq nix awk sed find sort; do
if ! command -v "$command" >/dev/null 2>&1; then
echo "Required command is unavailable: $command" >&2
exit 1
fi
done
if [[ $mode != bootstrap && $mode != update ]]; then
echo "CACHE_MODE must be either 'bootstrap' or 'update'." >&2
exit 1
fi
if [[ -z $server_url || -z $repository || -z $commit ]]; then
echo "CACHE_SERVER_URL, CACHE_REPOSITORY, and CACHE_COMMIT are required." >&2
exit 1
fi
if [[ -z ${GITEA_TOKEN:-} ]]; then
echo "GITEA_TOKEN is required." >&2
exit 1
fi
if [[ ! -s $key_file ]]; then
echo "NIX_CACHE_KEY_FILE must point to a non-empty signing key." >&2
exit 1
fi
if [[ ! $upload_jobs =~ ^[1-9][0-9]*$ ]]; then
echo "CACHE_UPLOAD_JOBS must be a positive integer." >&2
exit 1
fi
server_url=${server_url%/}
api_base="${server_url}/api/v1/repos/${repository}"
download_base="${server_url}/${repository}/releases/download"
cache_uri="${download_base}/${index_tag}"
manifest_url="${cache_uri}/cache-manifest.json"
public_key_url="${cache_uri}/cache-public-key"
public_key=$(nix key convert-secret-to-public <"$key_file")
key_name=${public_key%%:*}
work_dir=$(mktemp -d "${RUNNER_TEMP:-/tmp}/nix-release-cache.XXXXXX")
cache_dir="${work_dir}/cache"
rewritten_dir="${work_dir}/narinfo"
manifest_file="${work_dir}/manifest.json"
all_releases_file="${work_dir}/all-releases.json"
generation_release_file="${work_dir}/generation-release.json"
object_updates_file="${work_dir}/object-updates.jsonl"
narinfo_updates_file="${work_dir}/narinfo-updates.jsonl"
nar_upload_queue="${work_dir}/nar-upload-queue"
narinfo_upload_queue="${work_dir}/narinfo-upload-queue"
mkdir -p "$cache_dir" "$rewritten_dir"
: >"$object_updates_file"
: >"$narinfo_updates_file"
: >"$nar_upload_queue"
: >"$narinfo_upload_queue"
trap 'rm -rf "$work_dir"' EXIT
api_request() {
local method=$1
local path=$2
shift 2
curl --fail-with-body --silent --show-error \
--retry 5 --retry-delay 2 --retry-all-errors \
--request "$method" \
--header "Authorization: token ${GITEA_TOKEN}" \
--header "Accept: application/json" \
"$@" \
"${api_base}${path}"
}
api_get_optional() {
local path=$1
local output=$2
local status
status=$(curl --silent --show-error \
--retry 5 --retry-delay 2 --retry-all-errors \
--output "$output" --write-out '%{http_code}' \
--header "Authorization: token ${GITEA_TOKEN}" \
--header "Accept: application/json" \
"${api_base}${path}")
case "$status" in
200)
return 0
;;
404)
rm -f "$output"
return 1
;;
*)
echo "Gitea API request failed with HTTP ${status}: ${path}" >&2
cat "$output" >&2
return 2
;;
esac
}
create_release() {
local tag=$1
local name=$2
local body=$3
local prerelease=$4
jq -n \
--arg tag "$tag" \
--arg name "$name" \
--arg body "$body" \
--arg target "$commit" \
--argjson prerelease "$prerelease" \
'{
tag_name: $tag,
target_commitish: $target,
name: $name,
body: $body,
draft: false,
prerelease: $prerelease
}' | api_request POST /releases \
--header 'Content-Type: application/json' \
--data-binary @-
}
delete_asset() {
local release_id=$1
local asset_id=$2
api_request DELETE "/releases/${release_id}/assets/${asset_id}" >/dev/null
}
upload_asset() {
local release_id=$1
local file=$2
local name=$3
curl --fail-with-body --silent --show-error \
--retry 5 --retry-delay 2 --retry-all-errors \
--request POST \
--header "Authorization: token ${GITEA_TOKEN}" \
--form "attachment=@${file};type=application/octet-stream" \
--output /dev/null \
"${api_base}/releases/${release_id}/assets?name=${name}"
}
upload_asset_response() {
local release_id=$1
local file=$2
local name=$3
curl --fail-with-body --silent --show-error \
--retry 5 --retry-delay 2 --retry-all-errors \
--request POST \
--header "Authorization: token ${GITEA_TOKEN}" \
--form "attachment=@${file};type=application/octet-stream" \
"${api_base}/releases/${release_id}/assets?name=${name}"
}
rename_asset() {
local release_id=$1
local asset_id=$2
local name=$3
jq -n --arg name "$name" '{name: $name}' | api_request PATCH \
"/releases/${release_id}/assets/${asset_id}" \
--header 'Content-Type: application/json' \
--data-binary @- >/dev/null
}
upload_queue() {
local release_id=$1
local queue_file=$2
local file
local name
local pid
local failed=0
local -a pids=()
if [[ ! -s $queue_file ]]; then
return
fi
while IFS=$'\t' read -r file name; do
upload_asset "$release_id" "$file" "$name" &
pids+=("$!")
if ((${#pids[@]} == upload_jobs)); then
for pid in "${pids[@]}"; do
if ! wait "$pid"; then
failed=1
fi
done
pids=()
if ((failed)); then
return 1
fi
fi
done <"$queue_file"
for pid in "${pids[@]}"; do
if ! wait "$pid"; then
failed=1
fi
done
if ((failed)); then
return 1
fi
}
list_all_releases() {
local page=1
local page_file="${work_dir}/releases-page.json"
local releases_jsonl="${work_dir}/releases.jsonl"
local count
: >"$releases_jsonl"
while :; do
api_request GET "/releases?draft=false&pre-release=true&limit=50&page=${page}" >"$page_file"
count=$(jq 'length' "$page_file")
if ((count == 0)); then
break
fi
jq -c '.[]' "$page_file" >>"$releases_jsonl"
((page += 1))
done
jq -s '.' "$releases_jsonl" >"$all_releases_file"
}
initialize_manifest() {
jq -n \
--arg uri "$cache_uri" \
--arg manifest "$manifest_url" \
--arg public_key "$public_key" \
--arg public_key_url "$public_key_url" \
'{
schemaVersion: 1,
cache: {
uri: $uri,
nixCacheInfo: ($uri + "/nix-cache-info"),
manifest: $manifest,
publicKey: $public_key,
publicKeyUrl: $public_key_url
},
generatedAt: null,
generations: [],
objects: {},
narinfos: {}
}' >"$manifest_file"
}
index_release_file="${work_dir}/index-release.json"
if api_get_optional "/releases/tags/${index_tag}" "$index_release_file"; then
if [[ $mode == bootstrap ]]; then
if jq -e '.assets[]? | select(.name == "cache-manifest.json")' \
"$index_release_file" >/dev/null; then
echo "Release '${index_tag}' is already bootstrapped." >&2
exit 1
fi
echo "Resuming an interrupted cache bootstrap."
initialize_manifest
else
manifest_asset_url=$(jq -r '
[
.assets[]?
| select(.name == "cache-manifest.json")
]
| last
| .browser_download_url // empty
' "$index_release_file")
if [[ -z $manifest_asset_url ]]; then
manifest_asset_url=$(jq -r '
[
.assets[]?
| select(.name | test("^cache-manifest-[0-9a-f]+\\.json$"))
]
| sort_by(.created_at)
| last
| .browser_download_url // empty
' "$index_release_file")
if [[ -z $manifest_asset_url ]]; then
echo "The cache index has no recoverable manifest." >&2
exit 1
fi
echo "Recovering the cache index from a temporary manifest."
fi
curl --fail-with-body --silent --show-error \
--retry 5 --retry-delay 2 --retry-all-errors \
--header "Authorization: token ${GITEA_TOKEN}" \
--output "$manifest_file" \
"$manifest_asset_url"
if ! jq -e --arg public_key "$public_key" \
'.schemaVersion == 1 and .cache.publicKey == $public_key' \
"$manifest_file" >/dev/null; then
echo "The cache manifest is invalid or was signed by a different key." >&2
exit 1
fi
fi
else
optional_status=$?
if ((optional_status != 1)); then
exit "$optional_status"
fi
if [[ $mode == update ]]; then
echo "Release '${index_tag}' is missing. Run the bootstrap workflow first." >&2
exit 1
fi
create_release \
"$index_tag" \
"Nix binary cache index" \
"Stable HTTP index for the release-backed Nix binary cache." \
false >"$index_release_file"
initialize_manifest
fi
index_release_id=$(jq -r '.id' "$index_release_file")
if [[ -z $index_release_id || $index_release_id == null ]]; then
echo "Could not determine the cache index release ID." >&2
exit 1
fi
echo "Evaluating NixOS hosts..."
hosts_file="${work_dir}/hosts"
nix eval --json '.#nixosConfigurations' \
--apply 'configs: builtins.attrNames configs' | jq -r '.[]' >"$hosts_file"
mapfile -t hosts <"$hosts_file"
if ((${#hosts[@]} == 0)); then
echo "No NixOS configurations were discovered." >&2
exit 1
fi
targets=()
for host in "${hosts[@]}"; do
targets+=(".#nixosConfigurations.${host}.config.system.build.toplevel")
done
echo "Building hosts: ${hosts[*]}"
roots_file="${work_dir}/roots"
nix build --no-link --print-out-paths --print-build-logs "${targets[@]}" | sort -u >"$roots_file"
mapfile -t roots <"$roots_file"
if ((${#roots[@]} == 0)); then
echo "The Nix build returned no store paths." >&2
exit 1
fi
echo "Exporting the complete host closures to a signed local binary cache..."
nix copy \
--to "file://${cache_dir}?compression=zstd&compression-level=6&secret-key=${key_file}" \
"${roots[@]}"
first_narinfo=$(find "$cache_dir" -maxdepth 1 -type f -name '*.narinfo' -print -quit)
if [[ -z $first_narinfo ]] || ! grep -Fq "Sig: ${key_name}:" "$first_narinfo"; then
echo "Generated narinfo files do not contain the expected cache signature." >&2
exit 1
fi
list_all_releases
# Recover immutable NAR objects left by an interrupted older run. A NAR asset's
# content-addressed filename is globally unique, so it can be reused safely.
discovered_objects_file="${work_dir}/discovered-objects.json"
jq --arg prefix "$generation_prefix" '
reduce (
.[]
| select(.tag_name | startswith($prefix)) as $release
| $release.assets[]?
| select(.name | test("\\.nar\\.(zst|xz|bz2|gz)$"))
| {
key: .name,
value: {
url: .browser_download_url,
generation: $release.tag_name,
size: .size
}
}
) as $object ({}; .[$object.key] //= $object.value)
' "$all_releases_file" >"$discovered_objects_file"
jq --slurpfile discovered "$discovered_objects_file" \
'.objects = ($discovered[0] + .objects)' \
"$manifest_file" >"${manifest_file}.new"
mv "${manifest_file}.new" "$manifest_file"
generation_tag="${generation_prefix}${commit}"
if api_get_optional "/releases/tags/${generation_tag}" "$generation_release_file"; then
echo "Resuming generation release '${generation_tag}'."
else
optional_status=$?
if ((optional_status != 1)); then
exit "$optional_status"
fi
create_release \
"$generation_tag" \
"Nix cache ${commit:0:12}" \
"Branch: ${ref_name}\nCommit: ${commit}\nMode: ${mode}" \
true >"$generation_release_file"
fi
generation_release_id=$(jq -r '.id' "$generation_release_file")
declare -A known_narinfos=()
declare -A object_urls=()
declare -A object_sizes=()
declare -A queued_objects=()
declare -A index_asset_ids=()
while IFS= read -r hash; do
known_narinfos["$hash"]=1
done < <(jq -r '.narinfos | keys[]' "$manifest_file")
while IFS=$'\t' read -r name url; do
object_urls["$name"]=$url
done < <(
jq -r '.objects | to_entries[] | [.key, .value.url] | @tsv' \
"$manifest_file"
)
while IFS=$'\t' read -r name id; do
index_asset_ids["$name"]=$id
done < <(jq -r '.assets[]? | [.name, (.id | tostring)] | @tsv' "$index_release_file")
new_nar_count=0
new_narinfo_count=0
while IFS= read -r -d '' narinfo_file; do
narinfo_name=$(basename "$narinfo_file")
store_hash=${narinfo_name%.narinfo}
if [[ -n ${known_narinfos[$store_hash]:-} ]]; then
continue
fi
nar_relative=$(sed -n 's/^URL: //p' "$narinfo_file")
store_path=$(sed -n 's/^StorePath: //p' "$narinfo_file")
if [[ $nar_relative != nar/* || -z $store_path ]]; then
echo "Malformed narinfo file: ${narinfo_file}" >&2
exit 1
fi
nar_name=${nar_relative#nar/}
nar_file="${cache_dir}/${nar_relative}"
if [[ ! -f $nar_file ]]; then
echo "NAR payload is missing: ${nar_file}" >&2
exit 1
fi
if [[ -z ${object_urls[$nar_name]:-} ]]; then
object_urls["$nar_name"]="${download_base}/${generation_tag}/${nar_name}"
object_sizes["$nar_name"]=$(stat -c '%s' "$nar_file")
if [[ -z ${queued_objects[$nar_name]:-} ]]; then
printf '%s\t%s\n' "$nar_file" "$nar_name" >>"$nar_upload_queue"
queued_objects["$nar_name"]=1
((new_nar_count += 1))
fi
jq -cn \
--arg key "$nar_name" \
--arg url "${object_urls[$nar_name]}" \
--arg generation "$generation_tag" \
--argjson size "${object_sizes[$nar_name]}" \
'{key: $key, value: {url: $url, generation: $generation, size: $size}}' \
>>"$object_updates_file"
fi
rewritten_file="${rewritten_dir}/${narinfo_name}"
awk -v url="${object_urls[$nar_name]}" '
BEGIN { replaced = 0 }
/^URL: / {
print "URL: " url
replaced = 1
next
}
{ print }
END { if (!replaced) exit 1 }
' "$narinfo_file" >"$rewritten_file"
if [[ -n ${index_asset_ids[$narinfo_name]:-} ]]; then
delete_asset "$index_release_id" "${index_asset_ids[$narinfo_name]}"
fi
printf '%s\t%s\n' "$rewritten_file" "$narinfo_name" >>"$narinfo_upload_queue"
jq -cn \
--arg key "$store_hash" \
--arg url "${cache_uri}/${narinfo_name}" \
--arg store_path "$store_path" \
--arg nar "$nar_name" \
'{key: $key, value: {url: $url, storePath: $store_path, nar: $nar}}' \
>>"$narinfo_updates_file"
((new_narinfo_count += 1))
done < <(find "$cache_dir" -maxdepth 1 -type f -name '*.narinfo' -print0 | sort -z)
echo "Uploading ${new_nar_count} new NAR objects to '${generation_tag}'..."
upload_queue "$generation_release_id" "$nar_upload_queue"
echo "Uploading ${new_narinfo_count} new narinfo files to '${index_tag}'..."
upload_queue "$index_release_id" "$narinfo_upload_queue"
now=$(date -u +%Y-%m-%dT%H:%M:%SZ)
generations_file="${work_dir}/generations.json"
jq --arg prefix "$generation_prefix" '
[
.[]
| select(.tag_name | startswith($prefix))
| {
tag: .tag_name,
commit: .target_commitish,
createdAt: .created_at
}
]
' "$all_releases_file" >"$generations_file"
jq -s \
--slurpfile object_updates "$object_updates_file" \
--slurpfile narinfo_updates "$narinfo_updates_file" \
--slurpfile generations "$generations_file" \
--arg generation_tag "$generation_tag" \
--arg commit "$commit" \
--arg now "$now" \
'
.[0]
| reduce $object_updates[] as $update (.; .objects[$update.key] = $update.value)
| reduce $narinfo_updates[] as $update (.; .narinfos[$update.key] = $update.value)
| .generatedAt = $now
| .objects as $objects
| .generations = (
reduce (
$generations[0] + [{tag: $generation_tag, commit: $commit, createdAt: $now}]
)[] as $generation (
{};
.[$generation.tag] = $generation
)
| [.[]]
| sort_by(.createdAt)
| map(
. as $generation
| . + {
objects: [
$objects
| to_entries[]
| select(.value.generation == $generation.tag)
| .key
]
}
)
)
' "$manifest_file" >"${manifest_file}.new"
mv "${manifest_file}.new" "$manifest_file"
if [[ $mode == bootstrap ]]; then
for root_asset_name in nix-cache-info cache-public-key; do
root_asset_id=${index_asset_ids[$root_asset_name]:-}
if [[ -n $root_asset_id ]]; then
delete_asset "$index_release_id" "$root_asset_id"
fi
done
upload_asset "$index_release_id" "${cache_dir}/nix-cache-info" nix-cache-info
printf '%s\n' "$public_key" >"${work_dir}/cache-public-key"
upload_asset "$index_release_id" "${work_dir}/cache-public-key" cache-public-key
fi
manifest_asset_name=cache-manifest.json
old_manifest_asset_id=${index_asset_ids[$manifest_asset_name]:-}
temporary_manifest_name="cache-manifest-${commit}.json"
while IFS= read -r stale_temporary_asset_id; do
delete_asset "$index_release_id" "$stale_temporary_asset_id"
done < <(
jq -r '
.assets[]?
| select(.name | test("^cache-manifest-[0-9a-f]+\\.json$"))
| .id
' "$index_release_file"
)
temporary_manifest_asset=$(
upload_asset_response "$index_release_id" "$manifest_file" "$temporary_manifest_name"
)
temporary_manifest_asset_id=$(jq -r '.id' <<<"$temporary_manifest_asset")
if [[ -z $temporary_manifest_asset_id || $temporary_manifest_asset_id == null ]]; then
echo "Could not determine the temporary manifest asset ID." >&2
exit 1
fi
if [[ -n $old_manifest_asset_id ]]; then
delete_asset "$index_release_id" "$old_manifest_asset_id"
fi
rename_asset "$index_release_id" "$temporary_manifest_asset_id" "$manifest_asset_name"
echo "Published Nix cache generation: ${generation_tag}"
echo "Cache URI: ${cache_uri}"
echo "Public key: ${public_key}"
-46
View File
@@ -1,46 +0,0 @@
name: Bootstrap Nix binary cache
on:
workflow_dispatch:
permissions:
contents: write
concurrency:
group: nix-release-cache-publisher
cancel-in-progress: false
jobs:
bootstrap:
name: Build every host and bootstrap the cache
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Nix
uses: cachix/install-nix-action@v31
with:
extra_nix_config: |
experimental-features = nix-command flakes
accept-flake-config = true
- name: Build and publish the initial cache
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
NIX_CACHE_PRIVATE_KEY: ${{ secrets.NIX_CACHE_PRIVATE_KEY }}
CACHE_MODE: bootstrap
CACHE_REPOSITORY: moons-14/dotfiles
CACHE_SERVER_URL: https://git.yutakobayashi.com
CACHE_COMMIT: ${{ github.sha }}
CACHE_REF_NAME: ${{ github.ref_name }}
run: |
set -euo pipefail
if [[ -z "${NIX_CACHE_PRIVATE_KEY:-}" ]]; then
echo "Repository secret NIX_CACHE_PRIVATE_KEY is required." >&2
exit 1
fi
key_file="${RUNNER_TEMP:-/tmp}/nix-cache-private-key"
umask 077
printf '%s\n' "$NIX_CACHE_PRIVATE_KEY" > "$key_file"
unset NIX_CACHE_PRIVATE_KEY
export NIX_CACHE_KEY_FILE="$key_file"
trap 'rm -f "$key_file"' EXIT
./.gitea/scripts/publish-nix-cache.sh
-49
View File
@@ -1,49 +0,0 @@
name: Update Nix binary cache
on:
push:
branches:
- "**"
workflow_dispatch:
permissions:
contents: write
concurrency:
group: nix-release-cache-publisher
cancel-in-progress: false
jobs:
update:
name: Build every host and publish new cache objects
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Nix
uses: cachix/install-nix-action@v31
with:
extra_nix_config: |
experimental-features = nix-command flakes
accept-flake-config = true
- name: Build and publish new cache objects
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
NIX_CACHE_PRIVATE_KEY: ${{ secrets.NIX_CACHE_PRIVATE_KEY }}
CACHE_MODE: update
CACHE_REPOSITORY: moons-14/dotfiles
CACHE_SERVER_URL: https://git.yutakobayashi.com
CACHE_COMMIT: ${{ github.sha }}
CACHE_REF_NAME: ${{ github.ref_name }}
run: |
set -euo pipefail
if [[ -z "${NIX_CACHE_PRIVATE_KEY:-}" ]]; then
echo "Repository secret NIX_CACHE_PRIVATE_KEY is required." >&2
exit 1
fi
key_file="${RUNNER_TEMP:-/tmp}/nix-cache-private-key"
umask 077
printf '%s\n' "$NIX_CACHE_PRIVATE_KEY" > "$key_file"
unset NIX_CACHE_PRIVATE_KEY
export NIX_CACHE_KEY_FILE="$key_file"
trap 'rm -f "$key_file"' EXIT
./.gitea/scripts/publish-nix-cache.sh
@@ -0,0 +1,260 @@
name: Update Flake Input
description: Update one GitHub-backed Nix flake input and create a pull request
inputs:
input-name:
description: Name of the flake input to update
required: true
github-token:
description: Token used to query GitHub, push the update branch, and manage the pull request
required: true
base-branch:
description: Branch targeted by the pull request
required: false
default: main
minimum-release-age-days:
description: Minimum age of the target commit in days
required: false
default: "3"
skip-delay:
description: Update to the latest revision without applying the minimum age
required: false
default: "false"
auto-merge:
description: Enable squash auto-merge on the pull request
required: false
default: "true"
pr-labels:
description: Comma-separated labels to add when they already exist in the repository
required: false
default: dependencies,automated
outputs:
updated:
description: Whether flake.lock changed
value: ${{ steps.update.outputs.updated }}
current-version:
description: Previous locked revision
value: ${{ steps.update.outputs.current_version }}
new-version:
description: New locked revision
value: ${{ steps.update.outputs.new_version }}
pr-url:
description: URL of the created or updated pull request
value: ${{ steps.pull-request.outputs.pr_url }}
runs:
using: composite
steps:
- name: Update flake input
id: update
shell: bash
env:
GH_TOKEN: ${{ inputs.github-token }}
INPUT_NAME: ${{ inputs.input-name }}
MINIMUM_RELEASE_AGE_DAYS: ${{ inputs.minimum-release-age-days }}
SKIP_DELAY: ${{ inputs.skip-delay }}
run: |
set -euo pipefail
if [[ ! "$MINIMUM_RELEASE_AGE_DAYS" =~ ^[0-9]+$ ]]; then
echo "::error::minimum-release-age-days must be a non-negative integer"
exit 1
fi
node_key="$(
jq -er --arg input "$INPUT_NAME" '
.nodes.root.inputs[$input]
| if type == "array" then .[0] else . end
' flake.lock
)"
input_type="$(jq -r --arg node "$node_key" '.nodes[$node].locked.type // ""' flake.lock)"
input_owner="$(jq -r --arg node "$node_key" '.nodes[$node].locked.owner // ""' flake.lock)"
input_repo="$(jq -r --arg node "$node_key" '.nodes[$node].locked.repo // ""' flake.lock)"
input_ref="$(jq -r --arg node "$node_key" '.nodes[$node].original.ref // ""' flake.lock)"
current_rev="$(jq -er --arg node "$node_key" '.nodes[$node].locked.rev' flake.lock)"
if [ "$input_type" != "github" ] || [ -z "$input_owner" ] || [ -z "$input_repo" ]; then
echo "::error::${INPUT_NAME} is not a GitHub-backed flake input"
exit 1
fi
echo "Input: $INPUT_NAME"
echo "Repository: ${input_owner}/${input_repo}"
echo "Current revision: $current_rev"
if [ "$SKIP_DELAY" = "true" ]; then
nix flake update "$INPUT_NAME"
else
cutoff="$(date --utc --date="${MINIMUM_RELEASE_AGE_DAYS} days ago" +%Y-%m-%dT%H:%M:%SZ)"
api_args=(
--method GET
"repos/${input_owner}/${input_repo}/commits"
-f "until=$cutoff"
-f per_page=1
)
if [ -n "$input_ref" ]; then
api_args+=(-f "sha=$input_ref")
fi
echo "Selecting the newest commit no later than $cutoff"
target_data="$(gh api "${api_args[@]}" --jq '.[0] | {sha: .sha, date: .commit.committer.date}')"
target_rev="$(jq -er '.sha' <<< "$target_data")"
target_date="$(jq -er '.date' <<< "$target_data")"
if [ "$target_rev" = "$current_rev" ]; then
echo "The input is already at the newest eligible revision"
{
echo "updated=false"
echo "current_version=$current_rev"
echo "new_version=$current_rev"
} >> "$GITHUB_OUTPUT"
exit 0
fi
current_date="$(
gh api "repos/${input_owner}/${input_repo}/commits/${current_rev}" \
--jq '.commit.committer.date'
)"
current_timestamp="$(date --date="$current_date" +%s)"
target_timestamp="$(date --date="$target_date" +%s)"
if [ "$target_timestamp" -lt "$current_timestamp" ]; then
echo "The newest eligible revision is older than the current revision; skipping"
{
echo "updated=false"
echo "current_version=$current_rev"
echo "new_version=$current_rev"
} >> "$GITHUB_OUTPUT"
exit 0
fi
nix flake update "$INPUT_NAME" \
--override-input "$INPUT_NAME" "github:${input_owner}/${input_repo}/${target_rev}"
fi
if git diff --quiet -- flake.lock; then
echo "No lock file changes were produced"
{
echo "updated=false"
echo "current_version=$current_rev"
echo "new_version=$current_rev"
} >> "$GITHUB_OUTPUT"
exit 0
fi
new_node_key="$(
jq -er --arg input "$INPUT_NAME" '
.nodes.root.inputs[$input]
| if type == "array" then .[0] else . end
' flake.lock
)"
new_rev="$(jq -er --arg node "$new_node_key" '.nodes[$node].locked.rev' flake.lock)"
echo "New revision: $new_rev"
{
echo "updated=true"
echo "current_version=$current_rev"
echo "new_version=$new_rev"
echo "input_owner=$input_owner"
echo "input_repo=$input_repo"
} >> "$GITHUB_OUTPUT"
- name: Create or update pull request
id: pull-request
if: steps.update.outputs.updated == 'true'
shell: bash
env:
GH_TOKEN: ${{ inputs.github-token }}
INPUT_NAME: ${{ inputs.input-name }}
BASE_BRANCH: ${{ inputs.base-branch }}
CURRENT_REV: ${{ steps.update.outputs.current_version }}
NEW_REV: ${{ steps.update.outputs.new_version }}
INPUT_OWNER: ${{ steps.update.outputs.input_owner }}
INPUT_REPO: ${{ steps.update.outputs.input_repo }}
MINIMUM_RELEASE_AGE_DAYS: ${{ inputs.minimum-release-age-days }}
SKIP_DELAY: ${{ inputs.skip-delay }}
AUTO_MERGE: ${{ inputs.auto-merge }}
PR_LABELS: ${{ inputs.pr-labels }}
run: |
set -euo pipefail
branch_suffix="$(tr -c 'A-Za-z0-9._-' '-' <<< "$INPUT_NAME" | sed 's/-$//')"
branch="update-flake-${branch_suffix}"
current_short="${CURRENT_REV:0:8}"
new_short="${NEW_REV:0:8}"
title="chore(nix): update ${INPUT_NAME} to ${new_short}"
if [ "$SKIP_DELAY" = "true" ]; then
age_note="The minimum release age check was skipped for this manually requested update."
else
age_note="The target commit is at least ${MINIMUM_RELEASE_AGE_DAYS} days old."
fi
body="$(
printf '%s\n' \
"Automated update of the \`${INPUT_NAME}\` flake input." \
"" \
"- Previous revision: [\`${current_short}\`](https://github.com/${INPUT_OWNER}/${INPUT_REPO}/commit/${CURRENT_REV})" \
"- New revision: [\`${new_short}\`](https://github.com/${INPUT_OWNER}/${INPUT_REPO}/commit/${NEW_REV})" \
"- Changes: [compare](https://github.com/${INPUT_OWNER}/${INPUT_REPO}/compare/${CURRENT_REV}...${NEW_REV})" \
"" \
"$age_note"
)"
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add flake.lock
git switch -C "$branch"
git commit -m "$title"
git fetch origin "refs/heads/${branch}:refs/remotes/origin/${branch}" || true
git push --force-with-lease origin "HEAD:refs/heads/${branch}"
label_args=()
available_labels="$(gh label list --limit 100 --json name --jq '.[].name')"
IFS=',' read -ra requested_labels <<< "$PR_LABELS"
for label in "${requested_labels[@]}"; do
label="$(xargs <<< "$label")"
if [ -n "$label" ] && grep -Fxq "$label" <<< "$available_labels"; then
label_args+=(--add-label "$label")
elif [ -n "$label" ]; then
echo "::warning::Skipping missing pull request label: $label"
fi
done
pr_number="$(
gh pr list \
--state open \
--head "$branch" \
--json number \
--jq '.[0].number // empty'
)"
if [ -n "$pr_number" ]; then
gh pr edit "$pr_number" \
--title "$title" \
--body "$body" \
"${label_args[@]}"
else
gh pr create \
--base "$BASE_BRANCH" \
--head "$branch" \
--title "$title" \
--body "$body"
pr_number="$(
gh pr list \
--state open \
--head "$branch" \
--json number \
--jq '.[0].number'
)"
if [ "${#label_args[@]}" -gt 0 ]; then
gh pr edit "$pr_number" "${label_args[@]}"
fi
fi
if [ "$AUTO_MERGE" = "true" ]; then
gh pr merge "$pr_number" --auto --squash ||
echo "::warning::Auto-merge could not be enabled; check the repository merge settings"
fi
pr_url="$(gh pr view "$pr_number" --json url --jq '.url')"
echo "pr_url=$pr_url" >> "$GITHUB_OUTPUT"
echo "Pull request: $pr_url"
+4 -4
View File
@@ -21,11 +21,11 @@ jobs:
hosts: ${{ steps.hosts.outputs.hosts }}
steps:
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Install Nix
uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6
uses: cachix/install-nix-action@630ae543ea3a38a9a4166f03376c02c50f408342 # v31.11.0
with:
extra_nix_config: |
experimental-features = nix-command flakes
@@ -51,11 +51,11 @@ jobs:
host: ${{ fromJSON(needs.validate.outputs.hosts) }}
steps:
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Install Nix
uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6
uses: cachix/install-nix-action@630ae543ea3a38a9a4166f03376c02c50f408342 # v31.11.0
with:
extra_nix_config: |
experimental-features = nix-command flakes
+3 -3
View File
@@ -11,17 +11,17 @@ concurrency:
cancel-in-progress: false
jobs:
renovate:
name: Update Nix flake inputs
name: Update GitHub Actions dependencies
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
# Use a PAT or GitHub App token so Renovate PRs trigger the other workflows.
- name: Run Renovate
uses: renovatebot/github-action@22e0a16091fc706b04affe6ae53d5e3358ac4023 # v46.1.19
uses: renovatebot/github-action@3064367f740a1a91cca218698a63902689cce200 # v46.1.20
with:
renovate-version: 43.262.1
token: ${{ secrets.RENOVATE_TOKEN }}
+106
View File
@@ -0,0 +1,106 @@
name: Update Flake Inputs
on:
schedule:
# Every day at 03:30 JST (18:30 UTC on the previous day).
- cron: "30 18 * * *"
workflow_dispatch:
inputs:
input:
description: Update only this flake input (empty updates all inputs)
required: false
type: string
skip-delay:
description: Update to the latest revision without the three-day delay
required: false
default: false
type: boolean
auto-merge:
description: Enable auto-merge after required checks pass
required: false
default: true
type: boolean
permissions:
contents: write
pull-requests: write
concurrency:
group: update-flake-inputs
cancel-in-progress: false
jobs:
discover:
name: Discover flake inputs
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
matrix: ${{ steps.inputs.outputs.matrix }}
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Build update matrix
id: inputs
env:
REQUESTED_INPUT: ${{ inputs.input }}
run: |
set -euo pipefail
github_inputs="$(
jq -c '
. as $lock
| [
$lock.nodes.root.inputs
| to_entries[]
| .key as $name
| (
.value
| if type == "array" then .[0] else . end
) as $node
| select($lock.nodes[$node].locked.type == "github")
| $name
]
| sort
' flake.lock
)"
if [ -n "$REQUESTED_INPUT" ]; then
if ! jq -e --arg input "$REQUESTED_INPUT" 'index($input) != null' <<< "$github_inputs" >/dev/null; then
echo "::error::Unknown or unsupported flake input: $REQUESTED_INPUT"
exit 1
fi
matrix="$(jq -cn --arg input "$REQUESTED_INPUT" '{input: [$input]}')"
else
matrix="$(jq -cn --argjson inputs "$github_inputs" '{input: $inputs}')"
fi
echo "matrix=$matrix" >> "$GITHUB_OUTPUT"
echo "Update matrix: $matrix"
update:
name: Update ${{ matrix.input }}
needs: discover
if: ${{ needs.discover.outputs.matrix != '{"input":[]}' }}
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
fail-fast: false
max-parallel: 4
matrix: ${{ fromJSON(needs.discover.outputs.matrix) }}
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
token: ${{ secrets.RENOVATE_TOKEN }}
- name: Install Nix
uses: cachix/install-nix-action@630ae543ea3a38a9a4166f03376c02c50f408342 # v31.11.0
with:
extra_nix_config: |
experimental-features = nix-command flakes
accept-flake-config = true
access-tokens = github.com=${{ secrets.RENOVATE_TOKEN }}
- name: Update input
uses: ./.github/actions/update-flake-input
with:
input-name: ${{ matrix.input }}
github-token: ${{ secrets.RENOVATE_TOKEN }}
skip-delay: ${{ github.event_name == 'workflow_dispatch' && inputs.skip-delay }}
auto-merge: ${{ github.event_name != 'workflow_dispatch' || inputs.auto-merge }}
-76
View File
@@ -1,76 +0,0 @@
# Gitea Release-backed Nix binary cache
The workflows in `.gitea/workflows/` publish the closures of every
`nixosConfigurations` host to Gitea Releases.
- `nix-cache-bootstrap.yml` is a one-shot manual workflow that creates the
initial cache.
- `nix-cache-update.yml` runs on every branch push. It creates one immutable
generation release per commit and uploads only NAR content hashes that have
not appeared in an older generation.
- The `cache-latest` release is the stable cache index. It contains
`nix-cache-info`, `cache-public-key`, `cache-manifest.json`, and every
`<store-hash>.narinfo` file.
- Each narinfo has an absolute `URL:` that points at the generation release
containing its immutable NAR. Rewriting `URL:` does not alter the signed
store-path fingerprint.
The operational manifest enumerates all narinfo and NAR URLs. Nix itself does
not read that manifest: it requests `nix-cache-info` and
`<store-hash>.narinfo` directly from the cache URI.
## One-time setup
Generate a signing key on a trusted machine:
```sh
umask 077
nix key generate-secret --key-name dotfiles-gitea-cache-1 > cache-private-key
nix key convert-secret-to-public < cache-private-key
```
Add the complete contents of `cache-private-key` as the repository Actions
secret `NIX_CACHE_PRIVATE_KEY`. Do not commit this file. Ensure the repository
Actions token is allowed to write Releases, then run **Bootstrap Nix binary
cache** once from the Actions UI.
The bootstrap log and the following stable asset expose the public key:
```text
https://git.yutakobayashi.com/moons-14/dotfiles/releases/download/cache-latest/cache-public-key
```
The repository and its Release assets must be publicly readable for ordinary
Nix clients to use this as an unauthenticated substituter. The runner needs
enough disk for the Nix store plus one compressed copy of all host closures.
It also needs `bash`, `curl`, `jq`, and standard GNU userland tools.
## NixOS client configuration
After bootstrap, copy the exact value from `cache-public-key` into
`extra-trusted-public-keys`:
```nix
{
nix.settings = {
extra-substituters = [
"https://git.yutakobayashi.com/moons-14/dotfiles/releases/download/cache-latest"
];
extra-trusted-public-keys = [
"dotfiles-gitea-cache-1:REPLACE_WITH_THE_GENERATED_PUBLIC_KEY"
];
};
}
```
The substituter value is the directory-like cache URI, not the manifest file
URL. A quick validation after bootstrap is:
```sh
cache=https://git.yutakobayashi.com/moons-14/dotfiles/releases/download/cache-latest
curl --fail "$cache/nix-cache-info"
curl --fail "$cache/cache-manifest.json" | jq '.cache, (.objects | length), (.narinfos | length)'
```
Because every branch receives the signing secret, only trusted users should be
allowed to push branches or modify Actions workflows in this repository.
Generated
+256 -249
View File
@@ -88,11 +88,11 @@
]
},
"locked": {
"lastModified": 1782772816,
"narHash": "sha256-s9BuFv0mRuZx9C1MF8qPHRdcAK14ONi0A5m6E2wqOoM=",
"lastModified": 1784665499,
"narHash": "sha256-9BMxlTxCCDAeoNLtb1a/st7udtTIJep+wpUzquA29VU=",
"owner": "nix-community",
"repo": "bun2nix",
"rev": "5a39d717029e94163ac223aee8d5c9946cafed1c",
"rev": "0f2a1f0b6f42cebe3b149bf62d38754c5e0e9729",
"type": "github"
},
"original": {
@@ -104,16 +104,14 @@
"codex-desktop-linux": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": [
"nixpkgs-unstable"
]
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1784027639,
"narHash": "sha256-1h+sL/eGX3a0rblwLBwSWBI1exxZsBsH8WaYnWTjY5Q=",
"lastModified": 1784823421,
"narHash": "sha256-/EM7Cr2Ai0VjNbKv+eIW0+iXT/NBW6WbPkCbf9w+u/o=",
"owner": "ilysenko",
"repo": "codex-desktop-linux",
"rev": "9b7f1c513d3d4cb62fe05c73c0db5b7ef0efc618",
"rev": "efcf40b5ab41323c8fa8eef5526c6a50c45fd8cd",
"type": "github"
},
"original": {
@@ -124,11 +122,11 @@
},
"crane": {
"locked": {
"lastModified": 1783203018,
"narHash": "sha256-G6R9IT/xwFuu+CYBWDUAok6AdC4ERC4ZfPPFtEpxnZE=",
"lastModified": 1784407669,
"narHash": "sha256-gcFMcRjw0ZSn380Rx2QLlU1goUQeSrKX/DF12omI6+o=",
"owner": "ipetkov",
"repo": "crane",
"rev": "80db5bdc391be8a1794f6d8a2d56e3a84ebcede2",
"rev": "1316b7d278ad77a16aec024b71d971366e123bec",
"type": "github"
},
"original": {
@@ -160,11 +158,11 @@
"firefox-gnome-theme": {
"flake": false,
"locked": {
"lastModified": 1779670703,
"narHash": "sha256-UdfMivNMwCCqQsYDg5pSz8X2IOaOrIZLIIy+Bg3CO2o=",
"lastModified": 1782007937,
"narHash": "sha256-PbnJr+eB+9Czol3ReI83dUgEhcn0sDK6TSy6ODTQm88=",
"owner": "rafaelmardojai",
"repo": "firefox-gnome-theme",
"rev": "942159e73e40bf785816f7f1f5feed9ef3d7c8f9",
"rev": "981bd332015397fb1ca033fa982bd61635160c78",
"type": "github"
},
"original": {
@@ -176,11 +174,11 @@
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1761588595,
"narHash": "sha256-XKUZz9zewJNUj46b4AJdiRZJAvSZ0Dqj2BNfXvFlJC4=",
"lastModified": 1767039857,
"narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "f387cd2afec9419c8ee37694406ca490c3f34ee5",
"rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab",
"type": "github"
},
"original": {
@@ -321,11 +319,11 @@
]
},
"locked": {
"lastModified": 1778716662,
"narHash": "sha256-m1Yf0wZ8j1OHjTc2UwHwyQRSnNeSgLJOd7q5Y45hzi4=",
"lastModified": 1782949081,
"narHash": "sha256-vp6Y/Grm98ESt6ceOkWiHWyZRDV3J1RID4w+6NWK9yA=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "f7c1a2d347e4c52d5fb8d10cb4d94b5884e546fb",
"rev": "17c9d6cdfc60c64f4ee8d306f9bc0b4ccb51481e",
"type": "github"
},
"original": {
@@ -372,17 +370,17 @@
"inputs": {
"flake-compat": "flake-compat",
"home-manager": "home-manager",
"nixpkgs": "nixpkgs",
"nixpkgs": "nixpkgs_2",
"systems": "systems_2",
"zig": "zig",
"zon2nix": "zon2nix"
},
"locked": {
"lastModified": 1783580960,
"narHash": "sha256-41eBs4g66qLFEa6esgaCAs1hp1et5551Tqs/jriyI3c=",
"lastModified": 1784868212,
"narHash": "sha256-DvPf4hVaD8iEeSfqhPCfAtD9kWkBAODqvxp9rmEBgPo=",
"owner": "moons-14",
"repo": "ghostty",
"rev": "6260e9da0baba6c94c3e8f537558bc69085229b9",
"rev": "4c725242b7dbe8c77c6e227ef1f9540c5ef17921",
"type": "github"
},
"original": {
@@ -394,14 +392,14 @@
"git-hooks-nix": {
"inputs": {
"flake-compat": "flake-compat_2",
"nixpkgs": "nixpkgs_2"
"nixpkgs": "nixpkgs_3"
},
"locked": {
"lastModified": 1783008725,
"narHash": "sha256-jGiy6+sxjNWXSjp25uoJuNfyH9zBK1PEDY0lVoL4ibQ=",
"lastModified": 1784288435,
"narHash": "sha256-ReRHaLgr/uVqdD8afFSn+myXIfpHeOhP0yYe0TJqAA8=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "bca82caa46d5ec0f5d422c61fb1e30bc51313cbe",
"rev": "43b3c1ab9d40fb1dbb008f451988a91e375825e9",
"type": "github"
},
"original": {
@@ -413,18 +411,20 @@
"gnome-shell": {
"flake": false,
"locked": {
"lastModified": 1767737596,
"narHash": "sha256-eFujfIUQDgWnSJBablOuG+32hCai192yRdrNHTv0a+s=",
"host": "gitlab.gnome.org",
"lastModified": 1776175984,
"narHash": "sha256-RJFlFW8GiMei6oqUGrMkGEvVqOH8U7Q8abc1yK4VKD8=",
"owner": "GNOME",
"repo": "gnome-shell",
"rev": "ef02db02bf0ff342734d525b5767814770d85b49",
"type": "github"
"rev": "e0fdc4c13250e9a9b8ea9594c83925274f4a5dca",
"type": "gitlab"
},
"original": {
"host": "gitlab.gnome.org",
"owner": "GNOME",
"ref": "50.1",
"repo": "gnome-shell",
"rev": "ef02db02bf0ff342734d525b5767814770d85b49",
"type": "github"
"type": "gitlab"
}
},
"home-manager": {
@@ -435,11 +435,11 @@
]
},
"locked": {
"lastModified": 1770586272,
"narHash": "sha256-Ucci8mu8QfxwzyfER2DQDbvW9t1BnTUJhBmY7ybralo=",
"lastModified": 1782657028,
"narHash": "sha256-PHTCpYZCMzJYS3phhywqRAZphKVr2zjvlGYa+H20ZZ4=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "b1f916ba052341edc1f80d4b2399f1092a4873ca",
"rev": "4ad9aaae70c9aaab504127f926c0fa9cfbc2b365",
"type": "github"
},
"original": {
@@ -455,11 +455,11 @@
]
},
"locked": {
"lastModified": 1783740085,
"narHash": "sha256-qajyHfZY29G2oEQk+uHxmsJcRoBUBXP9maTpFlwP/dI=",
"lastModified": 1784350909,
"narHash": "sha256-ZWyzLbS1yKUTeFJLmdVuWNnHttL333/ldJbEE+KzCrM=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "3cd22efe6471dc7365c822bd9ad73a21e55f38fb",
"rev": "4ce190229c73d44536caa7072f6308fb2d8feeb3",
"type": "github"
},
"original": {
@@ -500,11 +500,11 @@
"rust-overlay": "rust-overlay"
},
"locked": {
"lastModified": 1783496806,
"narHash": "sha256-6B6CQUk1dPc8l/+otaGiYbuX8qeX/0VmSUQ+qSn0/uA=",
"lastModified": 1784568171,
"narHash": "sha256-t17AqLEhPG6m27ipkp8mJd8Ug0XkdANFDVsgyIFBZcQ=",
"owner": "nix-community",
"repo": "lanzaboote",
"rev": "6183ac79eadb079a1e72fa2c60915601be669100",
"rev": "f4b0aef3dba28677a5ca4b3416827aade60b5a0b",
"type": "github"
},
"original": {
@@ -517,18 +517,16 @@
"inputs": {
"bun2nix": "bun2nix",
"flake-parts": "flake-parts_2",
"nixpkgs": [
"nixpkgs-unstable"
],
"nixpkgs": "nixpkgs_4",
"systems": "systems_3",
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1784012825,
"narHash": "sha256-lbdkOH57StVOFMEpFASzEmi+GlK3iX6Uu7Y2zGUgVFE=",
"lastModified": 1784838505,
"narHash": "sha256-v9wgz4KSm259C+Yb9/Y/tPyylXto/bTyOQyiV599Ads=",
"owner": "numtide",
"repo": "llm-agents.nix",
"rev": "5c73869318afcf796a7a465b4b5e31b27f0819d4",
"rev": "b358b1d5b458d6bd9814d02b70fcd3c0cd61886f",
"type": "github"
},
"original": {
@@ -541,17 +539,17 @@
"inputs": {
"niri-stable": "niri-stable",
"niri-unstable": "niri-unstable",
"nixpkgs": "nixpkgs_3",
"nixpkgs": "nixpkgs_5",
"nixpkgs-stable": "nixpkgs-stable",
"xwayland-satellite-stable": "xwayland-satellite-stable",
"xwayland-satellite-unstable": "xwayland-satellite-unstable"
},
"locked": {
"lastModified": 1783896799,
"narHash": "sha256-eXIwrSxH79I3WgRg2q0zLEi6+fyEsd2PisHv2FaR0Po=",
"lastModified": 1784874881,
"narHash": "sha256-u4jhSIf/Un0qZB+Cn3hTTaHSI20XeAxYbA5o4faqdJs=",
"owner": "sodiboo",
"repo": "niri-flake",
"rev": "9d808f1bb6e86239780039bc18abb64e5415cb23",
"rev": "ef7a2a3d719af46b906c22a3ebfb7d65627b2cd2",
"type": "github"
},
"original": {
@@ -580,11 +578,11 @@
"niri-unstable": {
"flake": false,
"locked": {
"lastModified": 1783522755,
"narHash": "sha256-dI0HkX1djETia7cD/Y64h8BNIsSOfTRMzfNum2J6UhE=",
"lastModified": 1784570726,
"narHash": "sha256-9EMn69JBcFWFgUM7f0VBAX+jBby5b9H3M59U75+5yI4=",
"owner": "YaLTeR",
"repo": "niri",
"rev": "0777769e719b7c9b7c980d4ea66288bfbb4da5b3",
"rev": "7f26c3ee804fb6ed458ef7fb0e3c794f14e0b3bc",
"type": "github"
},
"original": {
@@ -621,11 +619,11 @@
]
},
"locked": {
"lastModified": 1783864904,
"narHash": "sha256-BQxN5UMg9FOevAsgBRwPxfxlh51Puj+dNn/8Dsi3sPM=",
"lastModified": 1784440659,
"narHash": "sha256-Q5kNLlWngt7TaIIZoxDKWMHjiSaNRVqr70FqWCRRfr4=",
"owner": "nix-community",
"repo": "nix-index-database",
"rev": "1111b9bc836afb7e31a7014e8d1272de9b1c917d",
"rev": "4f8d52a3598b0dc7db7a5e7b419e3edd9d1ecfdb",
"type": "github"
},
"original": {
@@ -636,14 +634,14 @@
},
"nixos-hardware": {
"inputs": {
"nixpkgs": "nixpkgs_4"
"nixpkgs": "nixpkgs_6"
},
"locked": {
"lastModified": 1783792734,
"narHash": "sha256-50rvY9GdFvpYDcMLcD/4cWSi0hVxArT5wsGlVsHy8eY=",
"lastModified": 1784723954,
"narHash": "sha256-1CfD8ZUjCkTgjsneLZ/lxCHhgDfqxxE7/GX0MmsgiqA=",
"owner": "NixOS",
"repo": "nixos-hardware",
"rev": "8efb4337e857949f4cfac86d12ef1066f417f31f",
"rev": "a017f5b72210026af5b3ac5949f08d94380a6fbd",
"type": "github"
},
"original": {
@@ -656,14 +654,14 @@
"nixos-wsl": {
"inputs": {
"flake-compat": "flake-compat_4",
"nixpkgs": "nixpkgs_5"
"nixpkgs": "nixpkgs_7"
},
"locked": {
"lastModified": 1783897948,
"narHash": "sha256-wusXpttNJn7SvUMvGLpNuJgcwIIkMwlWNnasPPxpftg=",
"lastModified": 1784642409,
"narHash": "sha256-hcbDqFuySAJawljt5r0sKBCJKYnbtGD0T/ZIozH1Dq0=",
"owner": "nix-community",
"repo": "NixOS-WSL",
"rev": "7348d3f38ab1bd6abe156a923fab6f43656b168f",
"rev": "eaeb18da90024448a60eb1ec7132eafa4003404e",
"type": "github"
},
"original": {
@@ -674,15 +672,18 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1770537093,
"narHash": "sha256-XV30uo8tXuxdzuV8l3sojmlPRLd/8tpMsOp4lNzLGUo=",
"rev": "fef9403a3e4d31b0a23f0bacebbec52c248fbb51",
"type": "tarball",
"url": "https://releases.nixos.org/nixpkgs/nixpkgs-26.05pre942631.fef9403a3e4d/nixexprs.tar.xz"
"lastModified": 1772773019,
"narHash": "sha256-E1bxHxNKfDoQUuvriG71+f+s/NT0qWkImXsYZNFFfCs=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "aca4d95fce4914b3892661bcb80b8087293536c6",
"type": "github"
},
"original": {
"type": "tarball",
"url": "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz"
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-lib": {
@@ -734,11 +735,11 @@
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1783915482,
"narHash": "sha256-FmieJB8/OUvNxbkboi7+IGfIuSXY3nF/hZQm8kD0r50=",
"lastModified": 1785009302,
"narHash": "sha256-IFv7UnewuC5hjMo8KdnGGHSYTW2UJZKZvvZyBd/Wj0s=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "6cdc7fc76e8bf7fde9fa43a849fcaaa70e230dee",
"rev": "0267914b93539fd1a77d38e7244f7efeca4d76a5",
"type": "github"
},
"original": {
@@ -748,100 +749,7 @@
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1782918843,
"narHash": "sha256-ETYnV9U7Sr+A45dohzZdfCZKOss4qrTkO+wgNZNvEc0=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e8273b29fe1390ec8d4603f2477357555291432e",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1783776592,
"narHash": "sha256-UgCQzxeWI75XM8G+hPrPh+MKzEPjG3SpAj7dtqSbksA=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e7a3ca8092b61ff85b6a45bf863ea2b2d6a661b3",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_4": {
"locked": {
"lastModified": 1767892417,
"narHash": "sha256-8bW3q88CEg2u4hSP66Vf4lpbLonHz7hqDNBMcCY7E9U=",
"rev": "3497aa5c9457a9d88d71fa93a4a8368816fbeeba",
"type": "tarball",
"url": "https://releases.nixos.org/nixos/unstable/nixos-26.05pre924538.3497aa5c9457/nixexprs.tar.xz"
},
"original": {
"type": "tarball",
"url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz"
}
},
"nixpkgs_5": {
"locked": {
"lastModified": 1783224372,
"narHash": "sha256-8i/87eeoqiGE4yOTjwSA3Eh/ziJRQEmd/unYU+K27sk=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "d407951447dcd00442e97087bf374aad70c04cea",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_6": {
"locked": {
"lastModified": 1783856661,
"narHash": "sha256-ZGP04e+Q6WyQJGA9ZvI5CL6+heGQldbAG9U1T9NGvmU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "569d578509928497eddc3fdbf94a799027050be4",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-26.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_7": {
"locked": {
"lastModified": 1770107345,
"narHash": "sha256-tbS0Ebx2PiA1FRW8mt8oejR0qMXmziJmPaU1d4kYY9g=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "4533d9293756b63904b7238acb84ac8fe4c8c2c4",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_8": {
"nixpkgs_10": {
"locked": {
"lastModified": 1772542754,
"narHash": "sha256-WGV2hy+VIeQsYXpsLjdr4GvHv5eECMISX1zKLTedhdg=",
@@ -857,7 +765,7 @@
"type": "github"
}
},
"nixpkgs_9": {
"nixpkgs_11": {
"locked": {
"lastModified": 1778869304,
"narHash": "sha256-30sZNZoA1cqF5JNO9fVX+wgiQYjB7HJqqJ4ztCDeBZE=",
@@ -873,6 +781,128 @@
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1782545840,
"narHash": "sha256-CAi8oAZaE6pTkcYQBnnOlvmfMgG/p1AO0FohKKN3J7I=",
"rev": "3d46470bb3030020f7e1361f33514854f5bfa86d",
"type": "tarball",
"url": "https://releases.nixos.org/nixpkgs/nixpkgs-26.11pre1023445.3d46470bb303/nixexprs.tar.xz"
},
"original": {
"type": "tarball",
"url": "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1782918843,
"narHash": "sha256-ETYnV9U7Sr+A45dohzZdfCZKOss4qrTkO+wgNZNvEc0=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e8273b29fe1390ec8d4603f2477357555291432e",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_4": {
"locked": {
"lastModified": 1784555310,
"narHash": "sha256-/FCliTPgiuV1owejZFNx3Ch9irdvkOfOFl+HHZ+DrtM=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "421eebfd0ec7bccd4abe826ce62d7e6e83129493",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_5": {
"locked": {
"lastModified": 1784796856,
"narHash": "sha256-wWFrV5/Qbm+lyt5x20E/bSbfJiGKMo4RCxZV8cl/WZI=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e2587caef70cea85dd97d7daab492899902dbf5d",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_6": {
"locked": {
"lastModified": 1767892417,
"narHash": "sha256-8bW3q88CEg2u4hSP66Vf4lpbLonHz7hqDNBMcCY7E9U=",
"rev": "3497aa5c9457a9d88d71fa93a4a8368816fbeeba",
"type": "tarball",
"url": "https://releases.nixos.org/nixos/unstable/nixos-26.05pre924538.3497aa5c9457/nixexprs.tar.xz"
},
"original": {
"type": "tarball",
"url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz"
}
},
"nixpkgs_7": {
"locked": {
"lastModified": 1783776592,
"narHash": "sha256-UgCQzxeWI75XM8G+hPrPh+MKzEPjG3SpAj7dtqSbksA=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e7a3ca8092b61ff85b6a45bf863ea2b2d6a661b3",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_8": {
"locked": {
"lastModified": 1784923315,
"narHash": "sha256-2e5BnQ0YLJMIRII1BdGsLiBcJ1fRVauvZypwZIR2JLw=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "d2f1d98be0573ebf42b96630bc8d7001ff62af43",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-26.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_9": {
"locked": {
"lastModified": 1770107345,
"narHash": "sha256-tbS0Ebx2PiA1FRW8mt8oejR0qMXmziJmPaU1d4kYY9g=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "4533d9293756b63904b7238acb84ac8fe4c8c2c4",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixvim": {
"inputs": {
"flake-parts": "flake-parts_3",
@@ -903,11 +933,11 @@
]
},
"locked": {
"lastModified": 1784027510,
"narHash": "sha256-XnZWqhZSo72MScneUZYqhiQdYEnI5M5uwEj9sqxxb7s=",
"lastModified": 1784917398,
"narHash": "sha256-lBVMJgBWbC3H6UGlCYiu8pbgUJqWWyJ70n/xIljk/1I=",
"owner": "noctalia-dev",
"repo": "noctalia",
"rev": "7b2e0da85e6fd72db72676395eb029f30af1337e",
"rev": "0cd9b22e19fb71455c950a70c11324b7e245a790",
"type": "github"
},
"original": {
@@ -928,11 +958,11 @@
]
},
"locked": {
"lastModified": 1780281641,
"narHash": "sha256-M/+hUKoKbHXpV0xGVfELbN1Ds1aoe3pL5p5/t46YhVo=",
"lastModified": 1783439237,
"narHash": "sha256-WUr8JF2v3n4Y30E5dxv4sAgNJXpVDBoCQNoQ/V4+n4o=",
"owner": "nix-community",
"repo": "NUR",
"rev": "30f9ae2f04174de63ba8bcf3580ca90843b28a01",
"rev": "b70bb66c7bcd162642f3a609bc16843c7059f503",
"type": "github"
},
"original": {
@@ -950,11 +980,11 @@
]
},
"locked": {
"lastModified": 1783008725,
"narHash": "sha256-jGiy6+sxjNWXSjp25uoJuNfyH9zBK1PEDY0lVoL4ibQ=",
"lastModified": 1784288435,
"narHash": "sha256-ReRHaLgr/uVqdD8afFSn+myXIfpHeOhP0yYe0TJqAA8=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "bca82caa46d5ec0f5d422c61fb1e30bc51313cbe",
"rev": "43b3c1ab9d40fb1dbb008f451988a91e375825e9",
"type": "github"
},
"original": {
@@ -978,7 +1008,7 @@
"nix-index-database": "nix-index-database",
"nixos-hardware": "nixos-hardware",
"nixos-wsl": "nixos-wsl",
"nixpkgs": "nixpkgs_6",
"nixpkgs": "nixpkgs_8",
"nixpkgs-unstable": "nixpkgs-unstable",
"nixvim": "nixvim",
"noctalia": "noctalia",
@@ -999,11 +1029,11 @@
]
},
"locked": {
"lastModified": 1783488441,
"narHash": "sha256-jmWf+H3iC/0z7/mmvTovaJx1E/LME1QyHkyk+AFfJPk=",
"lastModified": 1784438913,
"narHash": "sha256-NYF7ZM5ip0u+w1pBFDpIGEbrbgN/wpnLFAmBkWkYMXw=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "7dc3a177a239ed879c5581a80f6dc246c7e102f1",
"rev": "afacd6819d3765a05814ee8e3de74c77d42ac799",
"type": "github"
},
"original": {
@@ -1014,11 +1044,11 @@
},
"services-flake": {
"locked": {
"lastModified": 1783213527,
"narHash": "sha256-yIVKacNpTvEY+xQf2MzNn6jerRrazrkXxTwmwTK4N7M=",
"lastModified": 1784799366,
"narHash": "sha256-aK4fmqmGbk0J2sUhex79NAZTd1002DNWNsfubO6aic0=",
"owner": "juspay",
"repo": "services-flake",
"rev": "1c9142a3d74abc53aed62687106ee15e873dc3ff",
"rev": "eed1ab55413afbb8fd7bc929076c73894e5104e0",
"type": "github"
},
"original": {
@@ -1049,7 +1079,7 @@
},
"soulver-cpp": {
"inputs": {
"nixpkgs": "nixpkgs_9",
"nixpkgs": "nixpkgs_11",
"nixpkgs-libxml2": "nixpkgs-libxml2"
},
"locked": {
@@ -1086,11 +1116,11 @@
"tinted-zed": "tinted-zed"
},
"locked": {
"lastModified": 1783358511,
"narHash": "sha256-/F85cBWvU8b2hpawuCog464065ZTJtdMgVPWwJ9yHjE=",
"lastModified": 1784676123,
"narHash": "sha256-ndyanKzw90yX2nUVFmTuYqXidUNymtMfgmIHyNdhht0=",
"owner": "nix-community",
"repo": "stylix",
"rev": "14814ef555d8148ab82eba5054e654cd9eae3a1f",
"rev": "66714e5ce44269ecc58c20d9196da8dbe1b27a31",
"type": "github"
},
"original": {
@@ -1239,11 +1269,11 @@
"tinted-schemes": {
"flake": false,
"locked": {
"lastModified": 1777806186,
"narHash": "sha256-PDF0/wObw4nIsSBeXVYLsloXOiphXCgIdsrNcVXguKs=",
"lastModified": 1781968807,
"narHash": "sha256-yYO3Vw2M0y3TAUqt+9+Mj0zwP3XDTF5/PXcPhhFQ1ZM=",
"owner": "tinted-theming",
"repo": "schemes",
"rev": "0c94645546f4f3ddac77a1a5fce54eb95bf50795",
"rev": "2ccef2f4b22e3cab5a9292811f7133a07eeba4a7",
"type": "github"
},
"original": {
@@ -1255,11 +1285,11 @@
"tinted-tmux": {
"flake": false,
"locked": {
"lastModified": 1778379944,
"narHash": "sha256-wPDFzMGSlARlw0Sfsn48Q2+jPSfk6N0Ng6BC/d+7Q24=",
"lastModified": 1782012462,
"narHash": "sha256-2iDiD8DQLwS1lGuD9TS8WlvNyDoTs6krWntJbtB2zGo=",
"owner": "tinted-theming",
"repo": "tinted-tmux",
"rev": "fe0203a198690e71a5ff11e08812a4673de3678d",
"rev": "8c4e750f738a742bd73377ee41d3dadedebedef4",
"type": "github"
},
"original": {
@@ -1271,11 +1301,11 @@
"tinted-zed": {
"flake": false,
"locked": {
"lastModified": 1778378178,
"narHash": "sha256-OXPXRIQgGwV77HjYRryOHguh4ALX96jkg+tseLkGgHA=",
"lastModified": 1782009766,
"narHash": "sha256-VUhBjpGvWqHI7rWeyMYb/u87YJSXHKfVV6S+IelWeO8=",
"owner": "tinted-theming",
"repo": "base16-zed",
"rev": "9cd816033ff969415b190722cddf134e78a5665f",
"rev": "5e8350bcd354e3241ab681a265fa6ef060c40be1",
"type": "github"
},
"original": {
@@ -1292,11 +1322,11 @@
]
},
"locked": {
"lastModified": 1780220602,
"narHash": "sha256-eynAfOmbmxJnkp7YewvCEbShNnnYJ9gLLqkzsYtBPeM=",
"lastModified": 1784369104,
"narHash": "sha256-47cxbcZODibHv3rELFQ9vZly0vUNkND/atn/U7HLeb0=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "db947814a175b7ca6ded66e21383d938df01c227",
"rev": "df3c0640565d04a0261253cdd89fce78ec50168a",
"type": "github"
},
"original": {
@@ -1307,14 +1337,14 @@
},
"treefmt-nix_2": {
"inputs": {
"nixpkgs": "nixpkgs_7"
"nixpkgs": "nixpkgs_9"
},
"locked": {
"lastModified": 1780220602,
"narHash": "sha256-eynAfOmbmxJnkp7YewvCEbShNnnYJ9gLLqkzsYtBPeM=",
"lastModified": 1784369104,
"narHash": "sha256-47cxbcZODibHv3rELFQ9vZly0vUNkND/atn/U7HLeb0=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "db947814a175b7ca6ded66e21383d938df01c227",
"rev": "df3c0640565d04a0261253cdd89fce78ec50168a",
"type": "github"
},
"original": {
@@ -1325,16 +1355,16 @@
},
"vicinae": {
"inputs": {
"nixpkgs": "nixpkgs_8",
"nixpkgs": "nixpkgs_10",
"soulver-cpp": "soulver-cpp",
"systems": "systems_7"
},
"locked": {
"lastModified": 1783972265,
"narHash": "sha256-wALYzewjUgVZrxl9FQji4ZzBAT5CGTVlR+cFCD0G11U=",
"lastModified": 1784839524,
"narHash": "sha256-B87U5HDB/6JPxSnNQwnIiwtqUWvyxzqs7lV/GPzva68=",
"owner": "vicinaehq",
"repo": "vicinae",
"rev": "94f9570f096a407d27e18073d1b01dae13c4d064",
"rev": "632ca79e9f8fc9721384921f28ec069ff48aaf53",
"type": "github"
},
"original": {
@@ -1353,11 +1383,11 @@
"vicinae": "vicinae_2"
},
"locked": {
"lastModified": 1783009133,
"narHash": "sha256-Non+frT3WG0TN60zCq63m8+d7yNmCCMaI363kZaDmPM=",
"lastModified": 1784504910,
"narHash": "sha256-fzPBEJZiRvc/FNMdpbdcfaZzF01U4IQenHW9IQFzhos=",
"owner": "vicinaehq",
"repo": "extensions",
"rev": "afb84fe4b5253777ff82db8e19e6cc0c9b7f811f",
"rev": "ca74eede9a778a9373c8f5fd221b0a5026dcd1ef",
"type": "github"
},
"original": {
@@ -1411,11 +1441,11 @@
"xwayland-satellite-unstable": {
"flake": false,
"locked": {
"lastModified": 1783895132,
"narHash": "sha256-Dl0Gvrig3EpE962hzF3ETPhUztlfuRhcmlpd8ioHN54=",
"lastModified": 1784679892,
"narHash": "sha256-Mb7jpqnrcYCfNSItIkkHpuR3YxWFxPuIBfcwNKlRBkk=",
"owner": "Supreeeme",
"repo": "xwayland-satellite",
"rev": "a2b5c635d8c8c99b286967658d0d177044887eb8",
"rev": "8d135d3b2854b30fd01ea6cd6c27e523dd50a839",
"type": "github"
},
"original": {
@@ -1440,11 +1470,11 @@
]
},
"locked": {
"lastModified": 1776789209,
"narHash": "sha256-G6B7Q4TXn7MZ1mB+f9rymjsYF5PLWoSvmbxijb/99bw=",
"lastModified": 1782609341,
"narHash": "sha256-OfCPJFS/2Z2ZyjE4adR7PL+ZEqvDQFi2XNI1L8s6wKU=",
"owner": "mitchellh",
"repo": "zig-overlay",
"rev": "14fe971844e841297ddd2ce9783d6892b467af39",
"rev": "5386fea92c45b154bbeb52d14ef5504f82eda86c",
"type": "github"
},
"original": {
@@ -1453,42 +1483,19 @@
"type": "github"
}
},
"zig_2": {
"inputs": {
"nixpkgs": [
"ghostty",
"zon2nix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1777234348,
"narHash": "sha256-fKw44a4qbUuI5eTG8k0gPbqMV5TOrjYF35PBzsYgd2U=",
"ref": "refs/heads/main",
"rev": "2c781c0609ecda600ab98f98cca417bbd981bd53",
"revCount": 1677,
"type": "git",
"url": "https://codeberg.org/jcollie/zig-overlay.git"
},
"original": {
"type": "git",
"url": "https://codeberg.org/jcollie/zig-overlay.git"
}
},
"zon2nix": {
"inputs": {
"nixpkgs": [
"ghostty",
"nixpkgs"
],
"zig": "zig_2"
]
},
"locked": {
"lastModified": 1777314365,
"narHash": "sha256-eLxQaD0wc96Neqkln8wHS0rNq/chPODifFkhwrwilEU=",
"lastModified": 1784117571,
"narHash": "sha256-Hvnmnuu0VpHiZl+8z+UkMoxC7JZJvRYBqu2Asb0ZJOE=",
"owner": "jcollie",
"repo": "zon2nix",
"rev": "a5a1d412ad1ab6305511997bbc92b3a9dd6cb784",
"rev": "0ce628fb78309cdb13d098ae9c6fdbf87c75d25b",
"type": "github"
},
"original": {
-2
View File
@@ -78,12 +78,10 @@
# LLM agents
llm-agents = {
url = "github:numtide/llm-agents.nix";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
codex-desktop-linux = {
url = "github:ilysenko/codex-desktop-linux";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
# Index / Search
+1
View File
@@ -38,6 +38,7 @@
./vscode
./wayland.nix
./yazi.nix
./zed
./zellij
./zoom.nix
./zoxide.nix
+5 -1
View File
@@ -6,6 +6,10 @@
}:
let
cfg = config.my.applications.grok;
grok = pkgs.llm-agents.grok.overrideAttrs (_old: {
versionCheckProgram = "${placeholder "out"}/libexec/grok/grok-launcher";
});
in
{
options.my.applications.grok = {
@@ -14,7 +18,7 @@ in
config = lib.mkIf cfg.enable {
environment.systemPackages = [
pkgs.llm-agents.grok # Grok AI CLI
grok
];
};
}
+1 -1
View File
@@ -34,7 +34,7 @@ in
Service = {
Type = "forking";
ExecStart = "${lib.getExe pkgs.swaylock} -f";
ExecStart = "${lib.getExe pkgs.swaylock} -f -i %h/.wallpapers/28.jpg";
Restart = "on-failure";
RestartSec = 0;
};
+8 -3
View File
@@ -14,8 +14,13 @@ in
config = lib.mkIf cfg.enable {
services.systemd-lock-handler.enable = true;
# Screen unlocking deliberately uses passwords only. Fingerprints remain
# available to explicitly enabled PAM services such as sudo and polkit.
security.pam.services.swaylock.fprintAuth = false;
security.pam.services.swaylock.fprintAuth = true;
# PAM authentication is serial. Let a supplied password succeed before
# starting fprintd, whose scan otherwise blocks password verification until
# its timeout expires. Submit an empty password to start fingerprint
# authentication in upstream swaylock.
security.pam.services.swaylock.rules.auth.fprintd.order =
config.security.pam.services.swaylock.rules.auth.unix.order + 50;
};
}
+5
View File
@@ -53,6 +53,11 @@ in
extensions = with inputs.vicinae-extensions.packages.${pkgs.stdenv.hostPlatform.system}; [
nix
power-profile
niri
zoxide-recent-directories
ssh
port-killer
noctalia-shell-wallpaper-selector
];
};
}
-6
View File
@@ -19,19 +19,13 @@ in
# modules do not each append their own portal backends.
xdg.portal = {
enable = true;
wlr.enable = true;
extraPortals = [
pkgs.xdg-desktop-portal-gnome
pkgs.xdg-desktop-portal-gtk
pkgs.xdg-desktop-portal-wlr
];
xdgOpenUsePortal = true;
config = {
common.default = [ "gtk" ];
niri.default = lib.mkForce [
"wlr"
"gtk"
];
gnome.default = [
"gnome"
"gtk"
+21
View File
@@ -0,0 +1,21 @@
{
lib,
config,
...
}:
let
cfg = config.my.applications.zed;
in
{
imports = [
./home.nix
];
options.my.applications.zed = {
enable = lib.mkEnableOption "Zed code editor";
};
config = lib.mkIf cfg.enable {
my.applications.zed.homeManager.enable = lib.mkDefault true;
};
}
+66
View File
@@ -0,0 +1,66 @@
{
lib,
config,
...
}:
let
cfg = config.my.applications.zed.homeManager;
in
{
options.my.applications.zed.homeManager = {
enable = lib.mkEnableOption "Zed home-manager configuration";
};
config.home-manager.sharedModules = [
{
config = lib.mkIf cfg.enable {
programs.zed-editor = {
enable = true;
extensions = [
"catppuccin"
"nix"
];
mutableUserSettings = false;
userSettings = {
agent = {
flexible = true;
favorite_models = [ ];
model_parameters = [ ];
};
project_panel.dock = "left";
telemetry = {
diagnostics = false;
metrics = false;
};
vim_mode = true;
agent_servers = {
github-copilot-cli.type = "registry";
codex-acp.type = "registry";
claude-acp.type = "registry";
};
icon_theme = {
mode = "dark";
light = "Zed (Default)";
dark = "Zed (Default)";
};
ui_font_size = 16;
buffer_font_size = 16;
theme = {
mode = "dark";
light = "Catppuccin Latte";
dark = "Catppuccin Mocha";
};
};
};
};
}
];
}
+1 -16
View File
@@ -1,19 +1,10 @@
{
pkgs,
lib,
config,
...
}:
let
cfg = config.my.applications.zoom;
zoomX11 = pkgs.zoom-us.overrideAttrs (old: {
nativeBuildInputs = (old.nativeBuildInputs or [ ]) ++ [ pkgs.makeWrapper ];
postFixup = (old.postFixup or "") + ''
wrapProgram $out/bin/zoom \
--set QT_QPA_PLATFORM xcb
'';
});
in
{
options.my.applications.zoom = {
@@ -21,12 +12,6 @@ in
};
config = lib.mkIf cfg.enable {
home-manager.sharedModules = [
{
home.packages = with pkgs; [
zoomX11 # Video conferencing application with XWayland startup for GNOME stability
];
}
];
programs.zoom-us.enable = true;
};
}
+1
View File
@@ -33,6 +33,7 @@ in
unzip # Tool For Handling .zip Files
unrar # Tool For Handling .rar Files
ripgrep # Fast Search Tool
jq # Lightweight JSON processor
nurl # CLI tool for generating Nix fetcher calls from URLs
eza # ls alternative
bat # cat alternative
+2
View File
@@ -3,6 +3,8 @@
./agent.nix
./arduino.nix
./bun.nix
./dns.nix
./drawio.nix
./java.nix
./nix.nix
./python.nix
+20
View File
@@ -0,0 +1,20 @@
{
pkgs,
lib,
config,
...
}:
let
cfg = config.my.features.dev.dns;
in
{
options.my.features.dev.dns = {
enable = lib.mkEnableOption "DNS development tools (dig)";
};
config = lib.mkIf cfg.enable {
environment.systemPackages = with pkgs; [
bind # DNS lookup utilities (dig, host, nslookup)
];
};
}
+20
View File
@@ -0,0 +1,20 @@
{
pkgs,
lib,
config,
...
}:
let
cfg = config.my.features.dev.drawio;
in
{
options.my.features.dev.drawio = {
enable = lib.mkEnableOption "Draw.io diagram editor";
};
config = lib.mkIf cfg.enable {
environment.systemPackages = with pkgs; [
drawio # Diagram editor
];
};
}
+18
View File
@@ -12,6 +12,24 @@ in
};
config = lib.mkIf cfg.enable {
home-manager.sharedModules = [
{
xdg.userDirs = {
enable = true;
createDirectories = true;
desktop = "$HOME/Desktop";
documents = "$HOME/Documents";
download = "$HOME/Downloads";
music = "$HOME/Music";
pictures = "$HOME/Pictures";
projects = "$HOME/Projects";
publicShare = "$HOME/Public";
templates = "$HOME/Templates";
videos = "$HOME/Videos";
};
}
];
my.applications = {
gnome.enable = true;
gtk.enable = true;
+5 -2
View File
@@ -4,10 +4,13 @@ let
in
{
options.my.features.gui.editor = {
enable = lib.mkEnableOption "GUI code editor (VSCode)";
enable = lib.mkEnableOption "GUI code editors (VSCode and Zed)";
};
config = lib.mkIf cfg.enable {
my.applications.vscode.enable = true;
my.applications = {
vscode.enable = true;
zed.enable = true;
};
};
}
+2
View File
@@ -7,6 +7,7 @@ _: {
"https://noctalia.cachix.org"
"https://vicinae.cachix.org"
"https://cache.numtide.com"
"https://codex-desktop-linux.cachix.org"
];
extra-trusted-public-keys = [
@@ -16,6 +17,7 @@ _: {
"noctalia.cachix.org-1:pCOR47nnMEo5thcxNDtzWpOxNFQsBRglJzxWPp3dkU4="
"vicinae.cachix.org-1:1kDrfienkGHPYbkpNj1mWTr7Fm1+zcenzgTizIcI3oc="
"niks3.numtide.com-1:DTx8wZduET09hRmMtKdQDxNNthLQETkc/yaX7M4qK0g="
"codex-desktop-linux.cachix.org-1:nX/xy6AdK9hQE24A8ALGjkCKj2ObFmcnemiL5Cid4nk="
];
experimental-features = [
+2 -2
View File
@@ -1,6 +1,6 @@
{ inputs, ... }:
{
flake.overlays = {
default = inputs.llm-agents.overlays.shared-nixpkgs;
flake.overlays.default = final: {
llm-agents = inputs.llm-agents.packages.${final.stdenv.hostPlatform.system};
};
}
+2
View File
@@ -6,6 +6,8 @@
nix.enable = true;
python.enable = true;
bun.enable = true;
dns.enable = true;
drawio.enable = true;
java.enable = true;
};
gui.editor.enable = true;
+6 -13
View File
@@ -1,20 +1,13 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:recommended", "helpers:pinGitHubActionDigests"],
"enabledManagers": ["github-actions", "nix"],
"nix": {
"enabled": true
},
"enabledManagers": ["github-actions"],
"prHourlyLimit": 0,
"prCreation": "immediate",
"semanticCommits": "enabled",
"semanticCommitType": "chore",
"semanticCommitScope": "deps",
"packageRules": [
{
"description": "Group Nix flake input updates",
"matchManagers": ["nix"],
"groupName": "Nix flake inputs",
"groupSlug": "nix-flake-inputs"
}
]
"semanticCommitScope": "deps"
}