Skip to content

ci: Add GitHub Action to build installer images#196

Merged
nvmd merged 1 commit into
nvmd:developfrom
S0AndS0:add-cicd-build-installer-images
Jun 12, 2026
Merged

ci: Add GitHub Action to build installer images#196
nvmd merged 1 commit into
nvmd:developfrom
S0AndS0:add-cicd-build-installer-images

Conversation

@S0AndS0

@S0AndS0 S0AndS0 commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Much thanks be to @faddat on providing hints via PR #24

For next 90-ish days it should be possible to check, and download, artifact image built for RPi v5 via actions

Between that test, and this here message, I've re-enabled all variants within the related action's matrix.versions list/array, and added additional options to the actions/upload-artifact@v7 that should reduce upload/download file size

Tomorrow, if I've time, I'll try flashing the built and downloaded installer image to a RPi5's SD card

TLDR: using GitHub Actions to build flash-able install images seems to totally work! SSH is recommended to preform initial configuration and nixos-rebuild stuff, and remembering to not forget to enable networking management of some sort should make things relatively painless 🎉


Edit 2026-06-09

Did manage to flash SD card with image built via GitHub Actions, and it booted 🎉

Getting flooded with, "... buffer size too small... ignored", sorts of warnings. Which makes setup sub-optimal on-device. So may try SSH tomorrow, if there's time, to finish configuration/installation

Edit 2026-06-10

Took a picture and transcribed previously described flood of ignored errors;

ieee08211 phy0: brcmf_cfg08211_escan_handler: Buffer is too small: ignoring
#> ... fills the screen, then...
brcmfmac: brcmf_dump_obss: dump_obss error (-110)
brcmfmac: brcmf_cfg08211_set_power_mgmt: power save enabled
#> ... and, after a few moments, more ignored errors..
ieee08211 phy0: brcmf_cfg08211_escan_handler: Buffer is too small: ignoring

... These messages seem to stop after a rebuild and reboot, so I ain't gonna put too much time into investigating why/for(s)

Plus, SSH access was obtained and an /etc/nixox/flake.nix was written 🎉

{
  description = "Example Raspberry Pi 5 configuration flake";
    inputs = {
      nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
      nixos-raspberrypi.url = "github:nvmd/nixos-raspberrypi/main";
    };

  nixConfig = {
    extra-substituters = [
      "https://nixos-raspberrypi.cachix.org"
    ];
    extra-trusted-public-keys = [
      "nixos-raspberrypi.cachix.org-1:4iMO9LXa8BqhU+Rpg6LQKiGa2lsNh/j2oiYLNOQ5sPI="
    ];
  };

  outputs = { self, nixpkgs, nixos-raspberrypi }@inputs:
    {
      nixosConfigurations =
        let
          rpi5-hostname = "nixos-rpi5";
        in
        {
          ${rpi5-hostname} = nixos-raspberrypi.lib.nixosSystem {
            specialArgs = inputs;
            modules = [
              ({...}: {
                imports = with nixos-raspberrypi.nixosModules; [
                  ## Configures USB Gadget/Ethernet - Ethernet emulation over USB
                  ## Disabled, wrongly, due to first flash and reboot losing NetworkManager x-]
                  # usb-gadget-ethernet

                  ## Binary cache with prebuilt packages
                  trusted-nix-caches
                  ## Optional: Add all RPi and RPi-optimized packages under `pkgs.rpi`
                  nixpkgs-rpi
                ]
                ++ (with nixos-raspberrypi.lib; [
                  ## Required: Add necessary overlays with kernel, firmware, vendor packages
                  ## Causes -- error: infinite recursion encountered
                  # inject-overlays

                  ## Optional: add overlays with optimized packages to global scope, like `ffmpeg`
                  inject-overlays-global
                ])
                ++ (with nixos-raspberrypi.nixosModules.raspberry-pi-5; [
                  ## Base board support modules
                  base

                  ## "regular" display connected, note can swap for `display-rp1` if using DPI/composit/MIPI DSI
                  display-vc4

                  ## Add bluetooth stuff
                  bluetooth

                  ## Optional memory optimization: use 16k pages instead of
                  ## default 64k for jemalloc, saves memory, reduces
                  ## fragmentation. May fix any issues caused by the memory page
                  ## size discrepancy. May cause lots of rebuilds. (only for
                  ## systems running default rpi5 (bcm2712) kernel with 16k memory
                  ## page)
                  page-size-16k
                ]);
              })

              ({ ... }: {
                ## See [PR#61](https://github.com/nvmd/nixos-raspberrypi/pull/61) for more information
                boot.loader.raspberry-pi.bootloader = "kernelboot-legacy-unsupported";
              })

              ({ config, ... }: {
                system.nixos.tags =
                  let
                    cfg = config.boot.loader.raspberry-pi;
                  in
                  [
                    "raspberry-pi-${cfg.variant}"
                    cfg.bootloader
                    config.boot.kernelPackages.kernel.version
                  ];
              })

              ({ pkgs, ... }: {
                ## Resolve warnings -- https://nixos.org/manual/nixos/stable/options.html#opt-system.stateVersion
                system.stateVersion = "25.05";

                networking.hostName = "${rpi5-hostname}";

                users.users.root = {
                  openssh.authorizedKeys.keyFiles = [
                    ./services/openssh/id_rsa.pub
                  ];
                };

                users.users.pi = {
                  isNormalUser = true;
                  description = "pi";
                  initialPassword = "pi";
                  extraGroups = [
                    "networkmanager"
                    "wheel"
                  ];

                  openssh.authorizedKeys.keyFiles = [
                    ./services/openssh/id_rsa.pub
                  ];
                };

                services.openssh = {
                  enable = true;
                  settings = {
                    X11Forwarding = true;
                    PasswordAuthentication = false;
                    KbdInteractiveAuthentication = false;
                    PermitRootLogin = "prohibit-password";
                    AllowUsers = [
                      "root"
                      "pi"
                    ];
                  };
                };

                environment.systemPackages = with pkgs; [
                  vim-full
                ];
              })

              ## You like being able to connect to internet, right... right?
              ({ ... }: {
                networking = {
                  ## Enable networking
                  networkmanager.enable = true;

                  ## Disable IPv6
                  enableIPv6 = false;

                  ## Disable NetworkManager's internal DNS resolution
                  networkmanager.dns = "none";
                  ## These options are unnecessary when managing DNS ourselves
                  useDHCP = false;
                  dhcpcd.enable = false;
                  nameservers = [
                    "1.1.1.1"
                    "1.0.0.1"
                    "8.8.8.8"
                    "8.8.4.4"
                  ];

                  interfaces = {
                    end0.ipv4.addresses = [
                      {
                        address = "192.168.0.68";
                        prefixLength = 24;
                      }
                    ];
                  };
                  defaultGateway = "192.168.0.1";
                };
              })

              ({ ... }: {
                fileSystems = {
                  "/boot/firmware" = {
                    device = "/dev/disk/by-uuid/2175-794E";
                    fsType = "vfat";
                    options = [
                      "noatime"
                      "noauto"
                      "x-systemd.automount"
                      "x-systemd.idle-timeout=1min"
                    ];
                  };
                  "/" = {
                    device = "/dev/disk/by-uuid/44444444-4444-4444-8888-888888888888";
                    fsType = "ext4";
                    options = [ "noatime" ];
                  };
                };
              })
            ];
          };
        };
    };
}

