name: Create Images on: workflow_dispatch: inputs: board: description: 'Board to create image for' type: choice required: true options: - raspberrypi-rpi2 - raspberrypi-rpi64 - bananapi-bpi-r3 - bananapi-bpi-r4 - bananapi-bpi-r64 - friendlyarm-nanopi-r2s - microchip-sama7g54-ek - acer-connect-vero-w default: 'raspberrypi-rpi64' jobs: create-image: name: Create images for ${{ inputs.board }} runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v6 with: clean: true fetch-depth: 0 submodules: recursive - name: Install dependencies run: | sudo apt-get update sudo apt-get install -y \ genimage \ u-boot-tools \ parted \ gdisk \ qemu-utils \ dosfstools \ e2fsprogs \ genext2fs \ mtools \ jq - name: Prepare build environment run: | # Set up directory structure similar to buildroot build mkdir -p output/images mkdir -p build - name: Set bootloaders and targets based on board run: | arch= targets= bootloader_sdcard= bootloader_emmc= case "${{ inputs.board }}" in raspberrypi-rpi2) arch=arm targets="sdcard" bootloader_sdcard=rpi2-boot ;; raspberrypi-rpi64) arch=aarch64 targets="sdcard" bootloader_sdcard=rpi64-boot ;; bananapi-bpi-r3) arch=aarch64 targets="sdcard emmc" bootloader_sdcard=bpi-r3-sd-boot bootloader_emmc=bpi-r3-emmc-boot ;; bananapi-bpi-r4) arch=aarch64 targets="sdcard emmc" bootloader_sdcard=bpi-r4-sd-boot bootloader_emmc=bpi-r4-emmc-boot ;; bananapi-bpi-r64) arch=aarch64 targets="sdcard emmc" bootloader_sdcard=bpi-r64-sd-boot bootloader_emmc=bpi-r64-emmc-boot ;; acer-connect-vero-w) arch=aarch64 targets="emmc" bootloader_emmc=bpi-r3-emmc-boot ;; friendlyarm-nanopi-r2s) arch=aarch64 targets="sdcard" bootloader_sdcard=nanopi-r2s-boot ;; microchip-sama7g54-ek) arch=arm targets="sdcard emmc" bootloader_sdcard=sama7g54-ek-sd-boot bootloader_emmc=sama7g54-ek-emmc-boot ;; *) echo "Error: Unknown board ${{ inputs.board }}" exit 1 ;; esac echo "ARCH=$arch" >> $GITHUB_ENV echo "TARGETS=$targets" >> $GITHUB_ENV [ -n "$bootloader_sdcard" ] && echo "BOOTLOADER_SDCARD=$bootloader_sdcard" >> $GITHUB_ENV [ -n "$bootloader_emmc" ] && echo "BOOTLOADER_EMMC=$bootloader_emmc" >> $GITHUB_ENV echo "Arch: $arch for board: ${{ inputs.board }}" echo "Targets: $targets" [ -n "$bootloader_sdcard" ] && echo "SD bootloader: $bootloader_sdcard" [ -n "$bootloader_emmc" ] && echo "eMMC bootloader: $bootloader_emmc" - name: Download bootloader artifacts run: | for target in $TARGETS; do upper=$(printf '%s' "$target" | tr '[:lower:]' '[:upper:]') bootloader_var="BOOTLOADER_${upper}" bootloader="${!bootloader_var}" temp_dir="temp_bootloader_${target}" out_dir="output_${target}/images" echo "Downloading ${target} bootloader: ${bootloader}" mkdir -p "$out_dir" gh release download latest-boot --pattern "*${bootloader}*" --dir "$temp_dir/" tar -xzf "$temp_dir"/*.tar.gz --strip-components=1 -C "$out_dir/" rm -rf "$temp_dir" echo "${target} bootloader files:" ls -la "$out_dir/" done env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Download Infix artifacts run: | gh run list --workflow=164295764 --branch=main --limit=1 --status=success --json databaseId --jq '.[0].databaseId' > latest_infix_run_id INFIX_RUN_ID=$(cat latest_infix_run_id) gh run download ${INFIX_RUN_ID} --name artifact-${ARCH} --dir temp_infix/ for target in $TARGETS; do out_dir="output_${target}/images" mkdir -p "$out_dir" tar -xzf temp_infix/*.tar.gz --strip-components=1 -C "$out_dir/" echo "Infix files extracted to ${out_dir}:" ls -la "$out_dir/" done rm -rf temp_infix/ env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Verify extracted files run: | for target in $TARGETS; do echo "Files available for ${target} image:" ls -la "output_${target}/images/" echo "" done - name: Create images run: | export BUILD_DIR=$PWD/build export BR2_EXTERNAL_INFIX_PATH=$PWD export RELEASE="" export INFIX_ID="infix" for target in $TARGETS; do export BINARIES_DIR=$PWD/output_${target}/images ./utils/mkimage.sh -t "$target" ${{ inputs.board }} done - name: Verify created images run: | mkdir -p output/images for target in $TARGETS; do src_dir="output_${target}/images" found=false echo "${target} image:" ls -lh "$src_dir"/*-"$target".img* 2>/dev/null || true for img in "$src_dir"/*-"$target".img; do [ -e "$img" ] || continue found=true echo "- $(basename "$img")" file "$img" fdisk -l "$img" 2>/dev/null || true done if [ "$found" = false ]; then echo "No ${target} image found matching pattern: *-${target}.img" echo "Available files in ${src_dir}:" ls -la "$src_dir/" exit 1 fi for artifact in "$src_dir"/*-"$target".img*; do [ -e "$artifact" ] || continue cp "$artifact" output/images/ done echo "" done - name: Upload images as artifacts uses: actions/upload-artifact@v7 with: name: images-${{ inputs.board }} path: | output/images/*-sdcard.img* output/images/*-emmc.img* retention-days: 30 - name: Create checksums run: | cd output/images/ for file in *-sdcard.img *-emmc.img; do if [ -f "$file" ]; then sha256sum "$file" > "$file.sha256" fi done - name: Upload to release uses: ncipollo/release-action@v1 with: allowUpdates: true omitName: true omitBody: true omitBodyDuringUpdate: true prerelease: true tag: "latest-boot" token: ${{ secrets.GITHUB_TOKEN }} artifacts: "output/images/*-sdcard.img*,output/images/*-emmc.img*" - name: Generate summary run: | cat <> $GITHUB_STEP_SUMMARY # Image Build Complete! 🚀 **Board:** ${{ inputs.board }} **Arch:** ${{ env.ARCH }} **Targets:** ${{ env.TARGETS }} **Bootloader Source:** latest-boot release **Infix Source:** Latest workflow run on main ## Bootloaders $(for target in $TARGETS; do case "$target" in sdcard) bootloader="$BOOTLOADER_SDCARD" ;; emmc) bootloader="$BOOTLOADER_EMMC" ;; esac printf -- '- %s: %s\n' "$target" "$bootloader" done) ## Created Images $(find output/images/ -name "*.img" -o -name "*.img.bmap" | xargs ls -lh 2>/dev/null | awk '{print "- " $9 " (" $5 ")"}' || echo "- No images found") ## Download The generated images are available as workflow artifacts above and in the latest-boot release. EOF