Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
79f5f56
Update main.yml
ramalamadingdong Jul 30, 2025
a3ae8c0
Update README.md
ramalamadingdong Jul 30, 2025
15a2ee8
Enhance GitHub Actions workflow for rubikpi3 image processing
ramalamadingdong Jul 30, 2025
7d5d8ad
Update base_image URL for rubikpi3 in GitHub Actions workflow
ramalamadingdong Jul 30, 2025
811cd0e
Refactor GitHub Actions workflow by removing obsolete installation st…
ramalamadingdong Jul 30, 2025
c72b238
asdfasdf
ramalamadingdong Jul 30, 2025
6e98903
stfs
ramalamadingdong Jul 30, 2025
dd285d3
sdfsdf
ramalamadingdong Jul 30, 2025
10bbc30
Update GitHub Actions workflow: increase image_additional_mb for impr…
ramalamadingdong Jul 30, 2025
2d5f0bc
Update main.yml
ramalamadingdong Aug 15, 2025
02cac54
Update install_opi5.sh
ramalamadingdong Aug 15, 2025
18b9d9c
Revert "Update install_opi5.sh"
ramalamadingdong Aug 15, 2025
c1461b1
Refactor GitHub Actions workflow for rubikpi3 by removing the base im…
ramalamadingdong Aug 15, 2025
4c61160
Enhance GitHub Actions workflow for rubikpi3 by implementing a custom…
ramalamadingdong Aug 15, 2025
2eed51f
Refactor GitHub Actions workflow for rubikpi3 by simplifying the moun…
ramalamadingdong Aug 15, 2025
5747259
Enhance GitHub Actions workflow for rubikpi3 by adding rsync for copy…
ramalamadingdong Aug 16, 2025
6d7941d
Refactor rubikpi3 build to use YAML manifest and remove opi5 target
ramalamadingdong Oct 2, 2025
2c14c2a
asdfasdf
ramalamadingdong Oct 2, 2025
36f043e
**Simplify manifest download, verify SHA and robust extraction in CI**
ramalamadingdong Oct 2, 2025
b7f4d99
Fix yq command quoting in CI workflow to correctly concatenate URL an…
ramalamadingdong Oct 2, 2025
daf0a6d
khjkj
ramalamadingdong Oct 2, 2025
ace1599
Fix yq command quoting in CI workflow for proper syntax
ramalamadingdong Oct 2, 2025
057b88e
Make manifest parsing robust to leading spaces in YAML
ramalamadingdong Oct 2, 2025
bd97628
Improve CI workflow manifest parsing with robust awk extraction
ramalamadingdong Oct 2, 2025
a99faec
Replace image compression with full QLI archive in CI workflow
ramalamadingdong Oct 2, 2025
ae4fb46
Refactor rubikpi3 build to use dynamic partition mounting and chroot
ramalamadingdong Oct 6, 2025
ce2667f
Improve partition detection for GPT disk images in workflow
ramalamadingdong Oct 6, 2025
bb8581a
Fix GPT partition detection and add gdisk for image expansion
ramalamadingdong Oct 6, 2025
b8e1996
**Improve fdisk partition parsing in CI workflow for GPT images**
ramalamadingdong Oct 6, 2025
6350c73
Use sfdisk (fallback to parted) instead of fdisk for GPT detection
ramalamadingdong Oct 6, 2025
c4d09e8
Improve rootfs image detection and add raw filesystem support
ramalamadingdong Oct 6, 2025
2bcf58d
Improve raw filesystem detection and expansion in CI workflow
ramalamadingdong Oct 6, 2025
55deab8
Improve raw filesystem detection and expansion in CI workflow
ramalamadingdong Oct 6, 2025
6ab2bb3
sdfsdf
ramalamadingdong Oct 6, 2025
8611b0a
fixed main.yyml
ramalamadingdong Oct 6, 2025
192c687
Optimize disk space usage in GitHub Actions workflow
ramalamadingdong Oct 6, 2025
c37a0be
Remove disk cleanup and redundant comments from CI workflow
ramalamadingdong Oct 6, 2025
ebd7429
Refactor RubikPi3 installer to add package management and logging
ramalamadingdong Oct 6, 2025
472734f
sdfsdf
ramalamadingdong Oct 6, 2025
0b90fe6
Add verbose debugging and fix chroot execution for rubikpi3 build
ramalamadingdong Oct 6, 2025
28a5568
adsfsdf
ramalamadingdong Oct 6, 2025
8abb492
;lkp;ok
ramalamadingdong Oct 6, 2025
cff6fe6
klhjlkj
ramalamadingdong Oct 6, 2025
91b6527
sdfsdfsdfsdf
ramalamadingdong Oct 7, 2025
fb169e7
Add auto-confirm flag and remove unnecessary directory change
ramalamadingdong Oct 7, 2025
06d518a
Add --fix-broken flag to apt-get install command
ramalamadingdong Oct 7, 2025
ccfb1c5
asdfasdf
ramalamadingdong Oct 7, 2025
c84ffa5
fixed error hopefualy
ramalamadingdong Oct 7, 2025
932dc28
Fix OpenCL symf
ramalamadingdong Oct 7, 2025
2198232
Fix OpenCL symlink and clean up RubikPi3 installation script
ramalamadingdong Oct 7, 2025
2008e35
sdafdfasdf
ramalamadingdong Oct 7, 2025
0761807
asdfasdf
ramalamadingdong Oct 7, 2025
774ea22
asdfasdf
ramalamadingdong Oct 7, 2025
4937ad2
asdfgasdf
ramalamadingdong Oct 7, 2025
52ddc3e
trying in outside script commented out in the internal script
ramalamadingdong Oct 7, 2025
a4b02e6
sdfsdf
ramalamadingdong Oct 7, 2025
884bac6
sdfsdf
ramalamadingdong Oct 7, 2025
0d0dd10
sdfsdfsdf
ramalamadingdong Oct 7, 2025
b32cc4b
hop
ramalamadingdong Oct 7, 2025
002f602
Allow downgrades for libsqlite3-0 installation
samfreund Oct 7, 2025
743751d
Install pigpiod.service in the setup script
samfreund Oct 8, 2025
a404c0c
Update install_rubikpi3.sh to remove pigpiod
samfreund Oct 8, 2025
58a2927
rename rubik workflow
samfreund Oct 8, 2025
4883ab4
Merge remote-tracking branch 'origin/main' into rubik-pi-image
samfreund Oct 8, 2025
da35ea3
cleanup rubik workflow
samfreund Oct 8, 2025
7e8af23
remove readme
samfreund Oct 8, 2025
c179b31
REVERT LATER: for testing
samfreund Oct 8, 2025
671b024
rerun CI
samfreund Oct 8, 2025
90a61f8
fix env var loc
samfreund Oct 8, 2025
b8ee0f5
move bulk of rubik workflow to file
samfreund Oct 8, 2025
839b6ef
move rubik to main workflow
samfreund Oct 8, 2025
d612115
remove dtb.bin
samfreund Oct 8, 2025
d5cebfb
fix archive naming
samfreund Oct 8, 2025
3808d93
compress with xz
samfreund Oct 8, 2025
436465b
make release depend on rubik
samfreund Oct 8, 2025
9cbeb5c
move chroot commands into install script
samfreund Oct 8, 2025
e22c912
rename QLI dir to photonvision_rubikpi3
samfreund Oct 8, 2025
eb34555
add support for running on built image
samfreund Oct 8, 2025
b10ac03
add bind mount
samfreund Oct 8, 2025
53914fb
remove shift 2
samfreund Oct 8, 2025
5029639
cleaner cleanup
samfreund Oct 9, 2025
731e871
Update install_rubikpi3.sh
samfreund Oct 9, 2025
766166c
Quiet Log Spam
samfreund Oct 9, 2025
b502130
bump gh release action
samfreund Oct 10, 2025
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
41 changes: 31 additions & 10 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,34 @@ concurrency:
cancel-in-progress: true

jobs:
rubik:
env:
script: "./tmp/build/install_rubikpi3.sh"
base_image: "https://people.canonical.com/~platform/images/qualcomm-iot/rubikpi3/ubuntu-server-24.04/x00/ubuntu-24.04-preinstalled-server-arm64+rubikpi3-20250912-127.yaml"

runs-on: ubuntu-24.04

name: "Build for RubikPi3"

steps:
- uses: actions/checkout@v4.1.7
with:
fetch-depth: 0
- name: Fetch tags
run: git fetch --tags --force

- name: Build rubikpi3 with mounting
run: |
chmod +x ./mount_rubikpi3.sh
./mount_rubikpi3.sh ${{ env.base_image }} ${{ env.script }} ${{ github.ref_name }}

- uses: actions/upload-artifact@v4.3.4
with:
name: photonvision_rubikpi3.tar.xz
path: photonvision_rubikpi3.tar.xz
if-no-files-found: error
retention-days: 1

build:
runs-on: ubuntu-24.04

Expand Down Expand Up @@ -95,7 +123,7 @@ jobs:
retention-days: 1

release:
needs: [build]
needs: [build, rubik]
runs-on: ubuntu-24.04
steps:
# Download literally every single artifact
Expand All @@ -111,17 +139,10 @@ jobs:
**/*.xz
if: github.event_name == 'push'
# Upload all xz archives to GH tag if tagged
- uses: softprops/action-gh-release@v2.0.8
with:
files: |
**/*opi5*.xz
if: startsWith(github.ref, 'refs/tags/v')
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: softprops/action-gh-release@v2.0.8
- uses: softprops/action-gh-release@v2.4.0
with:
files: |
**/!(*opi5*).xz
**.xz
if: startsWith(github.ref, 'refs/tags/v')
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
66 changes: 66 additions & 0 deletions install_rubikpi3.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/bin/bash -v
# Verbose and exit on errors
set -ex

cd /tmp/build
echo '=== Current directory: \$(pwd) ==='
echo '=== Files in current directory: ==='
ls -la

REPO_ENTRY="deb http://apt.thundercomm.com/rubik-pi-3/noble ppa main"
HOST_ENTRY="151.106.120.85 apt.rubikpi.ai" # TODO: Remove legacy

# First update the APT
apt-get update -y


# TODO: Remove legacy
sed -i "/$HOST_ENTRY/d" /etc/hosts || true
sed -i '/apt.rubikpi.ai ppa main/d' /etc/apt/sources.list || true

if ! grep -q "^[^#]*$REPO_ENTRY" /etc/apt/sources.list; then
echo "$REPO_ENTRY" | tee -a /etc/apt/sources.list >/dev/null
fi

# Add the GPG key for the RUBIK Pi PPA
wget -qO - https://thundercomm.s3.dualstack.ap-northeast-1.amazonaws.com/uploads/web/rubik-pi-3/tools/key.asc | tee /etc/apt/trusted.gpg.d/rubikpi3.asc

apt update -y

apt-get -y --allow-downgrades install libsqlite3-0=3.45.1-1ubuntu2
apt-get -y install libqnn1 libsnpe1 tensorflow-lite-qcom-apps qcom-adreno1

ln -sf libOpenCL.so.1 /usr/lib/aarch64-linux-gnu/libOpenCL.so # Fix for snpe-tools

# Run normal photon installer
chmod +x ./install.sh
./install.sh --install-nm=yes --arch=aarch64

# Enable ssh
systemctl enable ssh


# Remove extra packages too
echo "Purging extra things"
apt-get purge -y gdb gcc g++ linux-headers* libgcc*-dev
apt-get autoremove -y

echo "Installing additional things"

apt-get update -y

apt-get install -y device-tree-compiler