Notes for future readers;

  • ./services/openssh/id_rsa.pub should point to your own SSH public key, I used scp ~/.ssh/id_rsa.pub root@192.168.0.68:/etc/nixos/services/openssh/id_rsa.pub for that
  • networking.networkmanager.enable = true; and much of that configuration block is necessary for those that like to have easy internet access to remain easily accessed after reboot, don't ask me how I know this x-]
  • nixos-raspberrypi.lib.inject-overlays causing error: infinite recursion encountered is a might bit concerning, so here be what seems are relevant from stack-trace/error;
        error: infinite recursion encountered
        at /nix/store/byhbqdj0d3j0j61acw3pnrf8pdwzgcq9-source/overlays/linux-and-firmware.nix:28:7:
            27|       # - `modules/hardware/all-firmware.nix` to populate `hardware.firmware` on aarch64
            28|       raspberrypiWirelessFirmware = wFw;
              |       ^
            29|     });
    
  • softprops/action-gh-release GitHub Action might be worth investigating for doing what this Workflow does but for "Releases", which may or may not live longer than normal "Artifacts"

@nvmd nvmd left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @S0AndS0 thanks for the PR and the testing you've done. Here are a couple of changes I think would make sense to do. What do you think? Looks good otherwise!

Comment thread .github/workflows/build-installer-images.yaml Outdated
Comment thread .github/workflows/build-installer-images.yaml Outdated
Comment thread .github/workflows/build-installer-images.yaml Outdated
Comment thread .github/workflows/build-installer-images.yaml Outdated
Much thanks be to @faddat on providing hints via PR nvmd#24

Co-authored-by: Sergey Kazenyuk <sergey@kazenyuk.com>
@S0AndS0 S0AndS0 force-pushed the add-cicd-build-installer-images branch from 0c5c2cc to 41515cf Compare June 12, 2026 18:04
@S0AndS0

S0AndS0 commented Jun 12, 2026

Copy link
Copy Markdown
Contributor Author

Hi @S0AndS0 thanks for the PR and the testing you've done. Here are a couple of changes I think would make sense to do. What do you think? Looks good otherwise!

Requested changes have been applied, thanks!

Workflow shows artifact was successfully built too 🎉

And latest force push should have squashed changes into one coherent commit, please do let me know if I missed anything

Side note; .github/workflows/cachix.yaml might be worth restricting to only project owner so those that fork ain't getting flooded with build failure emails x-]

@nvmd nvmd merged commit e322dc9 into nvmd:develop Jun 12, 2026
1 check passed
@nvmd

nvmd commented Jun 12, 2026

Copy link
Copy Markdown
Owner

Looks good, thank you! That was very fast:)

Side note; .github/workflows/cachix.yaml might be worth restricting to only project owner so those that fork ain't getting flooded with build failure emails x-]

Oh, no! Sorry, I will fix that, thanks for letting me know.

@S0AndS0

S0AndS0 commented Jun 12, 2026

Copy link
Copy Markdown
Contributor Author

Looks good, thank you! That was very fast:)

Super, and welcome as always!... ya had really good timing ;-)

Oh, no! Sorry, I will fix that, thanks for letting me know.

No worries, or hurries, it doesn't hurt too many things too bad


Edit: one thing I was thinking, while doing other things, is I believe there's an option to overwrite preexisting artifacts. Given that cron is running weekly and expiration-days is set to 40 this may result in interesting behavior... feel free to tag me in to battle that if that happens x-]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants