From 6709c88dcd9dc4f3067f6f2e6261d0a62c59f402 Mon Sep 17 00:00:00 2001 From: Michael Baudino Date: Wed, 22 Apr 2020 12:05:37 +0200 Subject: [PATCH 1/2] feat(ci): automatically generate assets for Raspberry Pi Imager MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit introduces a script that take as argument a path to a directory of Recalbox images and a destination path, and it generates the assets to make those images available on the [Rapsberry Pi Imager]. The path to images should have a subdirectory for each architecture, e.g. for an image directory named `dist`: ``` dist/ ├─ rpi1/ │ └─ recalbox-rpi1.img.xz ├─ rpi2/ │ └─ recalbox-rpi2.img.xz └─ rpi3/ └─ recalbox-rpi3.img.xz ``` [Raspberry Pi Imager]: https://github.com/raspberrypi/rpi-imager --- scripts/release/README.md | 36 + .../generate_external_installer_assets.sh | 90 + .../os_list_imagingutility_recalbox.json | 37 + .../templates/raspi_imager/recalbox.svg | 5991 +++++++++++++++++ 4 files changed, 6154 insertions(+) create mode 100644 scripts/release/README.md create mode 100755 scripts/release/generate_external_installer_assets.sh create mode 100644 scripts/release/templates/raspi_imager/os_list_imagingutility_recalbox.json create mode 100644 scripts/release/templates/raspi_imager/recalbox.svg diff --git a/scripts/release/README.md b/scripts/release/README.md new file mode 100644 index 0000000000..e483314497 --- /dev/null +++ b/scripts/release/README.md @@ -0,0 +1,36 @@ +# Raspberry Pi Imager + +
+ Recalbox entry for os_list_imagingutility.json + + > ℹ️ This can only be added to the [official `os_list_imagingutility.json`](https://downloads.raspberrypi.org/os_list_imagingutility.json) by Raspberry Foundation engineers + + ```json + { + "os_list": [ + { + "name": "Recalbox", + "description": "The official retro-gaming OS! Turn your Raspberry Pi into an all-in-one and plug-n-play retro-gaming console, supporting 100+ gaming systems!", + "icon": "https://download.recalbox.com/raspi-imager/recalbox.svg", + "subitems_url": "https://download.recalbox.com/raspi-imager/os_list_imagingutility_recalbox.json" + } + ] + } + ``` +
+ +Raspberry Pi Imager is much more flexible than NOOBS' one, because it allows us to host (and thus dynamically update!) our own configuration file via `subitems_url`. + +## `os_list_imagingutility.json` + +Each entry in this file represents an OS. Here is the list of fields each entry can define: + * `name` ⇒ name of the OS + * `description` ⇒ longer description of the OS + * `icon` ⇒ logo of the OS + * `extract_size` ⇒ size of image in bytes, once uncompressed + * `extract_sha256` ⇒ SHA256 hash of image, once uncompressed + * `image_download_size` ⇒ size of downloaded image (compressed) + * `image_download_sha256` ⇒ SHA256 hash of image (compressed) + * `release_date` ⇒ release date in `YYY-MM-DD` format + * `subitems_url` ⇒ URL to a file describing "flavours" of this OS: they can define exactly the same fields and will replace the entry declaring `subitems_url` + diff --git a/scripts/release/generate_external_installer_assets.sh b/scripts/release/generate_external_installer_assets.sh new file mode 100755 index 0000000000..82ac64574b --- /dev/null +++ b/scripts/release/generate_external_installer_assets.sh @@ -0,0 +1,90 @@ +#!/bin/bash + +## FUNCTIONS ## + +function exitWithUsage { + echo "Usage: $0 --images-dir --destination-dir " + echo + echo "This script generates assets for external OS installers (imagers)" + echo "such as NOOBS, PINN or Raspberry Pi Imager." + echo + echo " --images-dir path to Recalbox images" + echo " (should have a subdirectory per architecture)" + echo " --destination-dir path where assets will be generated" + exit 64 +} + +function generateRaspberryPiImagerAssets { + local templateDir="$(dirname $(readlink -f $0))/templates/raspi_imager" + local destinationDir="${params[destinationDir]}/raspi-imager" + declare -A metadata + + echo ">>> Generating assets for Raspberry Pi Imager (in ${destinationDir})" + + # Gather required information from images directory + + metadata[version]=${CI_COMMIT_REF_NAME} + metadata[releaseDate]=$(date +%Y-%m-%d) + + for arch in rpi1 rpi2 rpi3; do + # Fetch info regarding image downloads (XZ-compressed Recalbox image) + metadata["${arch}ImageDownloadSize"]=$(stat --format=%s "${params[imagesDir]}/${arch}/recalbox-${arch}.img.xz") + metadata["${arch}ImageDownloadSha256"]=$(sha256sum "${params[imagesDir]}/${arch}/recalbox-${arch}.img.xz" | cut -d' ' -f1) + # Fetch info regarding extracted images (raw Recalbox image, after XZ decompression) + unxz --keep "${params[imagesDir]}/${arch}/recalbox-${arch}.img.xz" + metadata["${arch}ExtractSize"]=$(stat --format=%s "${params[imagesDir]}/${arch}/recalbox-${arch}.img") + metadata["${arch}ExtractSha256"]=$(sha256sum "${params[imagesDir]}/${arch}/recalbox-${arch}.img" | cut -d' ' -f1) + rm "${params[imagesDir]}/${arch}/recalbox-${arch}.img" + done + + # Create assets in destination directory + + mkdir -p ${destinationDir} + + cat "${templateDir}/os_list_imagingutility_recalbox.json" \ + | sed -e "s|{{version}}|${metadata[version]}|" \ + -e "s|{{releaseDate}}|${metadata[releaseDate]}|" \ + -e "s|{{rpi1ExtractSize}}|${metadata[rpi1ExtractSize]}|" \ + -e "s|{{rpi2ExtractSize}}|${metadata[rpi2ExtractSize]}|" \ + -e "s|{{rpi3ExtractSize}}|${metadata[rpi3ExtractSize]}|" \ + -e "s|{{rpi1ExtractSha256}}|${metadata[rpi1ExtractSha256]}|" \ + -e "s|{{rpi2ExtractSha256}}|${metadata[rpi2ExtractSha256]}|" \ + -e "s|{{rpi3ExtractSha256}}|${metadata[rpi3ExtractSha256]}|" \ + -e "s|{{rpi1ImageDownloadSize}}|${metadata[rpi1ImageDownloadSize]}|" \ + -e "s|{{rpi2ImageDownloadSize}}|${metadata[rpi2ImageDownloadSize]}|" \ + -e "s|{{rpi3ImageDownloadSize}}|${metadata[rpi3ImageDownloadSize]}|" \ + -e "s|{{rpi1ImageDownloadSha256}}|${metadata[rpi1ImageDownloadSha256]}|" \ + -e "s|{{rpi2ImageDownloadSha256}}|${metadata[rpi2ImageDownloadSha256]}|" \ + -e "s|{{rpi3ImageDownloadSha256}}|${metadata[rpi3ImageDownloadSha256]}|" \ + > "${destinationDir}/os_list_imagingutility_recalbox.json" + cp -n "${templateDir}/recalbox.svg" "${destinationDir}/recalbox.svg" +} + +## PARAMETERS PARSING ## + +declare -A params + +while [ -n "$1" ]; do + case "$1" in + --images-dir) + shift + [ -n "$1" ] && params[imagesDir]=$(readlink -f "$1") || exitWithUsage + ;; + --destination-dir) + shift + [ -n "$1" ] && params[destinationDir]=$(readlink -f "$1") || exitWithUsage + ;; + *) + exitWithUsage + ;; + esac + shift +done + +if [[ ! -d ${params[imagesDir]} || ! -d ${params[destinationDir]} ]]; then + exitWithUsage +fi + +## MAIN ## + +generateRaspberryPiImagerAssets diff --git a/scripts/release/templates/raspi_imager/os_list_imagingutility_recalbox.json b/scripts/release/templates/raspi_imager/os_list_imagingutility_recalbox.json new file mode 100644 index 0000000000..b97f8ca89d --- /dev/null +++ b/scripts/release/templates/raspi_imager/os_list_imagingutility_recalbox.json @@ -0,0 +1,37 @@ +{ + "os_list": [ + { + "name": "Recalbox {{version}} (Pi 0/1)", + "description": "The official retro-gaming OS! Turn your Raspberry Pi into an all-in-one and plug-n-play retro-gaming console, supporting 100+ gaming systems!", + "url": "https://recalbox-releases.s3.nl-ams.scw.cloud/stable/v2/upgrade/rpi1/recalbox-rpi1.img.xz", + "icon": "https://download.recalbox.com/recalbox.svg", + "extract_size": {{rpi1ExtractSize}}, + "extract_sha256": "{{rpi1ExtractSha256}}", + "image_download_size": {{rpi1ImageDownloadSize}}, + "image_download_sha256": "{{rpi1ImageDownloadSha256}}", + "release_date": "{{releaseDate}}" + }, + { + "name": "Recalbox {{version}} (Pi 2)", + "description": "The official retro-gaming OS! Turn your Raspberry Pi into an all-in-one and plug-n-play retro-gaming console, supporting 100+ gaming systems!", + "url": "https://recalbox-releases.s3.nl-ams.scw.cloud/stable/v2/upgrade/rpi2/recalbox-rpi2.img.xz", + "icon": "https://download.recalbox.com/recalbox.svg", + "extract_size": {{rpi2ExtractSize}}, + "extract_sha256": "{{rpi2ExtractSha256}}", + "image_download_size": {{rpi2ImageDownloadSize}}, + "image_download_sha256": "{{rpi2ImageDownloadSha256}}", + "release_date": "{{releaseDate}}" + }, + { + "name": "Recalbox {{version}} (Pi 3)", + "description": "The official retro-gaming OS! Turn your Raspberry Pi into an all-in-one and plug-n-play retro-gaming console, supporting 100+ gaming systems!", + "url": "https://recalbox-releases.s3.nl-ams.scw.cloud/stable/v2/upgrade/rpi3/recalbox-rpi3.img.xz", + "icon": "https://download.recalbox.com/recalbox.svg", + "extract_size": {{rpi3ExtractSize}}, + "extract_sha256": "{{rpi3ExtractSha256}}", + "image_download_size": {{rpi3ImageDownloadSize}}, + "image_download_sha256": "{{rpi3ImageDownloadSha256}}", + "release_date": "{{releaseDate}}" + } + ] +} diff --git a/scripts/release/templates/raspi_imager/recalbox.svg b/scripts/release/templates/raspi_imager/recalbox.svg new file mode 100644 index 0000000000..c292e5ce79 --- /dev/null +++ b/scripts/release/templates/raspi_imager/recalbox.svg @@ -0,0 +1,5991 @@ + + + +