diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 411dad1..71fa13b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,7 +32,14 @@ jobs: if: needs.changes.outputs.non_docs == 'true' uses: ./.github/workflows/on-workflow-call-lint.yml - smoke-test: + nix-smoke: + needs: + - shellcheck + - format + - lint + uses: ./.github/workflows/on-workflow-call-nix.yml + + distro-smoke: needs: - shellcheck - format diff --git a/.github/workflows/on-workflow-call-nix.yml b/.github/workflows/on-workflow-call-nix.yml new file mode 100644 index 0000000..590dece --- /dev/null +++ b/.github/workflows/on-workflow-call-nix.yml @@ -0,0 +1,56 @@ +name: nix + +on: + workflow_call: + +permissions: + contents: read + +jobs: + nix: + runs-on: ubuntu-latest + + defaults: + run: + shell: bash + + steps: + - name: checkout + uses: actions/checkout@v4 + + - name: install nix + uses: cachix/install-nix-action@v31 + with: + github_access_token: ${{ github.token }} + enable_kvm: true + extra_nix_config: | + system-features = nixos-test benchmark big-parallel kvm + + - name: flake check + run: nix flake check --print-build-logs + + - name: build package + run: nix build .#thyx --print-build-logs + + - name: nixos vm smoke + run: nix build .#checks.x86_64-linux.nixos-vm --print-build-logs + + - name: verify package layout + run: | + set -euo pipefail + + nix build .#thyx --print-build-logs + + out="$(readlink -f result)" + + test -f "${out}/share/sddm/themes/thyx/metadata.desktop" + test -f "${out}/share/sddm/themes/thyx/theme.conf" + test -f "${out}/share/sddm/themes/thyx/src/Main.qml" + + test -d "${out}/share/sddm/themes/thyx/backgrounds" + test -d "${out}/share/sddm/themes/thyx/icons" + test -d "${out}/share/sddm/themes/thyx/presets" + test -d "${out}/share/sddm/themes/thyx/src" + + test -f "${out}/share/fonts/truetype/thyx/PlusJakartaSans-VariableFont_wght.ttf" + test -f "${out}/share/fonts/truetype/thyx/PlusJakartaSans-Italic-VariableFont_wght.ttf" diff --git a/README.md b/README.md index 9d953db..5ecac13 100644 --- a/README.md +++ b/README.md @@ -95,19 +95,7 @@ Want a fast mental model of what this is, what SDDM is, and how recovery works? ## Installation -Clone the repo, then run the installer from the repo root. - -```bash -./scripts/install -``` - -For non interactive installs, pass `--yes`. - -```bash -./scripts/install --yes -``` - -The installer will install and setup everything for the following (through the manifests in [`scripts/data`](./scripts/data/)): +The installer is atomic and idempotent and will auto setup everything with one command for the following: - **Arch** @@ -131,6 +119,22 @@ The installer will install and setup everything for the following (through the m - **Gentoo** - **Alpine Edge** +Simply run: + +```bash +git clone https://github.com/rccyx/thyx && cd thyx +bash ./scripts/install +``` + +For non interactive installs, pass `--yes`. + +```bash +bash ./scripts/install --yes +``` + +> [!IMPORTANT] +> Using NixOS? It's supported, just read [docs/nix.md](./docs/nix.md). Don't run those commands: + The installer is local, explicit, and idempotent. It validates the theme tree, installs missing runtime packages, checks required commands, stages the install atomically, writes the SDDM theme selection, and keeps the current session alive. During setup, it prints the exact plan, asks for confirmation and sudo, installs end to end, and logs the run. diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..89fbe2e --- /dev/null +++ b/default.nix @@ -0,0 +1,56 @@ +{ + lib, + stdenvNoCC, + qt6, +}: + +stdenvNoCC.mkDerivation { + pname = "thyx"; + version = "1.0.0"; + + src = ./.; + + dontBuild = true; + dontConfigure = true; + + installPhase = '' + runHook preInstall + + theme_dir="$out/share/sddm/themes/thyx" + font_dir="$out/share/fonts/truetype/thyx" + license_dir="$out/share/licenses/thyx" + + mkdir -p "$theme_dir" "$font_dir" "$license_dir" + + install -Dm0644 metadata.desktop "$theme_dir/metadata.desktop" + install -Dm0644 theme.conf "$theme_dir/theme.conf" + + cp -r backgrounds "$theme_dir/backgrounds" + cp -r icons "$theme_dir/icons" + cp -r presets "$theme_dir/presets" + cp -r src "$theme_dir/src" + + install -Dm0644 fonts/*.ttf -t "$font_dir" + install -Dm0644 LICENSE "$license_dir/LICENSE" + install -Dm0644 fonts/OFL.txt "$license_dir/OFL.txt" + + runHook postInstall + ''; + + passthru = { + sddmThemeName = "thyx"; + qtQmlPackages = with qt6; [ + qtdeclarative + qtmultimedia + qt5compat + qtsvg + ]; + }; + + meta = { + description = "Thyx SDDM theme"; + homepage = "https://github.com/rccyx/thyx"; + license = lib.licenses.mit; + platforms = lib.platforms.linux; + }; +} diff --git a/docs/nix.md b/docs/nix.md new file mode 100644 index 0000000..97b20d1 --- /dev/null +++ b/docs/nix.md @@ -0,0 +1,32 @@ +# NixOS + +Use the theme as a flake: + +```nix +{ + inputs = { + thyx.url = "github:rccyx/thyx"; + }; + + outputs = { nixpkgs, thyx, ... }: { + nixosConfigurations.host = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + + modules = [ + thyx.nixosModules.default + + { + services.displayManager.sddm.thyx.enable = true; + services.displayManager.sddm.wayland.enable = true; + } + ]; + }; + }; +} +``` + +Then rebuild. + +```bash +sudo nixos-rebuild switch --flake .#host +``` diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..0ee7307 --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1781577229, + "narHash": "sha256-lrp67w8AulE9Ks53n27I45ADSzbOCn4H+CNW1Ck8B+8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "567a49d1913ce81ac6e9582e3553dd90a955875f", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..506bb59 --- /dev/null +++ b/flake.nix @@ -0,0 +1,102 @@ +{ + description = "Thyx SDDM theme"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + }; + + outputs = { self, nixpkgs }: + let + systems = [ + "x86_64-linux" + "aarch64-linux" + ]; + + forAllSystems = nixpkgs.lib.genAttrs systems; + in + { + packages = forAllSystems (system: + let + pkgs = nixpkgs.legacyPackages.${system}; + in + { + default = pkgs.callPackage ./default.nix { }; + thyx = self.packages.${system}.default; + }); + + checks = forAllSystems (system: + let + pkgs = nixpkgs.legacyPackages.${system}; + package = self.packages.${system}.default; + + moduleEval = nixpkgs.lib.nixosSystem { + inherit system; + + modules = [ + self.nixosModules.default + + { + services.displayManager.sddm.thyx.enable = true; + services.displayManager.sddm.wayland.enable = true; + } + ]; + }; + in + { + package = package; + + nixos-module = pkgs.runCommand "thyx-nixos-module-check" { } '' + test "${moduleEval.config.services.displayManager.sddm.theme}" = "thyx" + test -e "${package}/share/sddm/themes/thyx/metadata.desktop" + test -e "${package}/share/sddm/themes/thyx/theme.conf" + test -e "${package}/share/sddm/themes/thyx/src/Main.qml" + test -e "${package}/share/sddm/themes/thyx/backgrounds/cinder.mp4" + test -e "${package}/share/sddm/themes/thyx/presets/cinder.conf" + test -e "${package}/share/fonts/truetype/thyx/PlusJakartaSans-VariableFont_wght.ttf" + test -e "${package}/share/fonts/truetype/thyx/PlusJakartaSans-Italic-VariableFont_wght.ttf" + + touch "$out" + ''; + + nixos-vm = pkgs.testers.runNixOSTest { + name = "thyx-nixos-smoke"; + + nodes.machine = { ... }: { + imports = [ + self.nixosModules.default + ]; + + services.displayManager.sddm.thyx.enable = true; + services.displayManager.sddm.wayland.enable = true; + + system.stateVersion = "25.11"; + }; + + testScript = '' + machine.wait_for_unit("multi-user.target") + + machine.succeed("test -f /run/current-system/sw/share/sddm/themes/thyx/metadata.desktop") + machine.succeed("test -f /run/current-system/sw/share/sddm/themes/thyx/theme.conf") + machine.succeed("test -f /run/current-system/sw/share/sddm/themes/thyx/src/Main.qml") + machine.succeed("test -f /run/current-system/sw/share/sddm/themes/thyx/backgrounds/cinder.mp4") + machine.succeed("test -f /run/current-system/sw/share/sddm/themes/thyx/presets/cinder.conf") + + machine.succeed("grep -q '^Current=thyx$' /etc/sddm.conf.d/00-nixos.conf") + machine.succeed("grep -q '^ThemeDir=/run/current-system/sw/share/sddm/themes$' /etc/sddm.conf.d/00-nixos.conf") + + machine.succeed("command -v sddm") + machine.succeed("command -v sddm-greeter-qt6 || command -v sddm-greeter") + + machine.wait_until_succeeds("systemctl is-active display-manager.service") + machine.wait_until_succeeds("journalctl -b --no-pager | grep -F 'Loading theme configuration from \"/run/current-system/sw/share/sddm/themes/thyx/theme.conf\"'") + machine.wait_until_succeeds("journalctl -b --no-pager | grep -F 'Loading file:///run/current-system/sw/share/sddm/themes/thyx/src/Main.qml'") + ''; + }; + }); + + nixosModules = { + default = import ./module.nix; + thyx = self.nixosModules.default; + }; + }; +} \ No newline at end of file diff --git a/module.nix b/module.nix new file mode 100644 index 0000000..110d4f5 --- /dev/null +++ b/module.nix @@ -0,0 +1,37 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.services.displayManager.sddm.thyx; + package = cfg.package; + themeName = package.passthru.sddmThemeName or "thyx"; + qtQmlPackages = package.passthru.qtQmlPackages or (with pkgs.qt6; [ + qtdeclarative + qtmultimedia + qt5compat + qtsvg + ]); +in +{ + options.services.displayManager.sddm.thyx = { + enable = lib.mkEnableOption "Thyx SDDM theme"; + + package = lib.mkOption { + type = lib.types.package; + default = pkgs.callPackage ./default.nix { }; + defaultText = lib.literalExpression "pkgs.callPackage ./default.nix { }"; + description = "Thyx SDDM theme package."; + }; + }; + + config = lib.mkIf cfg.enable { + environment.systemPackages = [ package ]; + + fonts.packages = [ package ]; + + services.displayManager.sddm = { + enable = true; + theme = themeName; + extraPackages = [ package ] ++ qtQmlPackages; + }; + }; +} diff --git a/scripts/install b/scripts/install index 23209a9..f7f0fe8 100755 --- a/scripts/install +++ b/scripts/install @@ -103,6 +103,7 @@ main() { _thyx_parse_args "$@" _thyx_setup_log _thyx_validate_repo_tree "${THYX_REPO_DIR}" + [ "$(_thyx_os_field ID || true)" != "nixos" ] || _thyx_die "NixOS install is declarative; use docs/nix.md. The uninstaller is not supported on NixOS." _thyx_prepare_runtime_manifest "${script_dir}" >/dev/null _thyx_print_install_plan