Add Waveshare ESP32-C3-Zero DIY variant #30203
Workflow file for this run
This file contains hidden or 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: CI | |
| concurrency: | |
| group: ci-${{ github.head_ref || github.run_id }} | |
| cancel-in-progress: true | |
| on: | |
| # # Triggers the workflow on push but only for the main branches | |
| push: | |
| branches: | |
| - master | |
| - develop | |
| - pioarduino # Remove when merged // use `feature/` in the future. | |
| - event/* | |
| - feature/* | |
| paths-ignore: | |
| - "**.md" | |
| - version.properties | |
| pull_request: | |
| branches: | |
| - master | |
| - develop | |
| - pioarduino # Remove when merged // use `feature/` in the future. | |
| - event/* | |
| - feature/* | |
| paths-ignore: | |
| - "**.md" | |
| #- "**.yml" | |
| schedule: | |
| # Nightly develop build, published to meshtastic.github.io firmware-nightly/ (no GitHub release). | |
| # Scheduled runs execute on the default branch (develop). 09:00 UTC avoids the 00:00 tests | |
| # and 02:00 daily_packaging crons. | |
| - cron: 0 9 * * * # Nightly develop build/publish (default branch is develop) | |
| workflow_dispatch: | |
| inputs: | |
| # trunk-ignore(checkov/CKV_GHA_7): intentional manual-test switch for the nightly publish path | |
| nightly: | |
| description: "Nightly mode: build + publish develop to github.io firmware-nightly/ (skips creating a GitHub release)" | |
| type: boolean | |
| default: false | |
| permissions: read-all | |
| jobs: | |
| setup: | |
| strategy: | |
| fail-fast: true | |
| matrix: | |
| arch: | |
| - all | |
| - check | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: actions/setup-python@v6 | |
| with: | |
| python-version: 3.x | |
| cache: pip | |
| - run: pip install -U platformio | |
| - name: Generate matrix | |
| id: jsonStep | |
| run: | | |
| if [[ "$GITHUB_HEAD_REF" == "" ]]; then | |
| TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}}) | |
| else | |
| TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}} --level pr) | |
| fi | |
| echo "Name: $GITHUB_REF_NAME Base: $GITHUB_BASE_REF Ref: $GITHUB_REF" | |
| echo "${{matrix.arch}}=$TARGETS" >> $GITHUB_OUTPUT | |
| echo "$TARGETS" >> $GITHUB_STEP_SUMMARY | |
| outputs: | |
| all: ${{ steps.jsonStep.outputs.all }} | |
| check: ${{ steps.jsonStep.outputs.check }} | |
| version: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Get release version string | |
| run: | | |
| echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT | |
| echo "deb=$(./bin/buildinfo.py deb)" >> $GITHUB_OUTPUT | |
| id: version | |
| env: | |
| BUILD_LOCATION: local | |
| outputs: | |
| long: ${{ steps.version.outputs.long }} | |
| deb: ${{ steps.version.outputs.deb }} | |
| check: | |
| needs: setup | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| check: ${{ fromJson(needs.setup.outputs.check) }} | |
| # Runs on GitHub-hosted runners so checks don't compete with builds for the | |
| # self-hosted 'arctastic' pool (which builds use). | |
| runs-on: ubuntu-latest | |
| if: ${{ github.event_name != 'workflow_dispatch' && github.repository == 'meshtastic/firmware' && github.event_name != 'schedule' && github.event.inputs.nightly != 'true' }} | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| submodules: recursive | |
| - name: Check ${{ matrix.check.board }} | |
| uses: meshtastic/gh-action-firmware@main | |
| with: | |
| pio_platform: ${{ matrix.check.platform }} | |
| pio_env: ${{ matrix.check.board }} | |
| pio_target: check | |
| build: | |
| needs: [setup, version] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| build: ${{ fromJson(needs.setup.outputs.all) }} | |
| uses: ./.github/workflows/build_firmware.yml | |
| with: | |
| version: ${{ needs.version.outputs.long }} | |
| pio_env: ${{ matrix.build.board }} | |
| platform: ${{ matrix.build.platform }} | |
| build-debian-src: | |
| if: ${{ github.repository == 'meshtastic/firmware' && github.event_name != 'schedule' && github.event.inputs.nightly != 'true' }} | |
| uses: ./.github/workflows/build_debian_src.yml | |
| with: | |
| series: UNRELEASED | |
| build_location: local | |
| secrets: inherit | |
| MacOS: | |
| if: ${{ github.event_name != 'schedule' && github.event.inputs.nightly != 'true' }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| macos_ver: | |
| - "26" # ARM64 | |
| # - '26-intel' # x86_64 | |
| - "15" # ARM64 | |
| # - '15-intel' # x86_64 | |
| uses: ./.github/workflows/build_macos_bin.yml | |
| with: | |
| macos_ver: ${{ matrix.macos_ver }} | |
| # secrets: inherit | |
| package-pio-deps-native-tft: | |
| if: ${{ github.repository == 'meshtastic/firmware' && github.event_name == 'workflow_dispatch' }} | |
| uses: ./.github/workflows/package_pio_deps.yml | |
| with: | |
| pio_env: native-tft | |
| secrets: inherit | |
| test-native: | |
| if: ${{ !contains(github.ref_name, 'event/') && github.repository == 'meshtastic/firmware' && github.event_name != 'schedule' && github.event.inputs.nightly != 'true' }} | |
| permissions: # Needed for dorny/test-reporter. | |
| contents: read | |
| actions: read | |
| checks: write | |
| uses: ./.github/workflows/test_native.yml | |
| build-wasm: | |
| if: ${{ github.event_name != 'schedule' && github.event.inputs.nightly != 'true' }} | |
| # Build the WebAssembly portduino node ([env:native-wasm]) as part of normal CI, | |
| # like the other platforms. It's a dedicated job (not a row in the `build` | |
| # matrix) because its artifact is meshnode.{mjs,wasm} - not a flashable | |
| # .bin/.uf2/.hex - and it needs the Emscripten SDK; board_level=extra keeps | |
| # it out of generate_ci_matrix.py. | |
| uses: ./.github/workflows/build_portduino_wasm.yml | |
| docker: | |
| if: ${{ github.event_name != 'schedule' && github.event.inputs.nightly != 'true' }} | |
| permissions: # Needed for pushing to GHCR. | |
| contents: read | |
| packages: write | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| distro: [debian, alpine] | |
| platform: [linux/amd64, linux/arm64, linux/arm/v7] | |
| pio_env: [native, native-tft] | |
| exclude: | |
| - distro: alpine | |
| platform: linux/arm/v7 | |
| - pio_env: native-tft | |
| platform: linux/arm64 | |
| - pio_env: native-tft | |
| platform: linux/arm/v7 | |
| uses: ./.github/workflows/docker_build.yml | |
| with: | |
| distro: ${{ matrix.distro }} | |
| platform: ${{ matrix.platform }} | |
| runs-on: ${{ contains(matrix.platform, 'arm') && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }} | |
| pio_env: ${{ matrix.pio_env }} | |
| push: false | |
| gather-artifacts: | |
| # trunk-ignore(checkov/CKV2_GHA_1) | |
| if: github.repository == 'meshtastic/firmware' | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| arch: | |
| - esp32 | |
| - esp32s3 | |
| - esp32c3 | |
| - esp32c6 | |
| - nrf52840 | |
| - rp2040 | |
| - rp2350 | |
| - stm32 | |
| runs-on: ubuntu-latest | |
| needs: [version, build] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v7 | |
| - uses: actions/download-artifact@v8 | |
| with: | |
| path: ./ | |
| pattern: firmware-${{matrix.arch}}-* | |
| merge-multiple: true | |
| - name: Display structure of downloaded files | |
| run: ls -R | |
| - name: Repackage in single firmware zip | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }} | |
| overwrite: true | |
| path: | | |
| ./firmware-*.mt.json | |
| ./firmware-*.bin | |
| ./firmware-*.uf2 | |
| ./firmware-*.hex | |
| ./firmware-*.zip | |
| ./device-*.sh | |
| ./device-*.bat | |
| ./littlefs-*.bin | |
| ./bleota*bin | |
| ./mt-*-ota.bin | |
| ./Meshtastic_nRF52_factory_erase*.uf2 | |
| retention-days: 30 | |
| - uses: actions/download-artifact@v8 | |
| with: | |
| name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }} | |
| merge-multiple: true | |
| path: ./output | |
| # For diagnostics | |
| - name: Show artifacts | |
| run: ls -lR | |
| - name: Device scripts permissions | |
| run: | | |
| chmod +x ./output/device-install.sh || true | |
| chmod +x ./output/device-update.sh || true | |
| - name: Zip firmware | |
| run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output | |
| - name: Repackage in single elfs zip | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }} | |
| overwrite: true | |
| path: ./*.elf | |
| retention-days: 30 | |
| firmware-size-report: | |
| if: ${{ github.repository == 'meshtastic/firmware' && github.event_name != 'schedule' && github.event.inputs.nightly != 'true' }} | |
| continue-on-error: true | |
| permissions: | |
| contents: read | |
| actions: read | |
| runs-on: ubuntu-latest | |
| needs: [build] | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Download current manifests | |
| uses: actions/download-artifact@v8 | |
| with: | |
| path: ./manifests/ | |
| pattern: manifest-* | |
| merge-multiple: true | |
| - name: Collect current firmware sizes | |
| run: python3 bin/collect_sizes.py ./manifests/ ./current-sizes.json | |
| - name: Upload size report artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: firmware-sizes-${{ github.sha }} | |
| overwrite: true | |
| path: ./current-sizes.json | |
| retention-days: 90 | |
| - name: Download baseline sizes from develop | |
| if: github.event_name == 'pull_request' | |
| continue-on-error: true | |
| id: baseline-develop | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| RUN_ID=$(gh run list -R "${{ github.repository }}" \ | |
| --workflow CI --branch develop --status success \ | |
| --limit 1 --json databaseId --jq '.[0].databaseId // empty') | |
| if [ -n "$RUN_ID" ]; then | |
| ARTIFACT_NAME=$(gh api "repos/${{ github.repository }}/actions/runs/${RUN_ID}/artifacts" \ | |
| --jq '.artifacts[] | select(.name | startswith("firmware-sizes-")) | select(.expired == false) | .name' | head -1) | |
| if [ -n "$ARTIFACT_NAME" ]; then | |
| gh run download "$RUN_ID" -R "${{ github.repository }}" \ | |
| --name "$ARTIFACT_NAME" --dir ./baseline-develop/ | |
| cp "./baseline-develop/current-sizes.json" ./develop-sizes.json | |
| echo "found=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "found=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| else | |
| echo "found=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Download baseline sizes from master | |
| if: github.event_name == 'pull_request' | |
| continue-on-error: true | |
| id: baseline-master | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| RUN_ID=$(gh run list -R "${{ github.repository }}" \ | |
| --workflow CI --branch master --status success \ | |
| --limit 1 --json databaseId --jq '.[0].databaseId // empty') | |
| if [ -n "$RUN_ID" ]; then | |
| ARTIFACT_NAME=$(gh api "repos/${{ github.repository }}/actions/runs/${RUN_ID}/artifacts" \ | |
| --jq '.artifacts[] | select(.name | startswith("firmware-sizes-")) | select(.expired == false) | .name' | head -1) | |
| if [ -n "$ARTIFACT_NAME" ]; then | |
| gh run download "$RUN_ID" -R "${{ github.repository }}" \ | |
| --name "$ARTIFACT_NAME" --dir ./baseline-master/ | |
| cp "./baseline-master/current-sizes.json" ./master-sizes.json | |
| echo "found=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "found=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| else | |
| echo "found=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Generate size comparison report | |
| if: github.event_name == 'pull_request' | |
| id: report | |
| run: | | |
| ARGS="./current-sizes.json --budgets bin/ram_budgets.json" | |
| if [ -f ./develop-sizes.json ]; then | |
| ARGS="$ARGS --baseline develop:./develop-sizes.json" | |
| fi | |
| if [ -f ./master-sizes.json ]; then | |
| ARGS="$ARGS --baseline master:./master-sizes.json" | |
| fi | |
| REPORT=$(python3 bin/size_report.py $ARGS) | |
| if [ -z "$REPORT" ]; then | |
| echo "has_report=false" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "has_report=true" >> "$GITHUB_OUTPUT" | |
| { | |
| echo '<!-- firmware-size-report -->' | |
| echo '# Firmware Size Report' | |
| echo '' | |
| echo "$REPORT" | |
| echo '' | |
| echo '---' | |
| echo "*Updated for ${{ github.sha }}*" | |
| } > ./size-report.md | |
| cat ./size-report.md >> "$GITHUB_STEP_SUMMARY" | |
| fi | |
| - name: Save PR number | |
| if: github.event_name == 'pull_request' && steps.report.outputs.has_report == 'true' | |
| run: echo "${{ github.event.pull_request.number }}" > ./pr-number.txt | |
| - name: Upload size report | |
| if: github.event_name == 'pull_request' && steps.report.outputs.has_report == 'true' | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: size-report | |
| path: | | |
| ./size-report.md | |
| ./pr-number.txt | |
| retention-days: 5 | |
| # RAM/flash guardrails: fails CI when an env listed in bin/ram_budgets.json | |
| # exceeds its static RAM (.data+.bss) or flash budget. Kept separate from | |
| # firmware-size-report, which is informational and continue-on-error. | |
| size-budget-gate: | |
| if: ${{ github.event_name != 'schedule' && github.event.inputs.nightly != 'true' }} | |
| permissions: | |
| contents: read | |
| actions: read | |
| runs-on: ubuntu-latest | |
| needs: [build] | |
| steps: | |
| - uses: actions/checkout@v7 | |
| # No continue-on-error / empty-dir fallback: the gate must fail closed when | |
| # the data it enforces on cannot be fetched (size_report.py additionally | |
| # fails on missing budgeted envs under --enforce-budgets). | |
| - name: Download current manifests | |
| uses: actions/download-artifact@v8 | |
| with: | |
| path: ./manifests/ | |
| pattern: manifest-* | |
| merge-multiple: true | |
| - name: Collect current firmware sizes | |
| run: python3 bin/collect_sizes.py ./manifests/ ./current-sizes.json | |
| - name: Enforce RAM/flash budgets | |
| run: python3 bin/size_report.py ./current-sizes.json --budgets bin/ram_budgets.json --enforce-budgets | |
| release-artifacts: | |
| permissions: # Needed for 'gh release upload'. | |
| contents: write | |
| runs-on: ubuntu-latest | |
| if: ${{ github.event_name == 'workflow_dispatch' && github.repository == 'meshtastic/firmware' && github.event.inputs.nightly != 'true' }} | |
| outputs: | |
| upload_url: ${{ steps.create_release.outputs.upload_url }} | |
| needs: | |
| - setup | |
| - version | |
| - gather-artifacts | |
| - build-debian-src | |
| - package-pio-deps-native-tft | |
| # - MacOS | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v7 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: 3.x | |
| - name: Generate release notes | |
| id: release_notes | |
| run: | | |
| chmod +x ./bin/generate_release_notes.py | |
| NOTES=$(./bin/generate_release_notes.py ${{ needs.version.outputs.long }} --compare-ref HEAD 2>release_notes.log) | |
| echo "notes<<EOF" >> $GITHUB_OUTPUT | |
| echo "$NOTES" >> $GITHUB_OUTPUT | |
| echo "EOF" >> $GITHUB_OUTPUT | |
| echo "### Release note range" >> $GITHUB_STEP_SUMMARY | |
| cat release_notes.log >> $GITHUB_STEP_SUMMARY | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Create release | |
| uses: softprops/action-gh-release@v3 | |
| id: create_release | |
| with: | |
| draft: true | |
| prerelease: true | |
| name: Meshtastic Firmware ${{ needs.version.outputs.long }} Alpha | |
| tag_name: v${{ needs.version.outputs.long }} | |
| target_commitish: ${{ github.sha }} | |
| body: ${{ steps.release_notes.outputs.notes }} | |
| - name: Download source deb | |
| uses: actions/download-artifact@v8 | |
| with: | |
| pattern: firmware-debian-${{ needs.version.outputs.deb }}~UNRELEASED-src | |
| merge-multiple: true | |
| path: ./output/debian-src | |
| - name: Download `native-tft` pio deps | |
| uses: actions/download-artifact@v8 | |
| with: | |
| pattern: platformio-deps-native-tft-${{ needs.version.outputs.long }} | |
| merge-multiple: true | |
| path: ./output/pio-deps-native-tft | |
| - name: Zip Linux sources | |
| working-directory: output | |
| run: | | |
| zip -j -9 -r ./meshtasticd-${{ needs.version.outputs.deb }}-src.zip ./debian-src | |
| zip -9 -r ./platformio-deps-native-tft-${{ needs.version.outputs.long }}.zip ./pio-deps-native-tft | |
| # For diagnostics | |
| - name: Display structure of downloaded files | |
| run: ls -lR | |
| - name: Generate Release manifest | |
| run: | | |
| jq -n --arg ver "${{ needs.version.outputs.long }}" --argjson targets ${{ toJson(needs.setup.outputs.all) }} '{ | |
| "version": $ver, | |
| "targets": $targets | |
| }' > firmware-${{ needs.version.outputs.long }}.json | |
| - name: Save Release manifest artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: manifest-${{ needs.version.outputs.long }} | |
| overwrite: true | |
| path: firmware-${{ needs.version.outputs.long }}.json | |
| - name: Add sources to GitHub Release | |
| # Only run when targeting master branch with workflow_dispatch | |
| if: ${{ github.ref_name == 'master' }} | |
| run: | | |
| gh release upload v${{ needs.version.outputs.long }} ./firmware-${{ needs.version.outputs.long }}.json | |
| gh release upload v${{ needs.version.outputs.long }} ./output/meshtasticd-${{ needs.version.outputs.deb }}-src.zip | |
| gh release upload v${{ needs.version.outputs.long }} ./output/platformio-deps-native-tft-${{ needs.version.outputs.long }}.zip | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| release-firmware: | |
| permissions: # Needed for 'gh release upload'. | |
| contents: write | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| arch: | |
| - esp32 | |
| - esp32s3 | |
| - esp32c3 | |
| - esp32c6 | |
| - nrf52840 | |
| - rp2040 | |
| - rp2350 | |
| - stm32 | |
| runs-on: ubuntu-latest | |
| if: ${{ github.event_name == 'workflow_dispatch' && github.repository == 'meshtastic/firmware' && github.event.inputs.nightly != 'true' }} | |
| needs: [release-artifacts, version] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v7 | |
| - name: Setup Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: 3.x | |
| - uses: actions/download-artifact@v8 | |
| with: | |
| pattern: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }} | |
| merge-multiple: true | |
| path: ./output | |
| - name: Display structure of downloaded files | |
| run: ls -lR | |
| - name: Device scripts permissions | |
| run: | | |
| chmod +x ./output/device-install.sh || true | |
| chmod +x ./output/device-update.sh || true | |
| - name: Zip firmware | |
| run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output | |
| - uses: actions/download-artifact@v8 | |
| with: | |
| name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }} | |
| merge-multiple: true | |
| path: ./elfs | |
| - name: Zip debug elfs | |
| run: zip -j -9 -r ./debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./elfs | |
| # For diagnostics | |
| - name: Display structure of downloaded files | |
| run: ls -lR | |
| - name: Add bins and debug elfs to GitHub Release | |
| # Only run when targeting master branch with workflow_dispatch | |
| if: ${{ github.ref_name == 'master' }} | |
| run: | | |
| gh release upload v${{ needs.version.outputs.long }} ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip | |
| gh release upload v${{ needs.version.outputs.long }} ./debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| publish-firmware: | |
| runs-on: ubuntu-24.04 | |
| if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.nightly != 'true' }} | |
| needs: [release-firmware, version] | |
| env: | |
| targets: |- | |
| esp32,esp32s3,esp32c3,esp32c6,nrf52840,rp2040,rp2350,stm32 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v7 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: 3.x | |
| - name: Get firmware artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| pattern: firmware-{${{ env.targets }}}-${{ needs.version.outputs.long }} | |
| merge-multiple: true | |
| path: ./publish | |
| - name: Get manifest artifact | |
| uses: actions/download-artifact@v8 | |
| with: | |
| pattern: manifest-${{ needs.version.outputs.long }} | |
| path: ./publish | |
| - name: Generate release notes | |
| run: | | |
| chmod +x ./bin/generate_release_notes.py | |
| ./bin/generate_release_notes.py ${{ needs.version.outputs.long }} --compare-ref HEAD > ./publish/release_notes.md | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Publish firmware to meshtastic.github.io | |
| uses: peaceiris/actions-gh-pages@v4 | |
| env: | |
| # On event/* branches, use the event name as the destination prefix | |
| DEST_PREFIX: ${{ contains(github.ref_name, 'event/') && format('{0}/', github.ref_name) || '' }} | |
| with: | |
| deploy_key: ${{ secrets.DIST_PAGES_DEPLOY_KEY }} | |
| external_repository: meshtastic/meshtastic.github.io | |
| publish_branch: master | |
| publish_dir: ./publish | |
| destination_dir: ${{ env.DEST_PREFIX }}firmware-${{ needs.version.outputs.long }} | |
| keep_files: true | |
| user_name: github-actions[bot] | |
| user_email: github-actions[bot]@users.noreply.github.com | |
| commit_message: ${{ needs.version.outputs.long }} | |
| enable_jekyll: true | |
| # Nightly publish: refresh the single, stable firmware-nightly/ folder on | |
| # meshtastic.github.io with the current develop build. Runs on the cron schedule | |
| # (or a manual nightly=true dispatch) and never creates a GitHub release. The | |
| # folder's release_notes.md is maintained by hand and deliberately left untouched. | |
| publish-nightly: | |
| runs-on: ubuntu-24.04 | |
| if: ${{ (github.event_name == 'schedule' || github.event.inputs.nightly == 'true') && github.repository == 'meshtastic/firmware' }} | |
| needs: [setup, version, gather-artifacts] | |
| env: | |
| targets: |- | |
| esp32,esp32s3,esp32c3,esp32c6,nrf52840,rp2040,rp2350,stm32 | |
| steps: | |
| - name: Get firmware artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| pattern: firmware-{${{ env.targets }}}-${{ needs.version.outputs.long }} | |
| merge-multiple: true | |
| path: ./stage | |
| - name: Generate Release manifest | |
| run: | | |
| jq -n --arg ver "${{ needs.version.outputs.long }}" --argjson targets ${{ toJson(needs.setup.outputs.all) }} '{ | |
| "version": $ver, | |
| "targets": $targets | |
| }' > ./stage/firmware-${{ needs.version.outputs.long }}.json | |
| - name: Generate nightly pointer | |
| run: | | |
| jq -n \ | |
| --arg ver "${{ needs.version.outputs.long }}" \ | |
| --arg sha "${{ github.sha }}" \ | |
| '{version: $ver, id: ("v" + $ver), title: ("Meshtastic Firmware " + $ver + " Nightly"), commit: $sha}' \ | |
| > ./stage/index.json | |
| - name: Preserve manually-maintained release notes | |
| # firmware-nightly/release_notes.md is edited by hand. Carry the current | |
| # copy into ./stage so the keep_files:false publish (which refreshes the | |
| # folder and clears stale nightly binaries) does not drop it. Seed a | |
| # placeholder on the first run (404); fail closed on any other error so a | |
| # transient fetch failure never clobbers the notes. | |
| run: | | |
| set -euo pipefail | |
| url=https://raw.githubusercontent.com/meshtastic/meshtastic.github.io/master/firmware-nightly/release_notes.md | |
| code=$(curl -sSL -o ./stage/release_notes.md -w '%{http_code}' --retry 5 --retry-all-errors "$url" || echo 000) | |
| if [ "$code" = "200" ]; then | |
| echo "Preserved existing release_notes.md" | |
| elif [ "$code" = "404" ]; then | |
| echo "No existing release_notes.md; seeding placeholder" | |
| printf '# Nightly (develop)\n\nAutomated nightly build from the `develop` branch. Edit these notes by hand.\n' > ./stage/release_notes.md | |
| else | |
| echo "Unexpected HTTP $code fetching release_notes.md; refusing to publish to avoid clobbering manual notes" | |
| exit 1 | |
| fi | |
| # For diagnostics | |
| - name: Display structure of files to publish | |
| run: ls -lR ./stage | |
| - name: Publish nightly to meshtastic.github.io | |
| uses: peaceiris/actions-gh-pages@v4 | |
| with: | |
| deploy_key: ${{ secrets.DIST_PAGES_DEPLOY_KEY }} | |
| external_repository: meshtastic/meshtastic.github.io | |
| publish_branch: master | |
| publish_dir: ./stage | |
| # keep_files:false is scoped to destination_dir, so this refreshes only | |
| # firmware-nightly/ (clearing stale nightly binaries) while sibling | |
| # release folders stay untouched; release_notes.md is carried in above. | |
| destination_dir: firmware-nightly | |
| keep_files: false | |
| user_name: github-actions[bot] | |
| user_email: github-actions[bot]@users.noreply.github.com | |
| commit_message: Nightly ${{ needs.version.outputs.long }} | |
| enable_jekyll: true |