Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions .github/workflows/build-nix.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Build Nix and cache it. Regenerate settings.

on:
workflow_dispatch:
pull_request:
push:
branches:
- main
tags:
- 'v*'

jobs:
build-and-push:
name: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: cachix/install-nix-action@v31
with:
nix_path: nixpkgs=channel:nixos-unstable
- uses: cachix/cachix-action@v14
with:
name: xaltsc-jfnd
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
- name: Build packages and push to cachix
run: nix build .#packages.x86_64-linux.default

regen-settings:
permissions:
contents: write
pull-requests: write
needs: build-and-push
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: cachix/install-nix-action@v31
with:
nix_path: nixpkgs=channel:nixos-unstable
- uses: cachix/cachix-action@v14
with:
name: xaltsc-jfnd
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
- name: Build packages and push to cachix
run: nix run . -- --generate-settings-schema > dev/nix/home/_settings.json
- name: Create PR if needed
uses: peter-evans/create-pull-request@v8
with:
commit-message: "flake: update settings schema"
title: "Update settings schema"
body: "Auto-generated by CI."
branch: auto-update-settings-schema
delete-branch: true
labels: |
settings
automated
nix
74 changes: 74 additions & 0 deletions .github/workflows/cef-nix-sync-in-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
name: Sync nix CEF version on PR open

on:
pull_request:
types: [ opened ]

permissions:
contents: write
pull-requests: write

jobs:
update-nix-ver:
runs-on: ubuntu-latest
# Only fire on a Renovate update CEF PR
if: >-
github.event.pull_request.user.login == 'renovate[bot]' &&
startsWith(github.event.pull_request.title, 'Update Rust crate cef')
steps:
- name: Check out the PR
uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.head.ref }}

- name: Install Nix
uses: cachix/install-nix-action@v31
with:
nix_path: nixpkgs=channel:nixos-unstable

- name: Update nix cef-binary if needed
run: |
set -o pipefail
UPDATE_SCRIPT="$(nix-instantiate --eval -E '(builtins.getFlake (toString ./.)).packages.${builtins.currentSystem}.cef-binary.passthru.updateScript')"
"${UPDATE_SCRIPT}" 2>&1 | tee /tmp/script.log

- name: Build the PR body
run: |
{
echo 'Automated changes produced by `cef-binary` `updateScript`.'
echo
echo "<details><summary>Script output</summary>"
echo
echo '````'
cat /tmp/script.log
echo '````'
echo
echo "</details>"
} > /tmp/pr-body.md

- name: Commit any changes
run: |
git config user.name 'github-actions[bot]'
git config user.email 'github-actions[bot]@users.noreply.github.com'
if git diff --quiet && git diff --cached --quiet; then
echo "Nothing to commit"
echo "EMPTY_COMMIT=1" >> "${GITHUB_ENV}"
else
VER="$(cat /tmp/pr-body.md | grep -e '^Target' | cut -d':' -f2 | tr -d ' ')"
git add -A
git commit -m "Updated nix cef-binary to match rust version v${VER}"
git push
fi

- name: Comment on the PR
env:
GH_TOKEN: ${{ github.token }}
PR_NUM: ${{ github.event.pull_request.number }}
run: |
if [ "$EMPTY_COMMIT" = 1 ]; then
gh pr comment "${PR_NUM}" \
--body 'Everything seems up to date on `nix` side.'
else
gh pr comment "${PR_NUM}" \
--body-file /tmp/pr-body.md
fi
27 changes: 27 additions & 0 deletions .github/workflows/update-flake-lock.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: update-flake-lock

on:
workflow_dispatch:
schedule:
- cron: '0 4 * * 1' # weekly, Monday 04:00 UTC

jobs:
lockfile:
permissions:
contents: write
id-token: write
issues: write
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- uses: DeterminateSystems/determinate-nix-action@v3

- uses: DeterminateSystems/update-flake-lock@main
with:
pr-title: "Update flake.lock"
pr-labels: |
dependencies
automated
nix
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ build/
dist/
src/target/

# Nix
result

