Build ESP32 Rust no_std binaries and upload to GitHub Release #18
This file contains 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 ESP32 Rust Binaries and upload to GitHub Release | |
on: | |
workflow_dispatch: | |
inputs: | |
release_tag: | |
description: "Upload to specific release" | |
required: true | |
default: 'v0.1.0' | |
skip_projects: | |
description: "Skip projects during build (e.g. esp32-c3-devkit-rust)" | |
required: false | |
default: '' | |
jobs: | |
get_release: | |
name: Get release | |
runs-on: ubuntu-latest | |
outputs: | |
upload_url: ${{ steps.get_upload_url.outputs.url }} | |
steps: | |
- uses: octokit/[email protected] | |
id: get_release | |
with: | |
route: GET /repos/{owner}/{repo}/releases/tags/${{ github.event.inputs.release_tag }} | |
owner: georgik | |
repo: esp32-lang-lab | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
- name: get upload url | |
id: get_upload_url | |
run: | | |
url=$(echo "$response" | jq -r '.upload_url' | sed 's/{?name,label}//') | |
echo "url=$url" >> $GITHUB_OUTPUT | |
env: | |
response: ${{ steps.get_release.outputs.data }} | |
build: | |
runs-on: ubuntu-22.04 | |
container: | |
image: espressif/idf-rust:all_1.75.0.0 | |
options: --user esp --workdir /home/esp | |
needs: get_release | |
steps: | |
- name: Clone repository with specific branch | |
run: | | |
export HOME=/home/esp | |
cd /home/esp | |
set +e # Workaround for Exit code 2 exit code installation | |
curl -L https://wokwi.com/ci/install.sh | sh | |
exit_code=$? | |
if [ $exit_code -eq 2 ]; then | |
echo "Received exit code 2 from install script, overriding to 0" | |
exit_code=0 | |
else | |
exit $exit_code | |
fi | |
set -e | |
pwd | |
git clone --depth 1 --branch ${{ github.ref_name }} https://github.com/georgik/esp32-lang-lab.git esp32-lang-lab | |
- name: Build and upload binaries | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
WOKWI_CLI_TOKEN: ${{ secrets.WOKWI_CLI_TOKEN }} | |
run: | | |
# Workaround GitHub issue with setting HOME in container https://github.com/actions/runner/issues/863 | |
export HOME=/home/esp | |
export PROJECT="${HOME}/esp32-lang-lab/examples/rust/no_std/hello-world" | |
cd /home/esp | |
. /home/esp/.bashrc | |
. /home/esp/export-esp.sh | |
# Install jq - workaround when running in the image without jq | |
mkdir -p $HOME/bin | |
curl -L -o $HOME/bin/jq "https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64" | |
chmod +x $HOME/bin/jq | |
export PATH="$HOME/bin:$PATH" | |
# echo "$HOME/bin" >> $GITHUB_PATH | |
# Upload loop for each binary | |
cd ${PROJECT} | |
# Prepare report | |
echo '[]' > results.json | |
for TARGET in esp32 esp32s2 esp32s3 esp32c3 esp32c6 esp32h2; do | |
echo "Building $TARGET" | |
OUTPUT_PREFIX="rust-no_std-hello-world-${TARGET}-${{ github.event.inputs.release_tag }}" | |
OUTPUT_BIN="${OUTPUT_PREFIX}.bin" | |
OUTPUT_TXT="${OUTPUT_PREFIX}.txt" | |
# If TARGET is a substring in SKIP_PROJECTS, skip it | |
#if echo "${{ github.event.inputs.skip_projects }}" | grep -q "${TARGET}"; then | |
# echo "Skipping $TARGET" | |
# continue | |
#fi | |
# Prepare Rust build | |
cp support/rust/rust-toolchain-${TARGET}.toml rust-toolchain.toml | |
echo "Toolchain: $(cat rust-toolchain.toml)" | |
# Using alias from .cargo/config.toml | |
cargo "save-image-${TARGET}" --release --merge --skip-padding ${OUTPUT_BIN} | |
# Prepare Wokwi test | |
cp support/wokwi/diagram-${TARGET}.json diagram.json | |
cp support/wokwi/wokwi-${TARGET}.toml wokwi.toml | |
# Run Wokwi test | |
/home/esp/bin/wokwi-cli --timeout 5000 \ | |
--timeout-exit-code 0 \ | |
--serial-log-file ${PROJECT}/${OUTPUT_TXT} \ | |
--elf ${OUTPUT_BIN} \ | |
"." | |
# Upload binary | |
asset_path="${PROJECT}/${OUTPUT_BIN}" | |
asset_name="${OUTPUT_BIN}" | |
curl \ | |
--request POST \ | |
--header "authorization: Bearer $GITHUB_TOKEN" \ | |
--header "Content-Type: application/octet-stream" \ | |
--data-binary "@$asset_path" \ | |
--url "${{ needs.get_release.outputs.upload_url }}?name=${asset_name}" | |
# Upload log | |
asset_path="${PROJECT}/${OUTPUT_TXT}" | |
asset_name="${OUTPUT_TXT}" | |
curl \ | |
--request POST \ | |
--header "authorization: Bearer $GITHUB_TOKEN" \ | |
--header "Content-Type: application/octet-stream" \ | |
--data-binary "@$asset_path" \ | |
--url "${{ needs.get_release.outputs.upload_url }}?name=${asset_name}" | |
# Extract heap size (you might need to adjust the parsing command) | |
HEAP_SIZE=$(grep 'Minimum free heap size' ${OUTPUT_TXT} | sed -e 's/Minimum free heap size: //' -e 's/ bytes//') | |
# Add a new record to the JSON database | |
jq --arg target "$TARGET" \ | |
--arg language "Rust" \ | |
--arg flavor "no_std" \ | |
--arg example "hello-world" \ | |
--arg property "heap" \ | |
--arg value "$HEAP_SIZE" \ | |
--arg unit "bytes" \ | |
--arg note "" \ | |
--arg version "1.75" \ | |
--arg timestamp "$(date -Iseconds)" \ | |
'. += [{ | |
target: $target, | |
language: $language, | |
flavor: $flavor, | |
example: $example, | |
property: $property, | |
value: $value, | |
unit: $unit, | |
note: $note, | |
version: $version, | |
timestamp: $timestamp | |
}]' results.json > temp.json && mv temp.json results.json | |
# If skip-wokwi-test.toml exists, skip Wokwi test | |
#if [ ! -f "skip-wokwi-test.toml" ]; then | |
# asset_path="/home/esp/project/${TARGET}/screenshot.png" | |
# asset_name="spooky-maze-${TARGET}-${{ github.event.inputs.release_tag }}.png" | |
# curl \ | |
# --request POST \ | |
# --header "authorization: Bearer $GITHUB_TOKEN" \ | |
# --header "Content-Type: application/octet-stream" \ | |
# --data-binary "@$asset_path" \ | |
# --url "${{ needs.get_release.outputs.upload_url }}?name=${asset_name}" | |
#fi | |
done | |
# Generate report | |
echo "| Target | Language | Flavor | Example | Property | Value | Unit | Note | Version | Timestamp |" > report.md | |
echo "|--------|----------|--------|---------|----------|-------|------|------|---------|-----------|" >> report.md | |
jq -r '.[] | "\(.target) | \(.language) | \(.flavor) | \(.example) | \(.property) | \(.value) | \(.unit) | \(.note) | \(.version) | \(.timestamp) |"' results.json >> report.md | |
asset_path="${PROJECT}/report.md" | |
asset_name="report.md" | |
curl \ | |
--request POST \ | |
--header "authorization: Bearer $GITHUB_TOKEN" \ | |
--header "Content-Type: application/octet-stream" \ | |
--data-binary "@$asset_path" \ | |
--url "${{ needs.get_release.outputs.upload_url }}?name=${asset_name}" | |
asset_path="${PROJECT}/report.json" | |
asset_name="report.json" | |
curl \ | |
--request POST \ | |
--header "authorization: Bearer $GITHUB_TOKEN" \ | |
--header "Content-Type: application/octet-stream" \ | |
--data-binary "@$asset_path" \ | |
--url "${{ needs.get_release.outputs.upload_url }}?name=${asset_name}" |