rm -rf /var/lib/apt/lists/*
apt-get clean

rm -rf /usr/share/doc
rm -rf /usr/share/locale/

echo '=== Running install_common.sh ==='
chmod +x ./install_common.sh
./install_common.sh
echo '=== Creating version file ==='
mkdir -p /opt/photonvision/
echo '{$1};rubikpi3' > /opt/photonvision/image-version
echo '=== Installation complete ==='
216 changes: 216 additions & 0 deletions mount_rubikpi3.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
# Set variables

base_image=$1
script=$2

set -exv

# Install required packages
sudo apt-get update
sudo apt-get install -y qemu-user-static wget xz-utils
# If base_image ends with .yaml, treat it as a manifest and skip download
if [[ "$base_image" == *.yaml ]]; then

# Download and process manifest
wget -O manifest.yaml "${base_image}"

echo "=== Manifest contents ==="
cat manifest.yaml
echo "========================="

# Process each component using awk to extract URL and SHA256
awk '/url:/ {
sub(/.*url:[[:space:]]*/,"",$0);
url=$0
}
/sha256sum:/ {
sub(/.*sha256sum:[[:space:]]*/,"",$0);
print url, $0
}' manifest.yaml | while read -r url sha; do
filename=$(basename "$url")
echo "Downloading: $filename from $url"
wget -nv -O "$filename" "$url"
echo "$sha $filename" | sha256sum -c -
done

echo "=== Downloaded files ==="
ls -lh
echo "========================"
elif [[ "$base_image" == *.tar.xz ]]; then
# Directly download the tar.xz file
wget -nv -O base_image.tar.xz "${base_image}"
tar -xJf base_image.tar.xz
else
echo "Error: base_image must be a .yaml manifest or .tar.xz"
exit 1
fi
# Find the rootfs image - look for the largest .img.xz file or one with "rootfs" in name
ROOTFS_IMG_XZ=""

# First try to find a file with "rootfs" in the name
for file in *.img.xz; do
if [[ "$file" == *"rootfs"* ]]; then
ROOTFS_IMG_XZ="$file"
echo "Found rootfs image by name: $ROOTFS_IMG_XZ"
break
fi
done

# If not found, use the largest .img.xz file
if [ -z "$ROOTFS_IMG_XZ" ]; then
ROOTFS_IMG_XZ=$(ls -S *.img.xz 2>/dev/null | head -n1)
echo "Using largest .img.xz file as rootfs: $ROOTFS_IMG_XZ"
fi

if [ -z "$ROOTFS_IMG_XZ" ] || [ ! -f "$ROOTFS_IMG_XZ" ]; then
echo "Error: Could not find a suitable rootfs image file"
echo "Available files:"
ls -la
exit 1
fi

ROOTFS_IMG="${ROOTFS_IMG_XZ%.xz}"

echo "Extracting rootfs image: $ROOTFS_IMG_XZ"
xz -d "$ROOTFS_IMG_XZ"

if [ ! -f "$ROOTFS_IMG" ]; then
echo "Error: Failed to extract $ROOTFS_IMG"
exit 1
fi

echo "Using rootfs image: $ROOTFS_IMG"

# This uses a fixed offset for Ubuntu preinstalled server images
echo "=== Mounting rootfs with fixed offset (rpiimager method) ==="
mkdir -p ./rootfs

# Calculate offset: 4096 bytes/sector * 139008 sectors = 569,376,768 bytes
OFFSET=$((4096*139008))
echo "Using offset: $OFFSET bytes (sector 139008)"

sudo mount -o rw,loop,offset=$OFFSET "$ROOTFS_IMG" ./rootfs

if [ $? -ne 0 ]; then
echo "Error: Failed to mount image with fixed offset"
exit 1
fi

echo "=== Mount successful ==="
ls -la ./rootfs | head -20

# Check if this is a Canonical or Modified image (from rpiimager logic)
if [ -f "rootfs/etc/ImgType" ]; then
cp rootfs/etc/ImgType ImgType
else
echo "Canonical" > ImgType
fi
read ImgType < ImgType
echo "Image type: $ImgType"

# Expand image if it's a Canonical image (first time modification)
if [ "$ImgType" == "Canonical" ]; then
echo "=== Marking image as CustomIDE ==="
sudo chroot rootfs /bin/bash -c "
touch /etc/ImgType
echo 'CustomIDE' > /etc/ImgType
"

echo "=== Unmounting for expansion ==="
sudo umount ./rootfs

# Expand the image by 4GB (reduced from 10GB to fit GitHub Actions disk space)
echo "=== Expanding image by 4GB ==="
dd if=/dev/zero bs=1M count=4096 >> "$ROOTFS_IMG"

# Remount after expansion
echo "=== Remounting after expansion ==="
sudo mount -o rw,loop,offset=$OFFSET "$ROOTFS_IMG" ./rootfs
elif [ "$ImgType" == "CustomIDE" ]; then
echo "Image already customized, no expansion needed"
fi

rm -f ImgType

echo "=== Filesystem ready ==="

# Setup chroot environment
sudo mount -t proc proc rootfs/proc
sudo mount -t sysfs sysfs rootfs/sys
sudo mount -t tmpfs tmpfs rootfs/run
sudo mount --bind /dev rootfs/dev

# Setup DNS resolution in chroot
echo "=== Setting up DNS in chroot ==="
sudo rm -f rootfs/etc/resolv.conf
sudo cp /etc/resolv.conf rootfs/etc/resolv.conf
sudo cp /etc/hosts rootfs/etc/hosts

# Copy qemu static binaries for ARM emulation
sudo cp /usr/bin/qemu-arm-static rootfs/usr/bin/ || true
sudo cp /usr/bin/qemu-aarch64-static rootfs/usr/bin/ || true

# DEPRECATED: using bind mount instead
# Copy repository into chroot (excluding mounted directories and problematic files)
# sudo mkdir -p rootfs/tmp/build/
# sudo rsync -av --exclude=rootfs --exclude=.git --exclude=*.img --exclude=*.xz . rootfs/tmp/build/

# Mount and bind the current directory into /tmp/build in chroot
sudo mkdir -p rootfs/tmp/build/
sudo mount --bind "$(pwd)" rootfs/tmp/build/

# Install sudo in the chroot environment (needed by install scripts)
echo "=== Installing sudo in chroot ==="
sudo chroot rootfs /usr/bin/qemu-aarch64-static /bin/bash -c "set -exv && DEBIAN_FRONTEND=noninteractive apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y sudo"

# Run the installation scripts in chroot with verbose output
echo "=== Running installation scripts in chroot ==="
sudo chroot rootfs /usr/bin/qemu-aarch64-static /bin/bash -c "
set -exv
export DEBIAN_FRONTEND=noninteractive
echo '=== Making script executable ==='
chmod +x ${script}
echo '=== Running ${script} with arguments: ${@:3} ==='
./${script} ${@:3}
"

# Cleanup mounts
sudo umount rootfs/dev || true
sudo umount rootfs/run || true
sudo umount rootfs/sys || true
sudo umount rootfs/proc || true
sudo umount rootfs/tmp/build/ || true
sudo umount rootfs || true

# More aggressive loop device cleanup
if [ -n "$LOOP_DEV" ]; then
sudo losetup -d "$LOOP_DEV" || true
fi

# Find and detach any remaining loop devices pointing to our image
sudo losetup -j "$ROOTFS_IMG" | cut -d: -f1 | xargs -r sudo losetup -d

# Ensure all filesystem operations are complete
sync
sleep 3

# Assembly process for remaining files
mkdir -p photonvision_rubikpi3
# Extract .tar.gz archive(s) directly into photonvision_rubikpi3 if they exist
if ls *.tar.gz 1>/dev/null 2>&1; then
tar -xzf *.tar.gz -C photonvision_rubikpi3
fi
# Move all files (rawprogram, dtb, img) into photonvision_rubikpi3
mv rawprogram*.xml photonvision_rubikpi3/ 2>/dev/null || true
mv dtb.bin photonvision_rubikpi3/ 2>/dev/null || true
mv *.img photonvision_rubikpi3/ 2>/dev/null || true

# Flatten directory structure - move all files from subdirectories to photonvision_rubikpi3 root
find photonvision_rubikpi3 -mindepth 2 -type f -exec mv {} photonvision_rubikpi3/ \;
# Remove empty subdirectories
find photonvision_rubikpi3 -mindepth 1 -type d -empty -delete

# Set output for later steps
# Save the rootfs image path for later steps
echo "rootfs_image=$ROOTFS_IMG" >> $GITHUB_ENV
tar -cJf photonvision_rubikpi3.tar.xz -C . photonvision_rubikpi3