# Python
__pycache__/
*.pyc
Expand Down
5 changes: 5 additions & 0 deletions dev/nix/flake/flake-parts.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{ inputs, ... }: {
imports = [
inputs.flake-parts.flakeModules.modules
];
}
3 changes: 3 additions & 0 deletions dev/nix/flake/systems.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{ inputs, ... }: {
systems = inputs.nixpkgs.lib.systems.flakeExposed;
}
78 changes: 78 additions & 0 deletions dev/nix/home/_settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "SettingsData",
"type": "object",
"properties": {
"serverUrl": {
"description": "Server URL",
"type": "string",
"format": "uri",
"examples": [
"https://jellyfin.domain.tld"
],
"default": ""
},
"hwdec": {
"description": "Hardware decoding mode (default: no)",
"type": "string",
"default": ""
},
"audioPassthrough": {
"description": "Audio passthrough codecs, e.g. ac3,dts-hd,eac3,truehd",
"type": "string",
"examples": [
"ac3,dts-hd"
],
"default": ""
},
"audioChannels": {
"description": "Audio channel layout, e.g. stereo, 5.1, 7.1",
"type": "string",
"examples": [
"7.1"
],
"default": ""
},
"logLevel": {
"description": "Log level",
"type": "string",
"examples": [
"debug"
],
"default": ""
},
"deviceName": {
"description": "Device name",
"type": "string",
"examples": [
"MYHOST"
],
"default": ""
},
"audioExclusive": {
"description": "Use exclusive audio output",
"type": "boolean",
"default": false
},
"disableGpuCompositing": {
"description": "Disable CEF GPU compositing",
"type": "boolean",
"default": false
},
"transparentTitlebar": {
"description": "Transparent title bar",
"type": "boolean",
"default": true
},
"forceTranscoding": {
"description": "Force transcoding",
"type": "boolean",
"default": false
},
"hideScrollbar": {
"description": "Enable hidden scrollbar",
"type": "boolean",
"default": true
}
}
}
139 changes: 139 additions & 0 deletions dev/nix/home/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
{ inputs, config, ... }:
let
packages = config.flake.packages;
in
{
imports = [ inputs.home-manager.flakeModules.home-manager ];
flake.homeModules = rec {
default = jellyfin-desktop;
jellyfin-desktop =
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.jellyfin-desktop;
inherit (lib)
mkEnableOption
mkOption
mkMerge
mkIf
types
literalExpression
;

inherit (types) nullOr;

jsonFormat = pkgs.formats.json { };

in
{
options.programs.jellyfin-desktop = {
cache.enable = mkEnableOption "Enable jellyfin cache";
enable = mkEnableOption "Enable jellyfin-desktop";
package = mkOption {
description = "Package for jellyfin-desktop";
type = types.package;
default = packages.${pkgs.stdenv.hostPlatform.system}.jellyfin-desktop;
defaultText = literalExpression "<flake>.packages.$system.jellyfin-desktop";
};
settings =
let
warningSuffix = "(if set, this option will overwrite settings on each generation)";
in
(lib.mapAttrs
(
_: v:
v
// (lib.optionalAttrs (v.type != types.bool) {
type = nullOr v.type;
default = null;
})
// {
description = "${v.description} ${warningSuffix}.";
}
)
(
let
settings = (lib.fromJSON (builtins.readFile ./_settings.json)).properties;
translateTypes =
typeString:
with lib.types;
{
string = str;
boolean = bool;
}
.${typeString};
maybeExample = v: if v ? examples then { example = builtins.head v.examples; } else { };
in
lib.mapAttrs (
n: v:
if v.type == "boolean" then
(lib.mkEnableOption v.description) // { inherit (v) default; }
else
(lib.mkOption (
{
inherit (v) description;
type = translateTypes v.type;
}
// (maybeExample v)
))
) settings
)
);
extraConfig = mkOption {
description = ''
Extra configuration to append to `settings.json`.
Translated from nix to JSON.
Values defined here overwrite those in settings.
'';
type = jsonFormat.type;
default = { };
example = {
someOption = true;
someOtherOption = false;
};
};
};

config = mkMerge [
(mkIf cfg.enable {
home.packages = [
# don't use the overlay as there's already a "jellyfin-desktop" package on nixpkgs.
cfg.package
];

home.activation.mergeJellyfinDesktopConfiguration =
let
nonNullSettings = (lib.attrsets.filterAttrs (_: v: v != null) cfg.settings) // cfg.extraConfig;
newSettingsFile = pkgs.writeText "jfnd-settings.json" (builtins.toJSON nonNullSettings);
target = "${config.xdg.configHome}/jellyfin-desktop/settings.json";
jq = lib.getExe pkgs.jq;
in
(mkIf (nonNullSettings != { }) (
lib.hm.dag.entryAfter [ "writeBoundary" ] ''
if [ -f "${target}" ]; then
${jq} -s '.[0] * .[1]' "${target}" "${newSettingsFile}" > "${target}.hm-tmp.json"
chmod --reference="${target}" "${target}.hm-tmp.json"
chown --reference="${target}" "${target}.hm-tmp.json"
$DRY_RUN_CMD mv "${target}.hm-tmp.json" "${target}"
else
$DRY_RUN_CMD mkdir -p "$(dirname "${target}")"
$DRY_RUN_CMD cp "${newSettingsFile}" "${target}"
$DRY_RUN_CMD chmod u+rw "${target}"
fi
''
));
})
(mkIf cfg.cache.enable {
nix.settings = {
substituters = [ "https://xaltsc-jfnd.cachix.org" ];
trusted-public-keys = [ "xaltsc-jfnd.cachix.org-1:cCD4MB/Hqw1ktSbT+Dtv0clFpK1/YksbIQExL1hBxqo=" ];
};
})
];
};
};
}
Loading