Update IMAGE_PATH for trixie distribution #729
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build and Release uConsole Images | |
| on: | |
| push: | |
| branches: | |
| - '**' | |
| workflow_dispatch: | |
| inputs: | |
| kernel_mode: | |
| description: 'Kernel mode (build/prebuilt)' | |
| required: true | |
| default: build | |
| type: choice | |
| options: | |
| - build | |
| - prebuilt | |
| kernel_arch: | |
| description: 'Kernel arch' | |
| required: true | |
| default: arm64 | |
| type: choice | |
| options: | |
| - arm64 | |
| - riscv | |
| kernel_branch: | |
| description: 'Kernel branch (e.g., stable/linux-6.12.y)' | |
| required: false | |
| default: 'rpi-6.12.y' | |
| type: string | |
| env: | |
| KERNEL_MODE: ${{ github.event.inputs.kernel_mode || 'build' }} | |
| KERNEL_ARCH: ${{ github.event.inputs.kernel_arch || 'arm64' }} | |
| KERNEL_BRANCH: ${{ github.event.inputs.kernel_branch || 'rpi-6.12.y' }} | |
| # apt packages that will be installed on the images | |
| UBUNTU_TASKS: 'ubuntu-server ubuntu-server-raspi task-laptop network-manager netplan.io wpasupplicant net-tools openssh-client openssh-server rfkill fdisk powertop cpufreq* flash-kernel u-boot-tools locales tzdata keyboard-configuration clockworkpi-*' | |
| DEBIAN_TASKS: 'live-task-recommended task-laptop laptop-mode-tools network-manager netplan.io wpasupplicant net-tools openssh-client openssh-server rfkill fdisk powertop cpufreq* flash-kernel u-boot-tools locales tzdata keyboard-configuration clockworkpi-*' | |
| jobs: | |
| prepare-kernel: | |
| runs-on: ubuntu-24.04-arm | |
| permissions: | |
| contents: read | |
| strategy: | |
| matrix: | |
| uconsole_core: [all] | |
| outputs: | |
| kernel_mode: ${{ env.KERNEL_MODE }} | |
| steps: | |
| - name: Set DNS to Google (optional) | |
| run: | | |
| echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf > /dev/null | |
| - name: Checkout repository | |
| if: env.KERNEL_MODE == 'build' | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Checkout kernel source | |
| if: env.KERNEL_MODE == 'build' | |
| run: | | |
| cd linux | |
| git fetch origin | |
| git checkout ${{ env.KERNEL_BRANCH }} | |
| - name: Build kernel | |
| if: env.KERNEL_MODE == 'build' | |
| run: | | |
| #sudo dpkg --add-architecture arm64 | |
| # enable debian sources | |
| cat /etc/apt/sources.list.d/ubuntu.sources | |
| sudo sed -i 's/deb/deb deb-src/g' /etc/apt/sources.list.d/ubuntu.sources | |
| sudo apt update | |
| sudo apt install -y bc bison flex libssl-dev make libc6-dev libncurses5-dev | |
| sudo apt install -y build-essential | |
| sudo apt build-dep -y -a arm64 linux linux-raspi | |
| cd linux | |
| export URL="https://github.com/raspberrypi/linux/compare/rpi-6.12.y...ak-rex:ClockworkPi-linux:rpi-6.12.y.diff" | |
| export orig="$(basename "$URL")" | |
| export safe=uconsole-kernel-patch.diff | |
| echo "Downloading $URL -> $safe" | |
| if ! wget -q -O "$safe" "$URL"; then | |
| echo "Failed to download patch, exiting" | |
| exit 1 | |
| fi | |
| if [ ! -f "$safe" ] || [ ! -s "$safe" ]; then | |
| echo "Patch file is empty or missing, exiting" | |
| exit 1 | |
| fi | |
| export PATCH_ABSOLUTE_PATH="$(pwd)/$safe" | |
| ## If matrix.uconsole_core is 'cm4' | |
| export KERNEL=kernel8 | |
| export ARCH=arm64 | |
| export CROSS_COMPILE=aarch64-linux-gnu- | |
| export LOCALVERSION=-raspi | |
| if ! patch -p1 < "$safe"; then | |
| echo "Patch application failed, exiting" | |
| exit 1 | |
| fi | |
| make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcm2711_defconfig | |
| make bindeb-pkg -j$(($(nproc) + 2)) LOCALVERSION=-raspi | |
| mkdir -p /home/runner/work/uConsole-Image-Builder/kernel-debs-${{ matrix.uconsole_core }}/ | |
| mv ../*.deb /home/runner/work/uConsole-Image-Builder/kernel-debs-${{ matrix.uconsole_core }}/ | |
| mv "$safe" /home/runner/work/uConsole-Image-Builder/uconsole-kernel-patch-${{ matrix.uconsole_core }}.diff | |
| - name: Upload kernel artifacts (1) | |
| if: env.KERNEL_MODE == 'build' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: kernel-debs-${{ matrix.uconsole_core }} | |
| path: | | |
| /home/runner/work/uConsole-Image-Builder/kernel-debs-${{ matrix.uconsole_core }}/*.deb | |
| - name: Upload kernel artifacts (2) | |
| if: env.KERNEL_MODE == 'build' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: kernel-patch-uconsole-${{ matrix.uconsole_core }} | |
| path: | | |
| /home/runner/work/uConsole-Image-Builder/uconsole-kernel-patch-${{ matrix.uconsole_core }}.diff | |
| build-image: | |
| name: uconsole-${{ needs.prepare-kernel.outputs.kernel_mode }}-image-${{ matrix.distro }}-${{ matrix.uconsole_core }}-${{ matrix.desktop }} | |
| needs: prepare-kernel | |
| runs-on: ubuntu-24.04-arm | |
| permissions: | |
| contents: read | |
| strategy: | |
| matrix: | |
| distro: [trixie, jammy] | |
| uconsole_core: [all] | |
| desktop: [gnome, kde, cinnamon, mate, xfce, lxde, lxqt, gnome-flashback] | |
| outputs: | |
| image: ${{ matrix.distro }} | |
| kernel_arch: ${{ env.KERNEL_ARCH }} | |
| steps: | |
| - name: Set desktop task packages | |
| id: desktop_task | |
| run: | | |
| # Map desktop environment to appropriate task packages | |
| case "${{ matrix.desktop }}" in | |
| gnome) | |
| if [ "${{ matrix.distro }}" == "jammy" ] || [ "${{ matrix.distro }}" == "noble" ]; then | |
| echo "DESKTOP_TASK=ubuntu-gnome-desktop" >> $GITHUB_ENV | |
| fi | |
| if [ "${{ matrix.distro }}" == "bookworm" ] || [ "${{ matrix.distro }}" == "trixie" ]; then | |
| echo "DESKTOP_TASK=task-gnome-desktop" >> $GITHUB_ENV | |
| fi | |
| ;; | |
| kde) | |
| if [ "${{ matrix.distro }}" == "jammy" ] || [ "${{ matrix.distro }}" == "noble" ]; then | |
| echo "DESKTOP_TASK=kubuntu-desktop" >> $GITHUB_ENV | |
| fi | |
| if [ "${{ matrix.distro }}" == "bookworm" ] || [ "${{ matrix.distro }}" == "trixie" ]; then | |
| echo "DESKTOP_TASK=task-kde-desktop" >> $GITHUB_ENV | |
| fi | |
| ;; | |
| cinnamon) | |
| if [ "${{ matrix.distro }}" == "jammy" ] || [ "${{ matrix.distro }}" == "noble" ]; then | |
| echo "DESKTOP_TASK=cinnamon-desktop-environment" >> $GITHUB_ENV | |
| fi | |
| if [ "${{ matrix.distro }}" == "bookworm" ] || [ "${{ matrix.distro }}" == "trixie" ]; then | |
| echo "DESKTOP_TASK=task-cinnamon-desktop" >> $GITHUB_ENV | |
| fi | |
| ;; | |
| mate) | |
| if [ "${{ matrix.distro }}" == "jammy" ] || [ "${{ matrix.distro }}" == "noble" ]; then | |
| echo "DESKTOP_TASK=ubuntu-mate-desktop" >> $GITHUB_ENV | |
| fi | |
| if [ "${{ matrix.distro }}" == "bookworm" ] || [ "${{ matrix.distro }}" == "trixie" ]; then | |
| echo "DESKTOP_TASK=task-mate-desktop" >> $GITHUB_ENV | |
| fi | |
| ;; | |
| xfce) | |
| if [ "${{ matrix.distro }}" == "jammy" ] || [ "${{ matrix.distro }}" == "noble" ]; then | |
| echo "DESKTOP_TASK=xubuntu-desktop" >> $GITHUB_ENV | |
| fi | |
| if [ "${{ matrix.distro }}" == "bookworm" ] || [ "${{ matrix.distro }}" == "trixie" ]; then | |
| echo "DESKTOP_TASK=task-xfce-desktop" >> $GITHUB_ENV | |
| fi | |
| ;; | |
| lxde) | |
| if [ "${{ matrix.distro }}" == "jammy" ] || [ "${{ matrix.distro }}" == "noble" ]; then | |
| echo "DESKTOP_TASK=lxde" >> $GITHUB_ENV | |
| fi | |
| if [ "${{ matrix.distro }}" == "bookworm" ] || [ "${{ matrix.distro }}" == "trixie" ]; then | |
| echo "DESKTOP_TASK=task-lxde-desktop" >> $GITHUB_ENV | |
| fi | |
| ;; | |
| lxqt) | |
| if [ "${{ matrix.distro }}" == "jammy" ] || [ "${{ matrix.distro }}" == "noble" ]; then | |
| echo "DESKTOP_TASK=lubuntu-desktop" >> $GITHUB_ENV | |
| fi | |
| if [ "${{ matrix.distro }}" == "bookworm" ] || [ "${{ matrix.distro }}" == "trixie" ]; then | |
| echo "DESKTOP_TASK=task-lxqt-desktop" >> $GITHUB_ENV | |
| fi | |
| ;; | |
| gnome-flashback) | |
| if [ "${{ matrix.distro }}" == "jammy" ] || [ "${{ matrix.distro }}" == "noble" ]; then | |
| echo "DESKTOP_TASK=ubuntu-gnome-desktop gnome-session-flashback" >> $GITHUB_ENV | |
| fi | |
| if [ "${{ matrix.distro }}" == "bookworm" ] || [ "${{ matrix.distro }}" == "trixie" ]; then | |
| echo "DESKTOP_TASK=task-gnome-flashback-desktop" >> $GITHUB_ENV | |
| fi | |
| ;; | |
| *) | |
| echo "ERROR: Unknown desktop environment: ${{ matrix.desktop }}" | |
| echo "Supported desktop environments: gnome, kde, cinnamon, mate, xfce, lxde, lxqt, gnome-flashback" | |
| exit 1 | |
| ;; | |
| esac | |
| echo "Desktop task set to: $DESKTOP_TASK" | |
| - name: Download kernel artifacts | |
| if: needs.prepare-kernel.outputs.kernel_mode == 'build' | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: kernel-debs-${{ matrix.uconsole_core }} | |
| path: /home/runner/work/uConsole-Image-Builder/uConsole-Image-Builder/kernel-debs/ | |
| - name: Customize image | |
| run: | | |
| # If matrix.distro is bookworm, use deb12-arm64-min.img | |
| # If matrix.distro is trixie, use deb13-arm64-min.img | |
| # If matrix.distro is jammy, use jammy for pi 4 (arm64) wget https://cdimage.ubuntu.com/releases/jammy/release/ubuntu-22.04.5-preinstalled-desktop-arm64+raspi.img.xz | |
| if [ "${{ matrix.distro }}" == "bookworm" ] || [ "${{ matrix.distro }}" == "trixie" ]; then | |
| # If matrix.distro is bookworm, | |
| if [ "${{ matrix.distro }}" == "bookworm" ]; then | |
| IMAGE_PATH=https://downloads.raspberrypi.com/raspios_oldstable_lite_arm64/images/raspios_oldstable_lite_arm64-2025-11-24/2025-11-24-raspios-bookworm-arm64-lite.img.xz | |
| else | |
| IMAGE_PATH=https://downloads.raspberrypi.com/raspios_lite_arm64/images/raspios_lite_arm64-2025-12-04/2025-12-04-raspios-trixie-arm64-lite.img.xz | |
| fi | |
| fi | |
| if [ "${{ matrix.distro }}" == "noble" ]; then | |
| IMAGE_PATH=https://cdimage.ubuntu.com/releases/24.04.3/release/ubuntu-24.04.3-preinstalled-server-arm64+raspi.img.xz | |
| fi | |
| if [ "${{ matrix.distro }}" == "jammy" ]; then | |
| IMAGE_PATH=https://cdimage.ubuntu.com/releases/22.04.5/release/ubuntu-22.04.5-preinstalled-server-arm64+raspi.img.xz | |
| fi | |
| if [ "${{ matrix.distro }}" == "popos" ]; then | |
| IMAGE_PATH=https://iso.pop-os.org/22.04/arm64/raspi/4/pop-os_22.04_arm64_raspi_4.img.xz | |
| fi | |
| wget $IMAGE_PATH -O ${{ matrix.distro }}-raspi.img.xz > /dev/null 2>&1 | |
| unxz ${{ matrix.distro }}-raspi.img.xz | |
| rm -f ${{ matrix.distro }}-raspi.img.xz | |
| IMAGE_PATH=./${{ matrix.distro }}-raspi.img | |
| # Resize image to 6GB for GNOME desktop | |
| echo "Resizing Ubuntu image to 6GB..." | |
| # Get current image size | |
| CURRENT_SIZE=$(stat -c%s "$IMAGE_PATH" 2>/dev/null) || { | |
| echo "ERROR: Failed to get image size" | |
| exit 1 | |
| } | |
| TARGET_SIZE=$((8 * 1024 * 1024 * 1024)) # 8GB in bytes | |
| echo "Current image size: $CURRENT_SIZE bytes" | |
| echo "Target image size: $TARGET_SIZE bytes" | |
| # Only resize if current size is less than target | |
| if [ $CURRENT_SIZE -lt $TARGET_SIZE ]; then | |
| # Extend the image file | |
| if ! truncate -s $TARGET_SIZE "$IMAGE_PATH"; then | |
| echo "ERROR: Failed to extend image file to 8GB" | |
| exit 1 | |
| fi | |
| # Setup loop device to resize partition | |
| RESIZE_LOOP=$(sudo losetup -f) | |
| if [ -z "$RESIZE_LOOP" ]; then | |
| echo "ERROR: No free loop device available" | |
| exit 1 | |
| fi | |
| if ! sudo losetup -P "$RESIZE_LOOP" "$IMAGE_PATH"; then | |
| echo "ERROR: Failed to setup loop device" | |
| exit 1 | |
| fi | |
| # Root partition for Ubuntu Raspberry Pi images | |
| ROOT_PARTITION="${RESIZE_LOOP}p2" | |
| # Verify partition device exists after losetup | |
| if [ ! -e "$ROOT_PARTITION" ]; then | |
| echo "ERROR: Partition device $ROOT_PARTITION not found after losetup" | |
| echo "Available devices:" | |
| ls -l ${RESIZE_LOOP}* || true | |
| sudo losetup -d "$RESIZE_LOOP" | |
| exit 1 | |
| fi | |
| echo "Found partition device: $ROOT_PARTITION" | |
| # Resize the root partition (partition 2) | |
| if ! echo ", +" | sudo sfdisk --no-reread -N 2 "$RESIZE_LOOP"; then | |
| echo "ERROR: Failed to resize partition" | |
| sudo losetup -d "$RESIZE_LOOP" | |
| exit 1 | |
| fi | |
| if ! sudo partprobe "$RESIZE_LOOP"; then | |
| echo "ERROR: Failed to update partition table" | |
| sudo losetup -d "$RESIZE_LOOP" | |
| exit 1 | |
| fi | |
| # Wait for partition device to be ready after partprobe | |
| sleep 2 | |
| # Verify partition device still exists after resize | |
| if [ ! -e "$ROOT_PARTITION" ]; then | |
| echo "ERROR: Partition device $ROOT_PARTITION disappeared after resize" | |
| echo "Available devices:" | |
| ls -l ${RESIZE_LOOP}* || true | |
| sudo losetup -d "$RESIZE_LOOP" | |
| exit 1 | |
| fi | |
| # Resize the filesystem - e2fsck exit codes: | |
| # 0 = no errors, 1 = errors corrected (acceptable), >1 = serious errors | |
| E2FSCK_EXIT=0 | |
| sudo e2fsck -f -y "$ROOT_PARTITION" || E2FSCK_EXIT=$? | |
| if [ "$E2FSCK_EXIT" -gt 1 ]; then | |
| echo "ERROR: Filesystem check failed with exit code $E2FSCK_EXIT" | |
| sudo losetup -d "$RESIZE_LOOP" | |
| exit 1 | |
| fi | |
| if ! sudo resize2fs "$ROOT_PARTITION"; then | |
| echo "ERROR: Failed to resize filesystem" | |
| sudo losetup -d "$RESIZE_LOOP" | |
| exit 1 | |
| fi | |
| # Clean up | |
| sudo losetup -d "$RESIZE_LOOP" | |
| echo "Image resized successfully to 8GB" | |
| fi | |
| #Clean up | |
| rm -f ${{ matrix.distro }}-raspi.img.xz | |
| echo "Image resized successfully to 8GB" | |
| # Mount image and chroot | |
| LOOP_DEVICE=$(sudo losetup -f --show -P $IMAGE_PATH) | |
| MOUNT_POINT=./rootfs-${{ matrix.distro }}-${{ matrix.uconsole_core }}-${{ matrix.desktop }} | |
| sudo mkdir -p $MOUNT_POINT | |
| sudo mount ${LOOP_DEVICE}p2 $MOUNT_POINT | |
| sudo mkdir -p $MOUNT_POINT/boot/firmware | |
| sudo mount ${LOOP_DEVICE}p1 $MOUNT_POINT/boot/firmware | |
| sudo mount --bind /dev $MOUNT_POINT/dev | |
| sudo mount --bind /dev/pts $MOUNT_POINT/dev/pts | |
| sudo mount --bind /proc $MOUNT_POINT/proc | |
| sudo mount --bind /sys $MOUNT_POINT/sys | |
| sleep 5 # Wait for mounts to stabilize | |
| # Configure DNS resolvers | |
| sudo chroot $MOUNT_POINT /bin/bash -c "mv /etc/resolv.conf /etc/resolv.conf.bak || true" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "echo 'nameserver 8.8.8.8' | tee /etc/resolv.conf" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "echo 'nameserver 8.8.4.4' | tee -a /etc/resolv.conf" | |
| # Remove current linux | |
| sudo chroot $MOUNT_POINT /bin/bash -c "apt remove -y linux-image-* linux-headers-* linux-raspi-headers-* || true" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "apt-get update && apt-get install -y --no-install-recommends wget gnupg initramfs-tools" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "apt update" | |
| if [ "${{ matrix.distro }}" == "jammy" ]; then | |
| sudo chroot $MOUNT_POINT /bin/bash -c "apt install -y --no-install-recommends linux-firmware linux-firmware-raspi" | |
| fi | |
| if [ "${{ matrix.distro }}" == "noble" ]; then | |
| sudo chroot $MOUNT_POINT /bin/bash -c "apt install -y --no-install-recommends linux-firmware linux-firmware-raspi" | |
| fi | |
| if [ "${{ matrix.distro }}" == "bookworm" ]; then | |
| sudo chroot $MOUNT_POINT /bin/bash -c "apt install -y --no-install-recommends firmware-linux-free firmware-misc-nonfree" | |
| #AIO BOARD set up | |
| sudo chroot $MOUNT_POINT /bin/bash -c "wget -q -O- https://raw.githubusercontent.com/ak-rex/ClockworkPi-apt/main/debian/KEY.gpg | gpg --dearmor | tee /etc/apt/trusted.gpg.d/ak-rex.gpg" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "echo 'deb [arch=arm64] https://raw.githubusercontent.com/ak-rex/ClockworkPi-apt/main/debian stable main' | tee /etc/apt/sources.list.d/ak-rex.list" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "echo 'deb http://http.us.debian.org/debian/ testing non-free contrib main' | tee /etc/apt/sources.list.d/testing.list" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "apt update" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get install -y --install-recommends --assume-yes -y hackergadgets-uconsole-aio-board" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "rm /etc/apt/sources.list.d/testing.list" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "apt update" | |
| fi | |
| if [ "${{ matrix.distro }}" == "trixie" ]; then | |
| sudo chroot $MOUNT_POINT /bin/bash -c "apt install -y --no-install-recommends firmware-linux-free firmware-misc-nonfree" | |
| #AIO BOARD set up | |
| sudo chroot $MOUNT_POINT /bin/bash -c "wget -q -O- https://raw.githubusercontent.com/ak-rex/ClockworkPi-apt/main/debian/KEY.gpg | gpg --dearmor | tee /etc/apt/trusted.gpg.d/ak-rex.gpg" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "echo 'deb [arch=arm64] https://raw.githubusercontent.com/ak-rex/ClockworkPi-apt/main/debian stable main' | tee /etc/apt/sources.list.d/ak-rex.list" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "echo 'deb http://http.us.debian.org/debian/ testing non-free contrib main' | tee /etc/apt/sources.list.d/testing.list" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "apt update" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get install -y --install-recommends --assume-yes -y hackergadgets-uconsole-aio-board" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "rm /etc/apt/sources.list.d/testing.list" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "apt update" | |
| fi | |
| #sudo chroot $MOUNT_POINT /bin/bash -c "sed -i 's/exec flash-kernel "$abi"/exec flash-kernel --force "$abi"/g' /etc/kernel/postinst.d/flash-kernel || true" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "dpkg --configure -a" | |
| # Ensure flash-kernel is installed | |
| sudo chroot $MOUNT_POINT /bin/bash -c "apt install -y flash-kernel" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "echo \"\nMachine: Raspberry Pi Compute Module 4 Rev 1.1\nKernel-Flavors: arm64 armmp armmp-lpae raspi\nDTB-Id: broadcom/bcm2711-rpi-4-b.dtb\nU-Boot-Script-Name: bootscr.uboot-generic\nRequired-Packages: u-boot-tools\nBoot-Script-Path: /boot/boot.scr\" > /usr/share/flash-kernel/db/all.db" | |
| # Add ClockworkPi repository | |
| sudo chroot $MOUNT_POINT /bin/bash -c "wget -q -O- https://raw.githubusercontent.com/clockworkpi/apt/main/debian/KEY.gpg | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/clockworkpi.gpg" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "echo 'deb [arch=arm64] https://raw.githubusercontent.com/clockworkpi/apt/main/bookworm stable main' | sudo tee -a /etc/apt/sources.list.d/clockworkpi.list" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "apt update" | |
| if [ "${{ matrix.distro }}" == "jammy" ]; then | |
| sudo chroot $MOUNT_POINT /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends --assume-yes ${{ env.UBUNTU_TASKS }}" | |
| fi | |
| if [ "${{ matrix.distro }}" == "noble" ]; then | |
| sudo chroot $MOUNT_POINT /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends --assume-yes ${{ env.UBUNTU_TASKS }}" | |
| fi | |
| if [ "${{ matrix.distro }}" == "bookworm" ]; then | |
| sudo chroot $MOUNT_POINT /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends --assume-yes ${{ env.DEBIAN_TASKS }}" | |
| fi | |
| if [ "${{ matrix.distro }}" == "trixie" ]; then | |
| sudo chroot $MOUNT_POINT /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends --assume-yes ${{ env.DEBIAN_TASKS }}" | |
| fi | |
| sudo chroot $MOUNT_POINT /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends ${{ env.DESKTOP_TASK }}" | |
| # Copy DTB files | |
| sudo chroot $MOUNT_POINT /bin/bash -c "cp /boot/firmware/*.dtb /etc/flash-kernel/dtbs/" | |
| if [ "${{ env.KERNEL_MODE }}" == "build" ]; then | |
| sudo cp /home/runner/work/uConsole-Image-Builder/uConsole-Image-Builder/kernel-debs/*.deb $MOUNT_POINT/tmp/ | |
| sudo chroot $MOUNT_POINT /bin/bash -c "dpkg -i /tmp/*.deb || apt -f install -y --no-install-recommends" | |
| else | |
| # Install kernel | |
| sudo chroot $MOUNT_POINT /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt install -y clockworkpi-*" | |
| fi | |
| sudo chroot $MOUNT_POINT /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends wireguard-tools" | |
| # Set LOCALE to en_US.UTF-8 | |
| sudo chroot $MOUNT_POINT /bin/bash -c "echo 'en_US.UTF-8 UTF-8' >> /etc/locale.gen && locale-gen en_US.UTF-8 && update-locale LANG=en_US.UTF-8" | |
| # Configure uConsole-specific config.txt | |
| sudo tee $MOUNT_POINT/boot/firmware/config.txt << 'EOF' | |
| [pi3] | |
| dtoverlay=clockworkpi-uconsole-cm3 | |
| dtoverlay=vc4-kms-v3d | |
| dtparam=spi=on | |
| dtoverlay=spi-gpio35-39 | |
| gpio=11=op,dh | |
| enable_uart=1 | |
| [pi4] | |
| #dtoverlay=clockworkpi-devterm | |
| dtoverlay=clockworkpi-uconsole | |
| dtoverlay=vc4-kms-v3d-pi4,cma-384 | |
| dtparam=spi=on | |
| enable_uart=1 | |
| dtparam=pciex1 | |
| [pi5] | |
| #dtoverlay=clockworkpi-devterm-cm5 | |
| dtoverlay=clockworkpi-uconsole-cm5 | |
| dtoverlay=vc4-kms-v3d-pi5,cma-384 | |
| dtparam=uart0 | |
| dtparam=pciex1 | |
| dtparam=pciex1_gen=3 | |
| [all] | |
| ignore_lcd=1 | |
| max_framebuffers=2 | |
| disable_overscan=1 | |
| dtparam=audio=on | |
| dtoverlay=audremap,pins_12_13 | |
| dtoverlay=dwc2,dr_mode=host | |
| dtparam=ant2 | |
| ##only edit the section of the pi you have, other section will be ignored. | |
| ##if you have a devterm uncomment devterm and comment out entries with uconsole. | |
| EOF | |
| # Generate vmlinuz (raspi kernel) initramfs | |
| sudo chroot $MOUNT_POINT /bin/bash -c "update-initramfs -c -k all" | |
| # Create user 'clockworkpi', identified by 'clockworkpi', create skeleton home directory and add to sudoers | |
| sudo chroot $MOUNT_POINT /bin/bash -c "adduser --gecos 'Clockwork Pi,,,,' --disabled-password clockworkpi || true" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "echo 'clockworkpi:clockworkpi' | chpasswd" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "usermod -aG sudo clockworkpi" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "echo 'clockworkpi ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "mkdir -p /home/clockworkpi/Desktop" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "chown -R clockworkpi:clockworkpi /home/clockworkpi/Desktop" | |
| # Set hostname | |
| sudo chroot $MOUNT_POINT /bin/bash -c "echo 'uconsole' > /etc/hostname" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "sed -i 's/ubuntu|debian|raspbian|raspberrypi/uconsole/g' /etc/hosts" | |
| # Enable SSH by default | |
| sudo chroot $MOUNT_POINT /bin/bash -c "systemctl enable ssh" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "touch /boot/firmware/ssh" | |
| # Set timezone to UTC | |
| sudo chroot $MOUNT_POINT /bin/bash -c "ln -sf /usr/share/zoneinfo/UTC /etc/localtime" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "dpkg-reconfigure -f noninteractive tzdata" | |
| # Set keyboard layout to us | |
| sudo chroot $MOUNT_POINT /bin/bash -c "echo 'XKBLAYOUT=\"us\"' >> /etc/default/keyboard" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "echo 'XKBMODEL=\"pc105\"' >> /etc/default/keyboard" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "dpkg-reconfigure -f noninteractive keyboard-configuration" | |
| # Cleanup to reduce image size | |
| sudo chroot $MOUNT_POINT /bin/bash -c "apt-get autoremove -y" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "apt-get clean" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "apt clean" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "rm -rf /var/lib/apt/lists/*" | |
| sudo tee $MOUNT_POINT/usr/local/bin/pi-apps << 'EOF' | |
| #!/bin/bash | |
| #Make sure it runs as root | |
| if [ "$EUID" -ne 0 ]; then | |
| echo "Please run as root" | |
| exit | |
| fi | |
| if wget -qO- https://raw.githubusercontent.com/Botspot/pi-apps/master/install | bash; then | |
| sudo rm $0 #Delete script after running | |
| echo "Pi-Apps installed successfully! Try installing an app from the Pi-Apps menu. Steam works!" | |
| fi | |
| EOF | |
| sudo tee $MOUNT_POINT/usr/local/bin/code << 'EOF' | |
| #!/bin/bash | |
| #Make sure it runs as root | |
| if [ "$EUID" -ne 0 ]; then | |
| echo "Please run as root" | |
| exit | |
| fi | |
| if wget https://code.visualstudio.com/docs/?dv=linuxarm64_deb -O /tmp/vscode-arm64.deb && sudo dpkg -i /tmp/vscode-arm64.deb && sudo apt-get install -f -y; then | |
| sudo rm $0 #Delete script after running | |
| echo "VSCode installed successfully!" | |
| fi | |
| EOF | |
| sudo tee $MOUNT_POINT/usr/local/bin/chromium << 'EOF' | |
| #!/bin/bash | |
| #Make sure it runs as root | |
| if [ "$EUID" -ne 0 ]; then | |
| echo "Please run as root" | |
| exit | |
| fi | |
| if sudo apt update && sudo apt install -y chromium; then | |
| sudo rm $0 #Delete script after running | |
| echo "Chromium installed successfully!" | |
| fi | |
| EOF | |
| sudo tee $MOUNT_POINT/usr/local/bin/firefox << 'EOF' | |
| #!/bin/bash | |
| #Make sure it runs as root | |
| if [ "$EUID" -ne 0 ]; then | |
| echo "Please run as root" | |
| exit | |
| fi | |
| if sudo apt update && sudo apt install -y chromium; then | |
| sudo rm $0 #Delete script after running | |
| echo "Chromium installed successfully!" | |
| fi | |
| EOF | |
| sudo tee $MOUNT_POINT/usr/local/bin/vulkan << 'EOF' | |
| #!/bin/bash | |
| #Make sure it runs as root | |
| if [ "$EUID" -ne 0 ]; then | |
| echo "Please run as root" | |
| exit | |
| fi | |
| if sudo apt update && sudo apt install -y mesa-vulkan-drivers mesa-utils v4l2loopback-utils libv4l-0 mesa-vulkan-drivers vulkan-utils; then | |
| sudo rm $0 #Delete script after running | |
| echo "Vulkan installed successfully!" | |
| fi | |
| EOF | |
| sudo chmod +x $MOUNT_POINT/usr/local/bin/pi-apps | |
| sudo chmod +x $MOUNT_POINT/usr/local/bin/code | |
| sudo chmod +x $MOUNT_POINT/usr/local/bin/chromium | |
| sudo chmod +x $MOUNT_POINT/usr/local/bin/firefox | |
| sudo chroot $MOUNT_POINT /bin/bash -c "sed -i 's| init=/usr/lib/raspi-config/init_resize\.sh||' /boot/firmware/cmdline.txt" | |
| # Remove unnecessary files to save space | |
| sudo chroot $MOUNT_POINT /bin/bash -c "rm -rf /var/lib/apt/lists/*" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "rm -rf /tmp/*" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "rm -rf /var/tmp/*" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "rm -rf /var/cache/apt/archives/*.deb" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "rm -rf /var/log/*.log /var/log/*.old /var/log/*.gz" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "apt purge -y *-doc" | |
| #sudo chroot $MOUNT_POINT /bin/bash -c "find /usr/share/doc -depth -type f ! -name copyright -delete" | |
| #sudo chroot $MOUNT_POINT /bin/bash -c "find /usr/share/doc -depth -type d -empty -delete" | |
| #sudo chroot $MOUNT_POINT /bin/bash -c "rm -rf /usr/share/man/* /usr/share/groff/* /usr/share/info/*" | |
| #sudo chroot $MOUNT_POINT /bin/bash -c "rm -rf /usr/share/lintian/* /usr/share/linda/*" | |
| sudo chroot $MOUNT_POINT /bin/bash -c "find /usr/share/locale -mindepth 1 -maxdepth 1 ! -name 'en*' -exec rm -rf {} +" | |
| # Restore original resolv.conf | |
| sudo chroot $MOUNT_POINT /bin/bash -c "mv /etc/resolv.conf.bak /etc/resolv.conf || true" | |
| # Clean up | |
| sleep 5 # Wait before unmounting | |
| sudo umount -lf $MOUNT_POINT/dev/pts | |
| sleep 2 | |
| sudo umount -lf $MOUNT_POINT/dev | |
| sleep 2 | |
| sudo umount -lf $MOUNT_POINT/proc | |
| sleep 2 | |
| sudo umount -lf $MOUNT_POINT/sys | |
| sleep 2 | |
| sudo umount -lf $MOUNT_POINT/boot/firmware | |
| sleep 2 | |
| sudo umount -lf $MOUNT_POINT | |
| sleep 2 | |
| sudo losetup -d $LOOP_DEVICE | |
| # Compress image with maximum compression settings | |
| #xz --threads=1 --memory=1000MiB --check=crc32 -9e --compress --keep "$IMAGE_PATH" | |
| xz -T1 -M1000MiB --lzma2=preset=9e,dict=1GiB,nice=273 -Ccrc32 -k "$IMAGE_PATH" | |
| mv "${IMAGE_PATH}.xz" /home/runner/work/uConsole-Image-Builder/uconsole-${{ matrix.distro }}-${{ matrix.uconsole_core }}-${{ matrix.desktop }}.img.xz | |
| - name: Upload image artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: uconsole-${{ matrix.distro }}-${{ matrix.uconsole_core }}-${{ matrix.desktop }}.img.xz | |
| path: /home/runner/work/uConsole-Image-Builder/uconsole-${{ matrix.distro }}-${{ matrix.uconsole_core }}-${{ matrix.desktop }}.img.xz | |
| release: | |
| needs: [prepare-kernel, build-image] | |
| runs-on: ubuntu-24.04-arm | |
| if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/') | |
| permissions: | |
| contents: write | |
| strategy: | |
| matrix: | |
| distro: [bookworm, trixie, jammy] | |
| uconsole_core: [all] | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Download kernel artifacts (${{ matrix.uconsole_core }}) | |
| if: needs.prepare-kernel.outputs.kernel_mode == 'build' | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: kernel-debs-${{ matrix.uconsole_core }} | |
| path: /home/runner/work/uConsole-Image-Builder/release/ | |
| - name: Download patch artifacts (${{ matrix.uconsole_core }}) | |
| if: needs.prepare-kernel.outputs.kernel_mode == 'build' | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: kernel-patch-uconsole-${{ matrix.uconsole_core }} | |
| path: /home/runner/work/uConsole-Image-Builder/release/ | |
| # Download only images for this specific distro-core combination | |
| # Pattern matches artifacts from build-image job (line 608): | |
| # uconsole-{distro}-{core}-{desktop}.img.xz | |
| - name: Download image artifacts for ${{ matrix.distro }}-${{ matrix.uconsole_core }} | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: uconsole-${{ matrix.distro }}-${{ matrix.uconsole_core }}-*.img.xz | |
| path: /home/runner/work/uConsole-Image-Builder/release/ | |
| merge-multiple: true | |
| - name: Create release tag | |
| id: tag | |
| run: | | |
| TAG_NAME="release-$(date +'%Y%m%d-%H%M%S')" | |
| FULL_TAG_NAME="uconsole-${{ env.kernel_arch }}-${TAG_NAME}-${{ matrix.distro }}-${{ matrix.uconsole_core }}" | |
| echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT | |
| echo "full_tag_name=$FULL_TAG_NAME" >> $GITHUB_OUTPUT | |
| git tag "$FULL_TAG_NAME" | |
| git push origin "$FULL_TAG_NAME" | |
| ls -laR /home/runner/work/uConsole-Image-Builder/release/ | |
| - name: Create GitHub Release for ${{ matrix.distro }}-${{ matrix.uconsole_core }} | |
| if: needs.prepare-kernel.outputs.kernel_mode == 'build' | |
| uses: softprops/action-gh-release@v2 | |
| timeout-minutes: 30 | |
| with: | |
| tag_name: ${{ steps.tag.outputs.full_tag_name }} | |
| name: uConsole Images - ${{ matrix.distro }} - ${{ matrix.uconsole_core }} - ${{ env.kernel_arch }} | |
| files: | | |
| /home/runner/work/uConsole-Image-Builder/release/*.img.xz | |
| /home/runner/work/uConsole-Image-Builder/release/*.deb | |
| /home/runner/work/uConsole-Image-Builder/release/*.diff | |
| generate_release_notes: true | |
| fail_on_unmatched_files: false | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Create GitHub Release for ${{ matrix.distro }}-${{ matrix.uconsole_core }} | |
| if: needs.prepare-kernel.outputs.kernel_mode == 'prebuilt' | |
| uses: softprops/action-gh-release@v2 | |
| timeout-minutes: 30 | |
| with: | |
| tag_name: ${{ steps.tag.outputs.full_tag_name }} | |
| name: uConsole Images - ${{ matrix.distro }} - ${{ matrix.uconsole_core }} - ${{ env.kernel_arch }} | |
| files: | | |
| /home/runner/work/uConsole-Image-Builder/release/*.img.xz | |
| generate_release_notes: true | |
| fail_on_unmatched_files: false | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |