Publish with a git tag
This workflow builds your firmware on GitHub whenever you push a tag that starts with v, then attaches the .bin files to a GitHub release. If the repository is linked to a firmware here, that release becomes a new version with the tag as its name and the release text as its notes.
- Save the workflow below as
.github/workflows/release.ymlin your repository. - Change the board (
FQBN) ortargetto match yours, and list any libraries the sketch uses. - Link the repository on the new firmware page, or in an existing firmware's settings.
- Run
git tag v1.0.0 && git push --tags. The build takes two to four minutes.
Arduino sketch
For a repository with the .ino file at its root. Uses arduino-cli and the ESP32 core.
name: Release firmware
on:
push:
tags: ["v*"]
permissions:
contents: write # needed to create the release
env:
FQBN: esp32:esp32:esp32c3 # your board; arduino-cli board listall esp32
ESP32_INDEX: https://espressif.github.io/arduino-esp32/package_esp32_index.json
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: arduino/setup-arduino-cli@v2
- name: Install the ESP32 core
run: |
arduino-cli core update-index --additional-urls "$ESP32_INDEX"
arduino-cli core install esp32:esp32 --additional-urls "$ESP32_INDEX"
# arduino-cli lib install "Adafruit NeoPixel" # list your libraries here
- name: Build
run: |
arduino-cli compile --fqbn "$FQBN" --export-binaries --output-dir out .
# boot_app0.bin isn't exported; Update mode needs it at 0xe000
cp "$(find ~/.arduino15/packages/esp32/hardware -name boot_app0.bin | head -n1)" out/
- name: Publish the release
uses: softprops/action-gh-release@v2
with:
files: out/*.bin
generate_release_notes: true
ESP-IDF project
For a repository with a top-level CMakeLists.txt. Offsets come from flasher_args.json, so custom partition tables work without extra setup.
name: Release firmware
on:
push:
tags: ["v*"]
permissions:
contents: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Build
uses: espressif/esp-idf-ci-action@v1
with:
esp_idf_version: v5.3
target: esp32c3 # your chip
- name: Publish the release
uses: softprops/action-gh-release@v2
with:
# flasher_args.json carries the exact offsets
files: |
build/flasher_args.json
build/bootloader/bootloader.bin
build/partition_table/partition-table.bin
build/ota_data_initial.bin
build/*.bin
generate_release_notes: true
From a script or another CI
Create an API token on your dashboard, then publish a build folder. The version comes from the app image unless you pass one.
FIRMSHARE_URL=https://this-site FIRMSHARE_TOKEN=fsh_… npx firmshare publish ./build --firmware <id> --notes CHANGELOG.md
The id is the long part of the firmware's link. Add --source src.zip to share the code and --prerelease to keep the main link on the current version.
Using your own build
Any release works if its files follow these names. Anything else attached to the release is ignored.
| File | Written at |
|---|---|
| *.bootloader.bin, bootloader.bin | 0x0 (0x1000 on ESP32, ESP32-S2) |
| *.partitions.bin, partition-table.bin | 0x8000 |
| boot_app0.bin, ota_data_initial.bin | 0xe000 |
| any other .bin with an app header | 0x10000 |
| *.merged.bin | 0x0, only used when no separate parts are attached |
A flasher_args.json in the release overrides these offsets.