Compare commits

..

20 Commits

Author SHA1 Message Date
thomas d7a82d8801 Merge branch 'main' into bot/handy-0.7.10 2026-03-11 16:36:22 +00:00
thomas 0e854495ff fix zen-browser audio/video codecs with ffmpeg-full 2026-03-11 16:35:46 +00:00
thomas 520177b9a5 update and add some pkgs 2026-03-11 14:56:42 +00:00
gitea actions 56f2da8d22 update handy to 0.7.10 2026-03-11 06:40:25 +00:00
thomas effd3390c3 enable openssh 2026-03-10 11:53:13 +00:00
thomas 59c1dde695 update handy to 0.7.9 (#3)
automated update of handy appimage version and hash

Co-authored-by: gitea actions <actions@localhost>
Reviewed-on: #3
2026-03-09 17:39:54 +00:00
thomas fc60083346 test further 2026-03-09 17:38:43 +00:00
thomas 84585ae218 fix pr payload quoting in workflows 2026-03-09 17:37:04 +00:00
thomas 0f5f6f3694 make action pr auth failures explicit 2026-03-09 17:35:18 +00:00
thomas 1dfe28047c avoid github api rate limits in update workflows 2026-03-09 17:33:45 +00:00
thomas 1b63847315 add debug output to pr creation 2026-03-09 17:14:54 +00:00
thomas 76584c4983 use hardcoded gitea url and main branch for pr creation 2026-03-09 17:12:00 +00:00
thomas cf5a3a7725 use secrets.tea_token for gitea api auth 2026-03-09 17:03:35 +00:00
thomas b35d617b31 fix all workflows: use env vars for python f-strings 2026-03-09 16:20:03 +00:00
thomas a377ba9d2c fix handy workflow and add push trigger for testing
handy update / update-handy (push) Failing after 8s
2026-03-09 16:18:58 +00:00
thomas 6f3dfa8afa update 2026-03-09 16:10:42 +00:00
thomas 2708cc0acf workflow update 2026-03-09 16:08:50 +00:00
thomas e63dadd5ca test action 2026-03-09 16:06:25 +00:00
thomas b6cf2ff197 yay media ctrls 2026-03-09 15:58:30 +00:00
thomas 162bca9d81 add theming modules 2026-03-09 15:50:55 +00:00
9 changed files with 204 additions and 100 deletions
+52 -27
View File
@@ -14,6 +14,11 @@ jobs:
with: with:
fetch-depth: 0 fetch-depth: 0
- name: install nix
uses: cachix/install-nix-action@v27
with:
nix_path: nixpkgs=channel:nixos-unstable
- name: check latest handy release and update file - name: check latest handy release and update file
id: update id: update
shell: bash shell: bash
@@ -30,15 +35,10 @@ jobs:
PY PY
) )
latest_version=$(python - <<'PY' latest_version=$(curl -fsSLI -o /dev/null -w '%{url_effective}' \
import json, urllib.request 'https://github.com/cjpais/Handy/releases/latest' \
url='https://api.github.com/repos/cjpais/Handy/releases/latest' | sed -E 's#.*/##' \
with urllib.request.urlopen(url) as r: | sed 's/^v//')
data=json.load(r)
tag=data.get('tag_name','').lstrip('v')
print(tag)
PY
)
echo "current=$current_version" echo "current=$current_version"
echo "latest=$latest_version" echo "latest=$latest_version"
@@ -51,12 +51,16 @@ jobs:
url="https://github.com/cjpais/Handy/releases/download/v${latest_version}/Handy_${latest_version}_amd64.AppImage" url="https://github.com/cjpais/Handy/releases/download/v${latest_version}/Handy_${latest_version}_amd64.AppImage"
new_hash=$(nix store prefetch-file --json "$url" | python -c 'import json,sys; print(json.load(sys.stdin)["hash"])') new_hash=$(nix store prefetch-file --json "$url" | python -c 'import json,sys; print(json.load(sys.stdin)["hash"])')
export LATEST_VERSION="$latest_version"
export NEW_HASH="$new_hash"
python - <<PY python - <<PY
import re import re
import os
p='modules/pkgs/handy.nix' p='modules/pkgs/handy.nix'
s=open(p).read() s=open(p).read()
s=re.sub(r'(version\s*=\s*")[^"]+(";)', r'\1${latest_version}\2', s, count=1) s=re.sub(r'version\s*=\s*"[^"]+"', f'version = "{os.environ["LATEST_VERSION"]}"', s, count=1)
s=re.sub(r'(hash\s*=\s*")[^"]+(";)', r'\1${new_hash}\2', s, count=1) s=re.sub(r'hash\s*=\s*"[^"]+"', f'hash = "{os.environ["NEW_HASH"]}"', s, count=1)
open(p,'w').write(s) open(p,'w').write(s)
PY PY
@@ -81,34 +85,55 @@ jobs:
- name: open pull request - name: open pull request
if: steps.update.outputs.updated == 'true' if: steps.update.outputs.updated == 'true'
env: env:
GITEA_TOKEN: ${{ gitea.token }} GITEA_TOKEN: ${{ secrets.tea_token || secrets.TEA_TOKEN }}
shell: bash shell: bash
run: | run: |
set -euo pipefail set -euo pipefail
api="${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}" api="https://gitea.unrail.xyz/api/v1/repos/thomas/nixos-config"
branch="bot/handy-${{ steps.update.outputs.version }}" branch="bot/handy-${{ steps.update.outputs.version }}"
if [ -z "${GITEA_TOKEN:-}" ]; then
echo "GITEA_TOKEN is empty (check repo secret tea_token/TEA_TOKEN)"
exit 1
fi
echo "Checking for existing PRs..."
existing=$(curl -fsS \ existing=$(curl -fsS \
-H "Authorization: token ${GITEA_TOKEN}" \ -H "Authorization: token ${GITEA_TOKEN}" \
"${api}/pulls?state=open" \ "${api}/pulls?state=open" \
| python -c 'import json,sys; d=json.load(sys.stdin); b="'"$branch"'"; print(next((str(pr["number"]) for pr in d if pr.get("head",{}).get("ref")==b), ""))') | python -c 'import json,sys; d=json.load(sys.stdin); b="'"$branch"'"; print(next((str(pr["number"]) for pr in d if isinstance(pr,dict) and pr.get("head",{}).get("ref")==b), ""))')
if [ -n "$existing" ]; then if [ -n "$existing" ]; then
echo "PR already exists: #$existing" echo "PR already exists: #$existing"
exit 0 exit 0
fi fi
curl -fsS -X POST \ echo "Creating PR..."
-H "Authorization: token ${GITEA_TOKEN}" \ created="false"
-H "Content-Type: application/json" \ for head in "${branch}" "thomas:${branch}"; do
"${api}/pulls" \ echo "Trying head=${head}"
-d "$(cat <<JSON payload=$(printf '{"title":"update handy to %s","head":"%s","base":"main","body":"automated update of handy appimage version and hash"}' \
{ "${{ steps.update.outputs.version }}" "$head")
\"title\": \"update handy to ${{ steps.update.outputs.version }}\", response=$(curl -sS -w '\n%{http_code}' -X POST \
\"head\": \"${branch}\", -H "Authorization: token ${GITEA_TOKEN}" \
\"base\": \"${GITHUB_REF_NAME}\", -H "Content-Type: application/json" \
\"body\": \"automated update of handy appimage version and hash\" "${api}/pulls" \
} -d "$payload")
JSON
)" body=$(printf '%s\n' "$response" | sed '$d')
code=$(printf '%s\n' "$response" | tail -n1)
echo "Create PR status: $code"
echo "$body"
if [ "$code" -ge 200 ] && [ "$code" -lt 300 ]; then
created="true"
break
fi
done
if [ "$created" != "true" ]; then
echo "PR creation failed"
exit 1
fi
+50 -26
View File
@@ -14,6 +14,11 @@ jobs:
with: with:
fetch-depth: 0 fetch-depth: 0
- name: install nix
uses: cachix/install-nix-action@v27
with:
nix_path: nixpkgs=channel:nixos-unstable
- name: check latest helium release and update file - name: check latest helium release and update file
id: update id: update
shell: bash shell: bash
@@ -31,15 +36,10 @@ jobs:
PY PY
) )
latest_version=$(python - <<'PY' latest_version=$(curl -fsSLI -o /dev/null -w '%{url_effective}' \
import json, urllib.request 'https://github.com/imputnet/helium-linux/releases/latest' \
url='https://api.github.com/repos/imputnet/helium-linux/releases/latest' | sed -E 's#.*/##' \
with urllib.request.urlopen(url) as r: | sed 's/^v//')
data=json.load(r)
tag=data.get('tag_name','').lstrip('v')
print(tag)
PY
)
echo "current=$current_version" echo "current=$current_version"
echo "latest=$latest_version" echo "latest=$latest_version"
@@ -52,12 +52,16 @@ jobs:
url="https://github.com/imputnet/helium-linux/releases/download/${latest_version}/helium-${latest_version}-x86_64.AppImage" url="https://github.com/imputnet/helium-linux/releases/download/${latest_version}/helium-${latest_version}-x86_64.AppImage"
new_hash=$(nix store prefetch-file --json "$url" | python -c 'import json,sys; print(json.load(sys.stdin)["hash"])') new_hash=$(nix store prefetch-file --json "$url" | python -c 'import json,sys; print(json.load(sys.stdin)["hash"])')
export LATEST_VERSION="$latest_version"
export NEW_HASH="$new_hash"
python - <<PY python - <<PY
import re import re
import os
p='modules/pkgs/helium.nix' p='modules/pkgs/helium.nix'
s=open(p).read() s=open(p).read()
s=re.sub(r'(version\s*=\s*")[^"]+(";)', r'\1${latest_version}\2', s, count=1) s=re.sub(r'version\s*=\s*"[^"]+"', f'version = "{os.environ["LATEST_VERSION"]}"', s, count=1)
s=re.sub(r'(hash\s*=\s*")[^"]+(";)', r'\1${new_hash}\2', s, count=1) s=re.sub(r'hash\s*=\s*"[^"]+"', f'hash = "{os.environ["NEW_HASH"]}"', s, count=1)
open(p,'w').write(s) open(p,'w').write(s)
PY PY
@@ -82,14 +86,19 @@ jobs:
- name: open pull request - name: open pull request
if: steps.update.outputs.updated == 'true' if: steps.update.outputs.updated == 'true'
env: env:
GITEA_TOKEN: ${{ gitea.token }} GITEA_TOKEN: ${{ secrets.tea_token || secrets.TEA_TOKEN }}
shell: bash shell: bash
run: | run: |
set -euo pipefail set -euo pipefail
api="${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}" api="https://gitea.unrail.xyz/api/v1/repos/thomas/nixos-config"
branch="bot/helium-${{ steps.update.outputs.version }}" branch="bot/helium-${{ steps.update.outputs.version }}"
if [ -z "${GITEA_TOKEN:-}" ]; then
echo "GITEA_TOKEN is empty (check repo secret tea_token/TEA_TOKEN)"
exit 1
fi
# Skip if PR for this branch already exists # Skip if PR for this branch already exists
existing=$(curl -fsS \ existing=$(curl -fsS \
-H "Authorization: token ${GITEA_TOKEN}" \ -H "Authorization: token ${GITEA_TOKEN}" \
@@ -101,16 +110,31 @@ jobs:
exit 0 exit 0
fi fi
curl -fsS -X POST \ echo "Creating PR..."
-H "Authorization: token ${GITEA_TOKEN}" \ created="false"
-H "Content-Type: application/json" \ for head in "${branch}" "thomas:${branch}"; do
"${api}/pulls" \ echo "Trying head=${head}"
-d "$(cat <<JSON payload=$(printf '{"title":"update helium to %s","head":"%s","base":"main","body":"automated update of helium appimage version and hash"}' \
{ "${{ steps.update.outputs.version }}" "$head")
\"title\": \"update helium to ${{ steps.update.outputs.version }}\", response=$(curl -sS -w '\n%{http_code}' -X POST \
\"head\": \"${branch}\", -H "Authorization: token ${GITEA_TOKEN}" \
\"base\": \"${GITHUB_REF_NAME}\", -H "Content-Type: application/json" \
\"body\": \"automated update of helium appimage version and hash\" "${api}/pulls" \
} -d "$payload")
JSON
)" body=$(printf '%s\n' "$response" | sed '$d')
code=$(printf '%s\n' "$response" | tail -n1)
echo "Create PR status: $code"
echo "$body"
if [ "$code" -ge 200 ] && [ "$code" -lt 300 ]; then
created="true"
break
fi
done
if [ "$created" != "true" ]; then
echo "PR creation failed"
exit 1
fi
+51 -26
View File
@@ -14,6 +14,11 @@ jobs:
with: with:
fetch-depth: 0 fetch-depth: 0
- name: install nix
uses: cachix/install-nix-action@v27
with:
nix_path: nixpkgs=channel:nixos-unstable
- name: check latest zen browser release and update file - name: check latest zen browser release and update file
id: update id: update
shell: bash shell: bash
@@ -30,14 +35,10 @@ jobs:
PY PY
) )
latest_version=$(python - <<'PY' latest_version=$(curl -fsSLI -o /dev/null -w '%{url_effective}' \
import json, urllib.request 'https://github.com/zen-browser/desktop/releases/latest' \
url='https://api.github.com/repos/zen-browser/desktop/releases/latest' | sed -E 's#.*/##' \
with urllib.request.urlopen(url) as r: | sed 's/^v//')
data=json.load(r)
print(data.get('tag_name','').lstrip('v'))
PY
)
echo "current=$current_version" echo "current=$current_version"
echo "latest=$latest_version" echo "latest=$latest_version"
@@ -50,12 +51,16 @@ jobs:
url="https://github.com/zen-browser/desktop/releases/download/${latest_version}/zen-x86_64.AppImage" url="https://github.com/zen-browser/desktop/releases/download/${latest_version}/zen-x86_64.AppImage"
new_hash=$(nix store prefetch-file --json "$url" | python -c 'import json,sys; print(json.load(sys.stdin)["hash"])') new_hash=$(nix store prefetch-file --json "$url" | python -c 'import json,sys; print(json.load(sys.stdin)["hash"])')
export LATEST_VERSION="$latest_version"
export NEW_HASH="$new_hash"
python - <<PY python - <<PY
import re import re
import os
p='modules/pkgs/zen-browser.nix' p='modules/pkgs/zen-browser.nix'
s=open(p).read() s=open(p).read()
s=re.sub(r'(version\s*=\s*")[^"]+(";)', r'\1${latest_version}\2', s, count=1) s=re.sub(r'version\s*=\s*"[^"]+"', f'version = "{os.environ["LATEST_VERSION"]}"', s, count=1)
s=re.sub(r'(hash\s*=\s*")[^"]+(";)', r'\1${new_hash}\2', s, count=1) s=re.sub(r'hash\s*=\s*"[^"]+"', f'hash = "{os.environ["NEW_HASH"]}"', s, count=1)
open(p,'w').write(s) open(p,'w').write(s)
PY PY
@@ -80,34 +85,54 @@ jobs:
- name: open pull request - name: open pull request
if: steps.update.outputs.updated == 'true' if: steps.update.outputs.updated == 'true'
env: env:
GITEA_TOKEN: ${{ gitea.token }} GITEA_TOKEN: ${{ secrets.tea_token || secrets.TEA_TOKEN }}
shell: bash shell: bash
run: | run: |
set -euo pipefail set -euo pipefail
api="${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}" api="https://gitea.unrail.xyz/api/v1/repos/thomas/nixos-config"
branch="bot/zen-browser-${{ steps.update.outputs.version }}" branch="bot/zen-browser-${{ steps.update.outputs.version }}"
if [ -z "${GITEA_TOKEN:-}" ]; then
echo "GITEA_TOKEN is empty (check repo secret tea_token/TEA_TOKEN)"
exit 1
fi
existing=$(curl -fsS \ existing=$(curl -fsS \
-H "Authorization: token ${GITEA_TOKEN}" \ -H "Authorization: token ${GITEA_TOKEN}" \
"${api}/pulls?state=open" \ "${api}/pulls?state=open" \
| python -c 'import json,sys; d=json.load(sys.stdin); b="'"$branch"'"; print(next((str(pr["number"]) for pr in d if pr.get("head",{}).get("ref")==b), ""))') | python -c 'import json,sys; d=json.load(sys.stdin); b="'"$branch"'"; print(next((str(pr["number"]) for pr in d if isinstance(pr,dict) and pr.get("head",{}).get("ref")==b), ""))')
if [ -n "$existing" ]; then if [ -n "$existing" ]; then
echo "PR already exists: #$existing" echo "PR already exists: #$existing"
exit 0 exit 0
fi fi
curl -fsS -X POST \ echo "Creating PR..."
-H "Authorization: token ${GITEA_TOKEN}" \ created="false"
-H "Content-Type: application/json" \ for head in "${branch}" "thomas:${branch}"; do
"${api}/pulls" \ echo "Trying head=${head}"
-d "$(cat <<JSON payload=$(printf '{"title":"update zen browser to %s","head":"%s","base":"main","body":"automated update of zen browser appimage version and hash"}' \
{ "${{ steps.update.outputs.version }}" "$head")
\"title\": \"update zen browser to ${{ steps.update.outputs.version }}\", response=$(curl -sS -w '\n%{http_code}' -X POST \
\"head\": \"${branch}\", -H "Authorization: token ${GITEA_TOKEN}" \
\"base\": \"${GITHUB_REF_NAME}\", -H "Content-Type: application/json" \
\"body\": \"automated update of zen browser appimage version and hash\" "${api}/pulls" \
} -d "$payload")
JSON
)" body=$(printf '%s\n' "$response" | sed '$d')
code=$(printf '%s\n' "$response" | tail -n1)
echo "Create PR status: $code"
echo "$body"
if [ "$code" -ge 200 ] && [ "$code" -lt 300 ]; then
created="true"
break
fi
done
if [ "$created" != "true" ]; then
echo "PR creation failed"
exit 1
fi
+2
View File
@@ -2,6 +2,7 @@
flake.nixosModules.development = {pkgs, ...}: { flake.nixosModules.development = {pkgs, ...}: {
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
nodejs_24 nodejs_24
go
nixfmt nixfmt
zellij zellij
@@ -17,6 +18,7 @@
vscode-langservers-extracted # includes css-lsp, eslint-lsp, html-lsp, json-lsp vscode-langservers-extracted # includes css-lsp, eslint-lsp, html-lsp, json-lsp
tailwindcss-language-server tailwindcss-language-server
biome biome
typescript-go
# Treesitter CLI + C compiler for building grammars # Treesitter CLI + C compiler for building grammars
tree-sitter tree-sitter
+8
View File
@@ -48,6 +48,14 @@ flake.nixosModules.nixos-host = {pkgs, ...}: {
pulse.enable = true; pulse.enable = true;
}; };
# SSH
services.openssh = {
enable = true;
settings = {
PermitRootLogin = "no";
};
};
# User account # User account
users.users.${config.username} = { users.users.${config.username} = {
isNormalUser = true; isNormalUser = true;
+2
View File
@@ -20,6 +20,8 @@
feishin feishin
obsidian obsidian
self.packages.${pkgs.stdenv.hostPlatform.system}.handy self.packages.${pkgs.stdenv.hostPlatform.system}.handy
mpv
ffmpeg
]; ];
}; };
} }
+5 -5
View File
@@ -1,16 +1,16 @@
{ ... }: { {...}: {
perSystem = { pkgs, ... }: { perSystem = {pkgs, ...}: {
packages.handy = pkgs.appimageTools.wrapType2 rec { packages.handy = pkgs.appimageTools.wrapType2 rec {
pname = "handy"; pname = "handy";
version = "0.7.9"; version = "0.7.10";
src = pkgs.fetchurl { src = pkgs.fetchurl {
url = "https://github.com/cjpais/Handy/releases/download/v${version}/Handy_${version}_amd64.AppImage"; url = "https://github.com/cjpais/Handy/releases/download/v${version}/Handy_${version}_amd64.AppImage";
hash = "sha256-iSibRpme8xJfumhjJ2LzkrtFwV8j9nHajMnBygBFLz4="; hash = "sha256-vBOcXCCJr9D0u0h27nN4XLPPngx4m+toAfi6O6Fuojk=";
}; };
extraInstallCommands = let extraInstallCommands = let
contents = pkgs.appimageTools.extract { inherit pname version src; }; contents = pkgs.appimageTools.extract {inherit pname version src;};
in '' in ''
desktop_file=$(find ${contents} -name "*.desktop" | head -n1) desktop_file=$(find ${contents} -name "*.desktop" | head -n1)
if [ -n "$desktop_file" ]; then if [ -n "$desktop_file" ]; then
+28 -16
View File
@@ -1,29 +1,41 @@
{ ... }: { { lib, ... }: {
perSystem = { pkgs, ... }: { perSystem = { pkgs, ... }: let
packages.zen-browser = pkgs.appimageTools.wrapType2 rec { pname = "zen-browser";
pname = "zen-browser"; version = "1.19.1b";
version = "1.19.1b";
src = pkgs.fetchurl { src = pkgs.fetchurl {
url = "https://github.com/zen-browser/desktop/releases/download/${version}/zen-x86_64.AppImage"; url = "https://github.com/zen-browser/desktop/releases/download/${version}/zen-x86_64.AppImage";
hash = "sha256-h3lza2C+SxptpcX897Uf/nM8dNILUBXScSNQZlvSIQg="; hash = "sha256-h3lza2C+SxptpcX897Uf/nM8dNILUBXScSNQZlvSIQg=";
}; };
extraInstallCommands = let appimageContents = pkgs.appimageTools.extract { inherit pname version src; };
contents = pkgs.appimageTools.extract { inherit pname version src; }; in {
in '' packages.zen-browser = pkgs.appimageTools.wrapType2 {
desktop_file=$(find ${contents} -name "*.desktop" | head -n1) inherit pname version src;
extraPkgs = pkgs: [ pkgs.ffmpeg-full ];
extraInstallCommands = ''
desktop_file=$(find ${appimageContents} -name "*.desktop" | head -n1)
if [ -n "$desktop_file" ]; then if [ -n "$desktop_file" ]; then
install -m 444 -D "$desktop_file" "$out/share/applications/${pname}.desktop" install -m 444 -D "$desktop_file" "$out/share/applications/${pname}.desktop"
# The desktop file uses 'zen' as the binary name
substituteInPlace "$out/share/applications/${pname}.desktop" \ substituteInPlace "$out/share/applications/${pname}.desktop" \
--replace 'Exec=zen' 'Exec=${pname}' --replace 'Exec=zen' 'Exec=${pname}'
fi fi
if [ -d ${contents}/usr/share/icons ]; then if [ -d ${appimageContents}/usr/share/icons ]; then
cp -r ${contents}/usr/share/icons $out/share cp -r ${appimageContents}/usr/share/icons $out/share
fi fi
ln -s $out/bin/${pname} $out/bin/zen
''; '';
meta = {
description = "Experience tranquillity while browsing the web without people tracking you!";
homepage = "https://zen-browser.app";
license = lib.licenses.mpl20;
platforms = [ "x86_64-linux" ];
};
}; };
}; };
} }
+6
View File
@@ -27,10 +27,16 @@
programs.niri.enable = true; programs.niri.enable = true;
services.displayManager.sessionPackages = [ pkgs.niri ]; services.displayManager.sessionPackages = [ pkgs.niri ];
services.gnome.gnome-keyring.enable = true; # secret service services.gnome.gnome-keyring.enable = true; # secret service
services.playerctld.enable = true; # MPRIS media player daemon for playerctl
# enable xwayland-satellite # enable xwayland-satellite
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
xwayland-satellite xwayland-satellite
adw-gtk3
qgnomeplatform-qt6
]; ];
# Enable dconf for theme settings
programs.dconf.enable = true;
}; };
} }