Compare commits

..

7 Commits

Author SHA1 Message Date
Thomas Göttgens
f8582885bd Merge branch 'master' into moar-nxp 2025-07-13 18:20:07 +02:00
Thomas Göttgens
974ae821d7 Merge branch 'master' into moar-nxp 2025-03-31 09:44:04 +02:00
Thomas Göttgens
4ba7dc21bb Merge branch 'master' into moar-nxp 2025-03-20 21:37:16 +01:00
Austin
c3e7c7843e Merge branch 'master' into moar-nxp 2025-02-15 09:50:33 -05:00
Thomas Göttgens
ccdecbeae2 Merge branch 'master' into moar-nxp 2025-01-19 22:55:39 +01:00
Jonathan Bennett
03cd38929e Add NXP wire define to rak4631 2025-01-05 11:25:41 +01:00
Jonathan Bennett
a5797aceaa Add SE05X library 2025-01-05 11:25:41 +01:00
901 changed files with 16766 additions and 61422 deletions

View File

@@ -51,7 +51,7 @@ for f in .clusterfuzzlite/*_fuzzer.cpp; do
fuzzer=$(basename "$f" .cpp) fuzzer=$(basename "$f" .cpp)
cp -f "$f" src/fuzzer.cpp cp -f "$f" src/fuzzer.cpp
pio run -vvv --environment "$PIO_ENV" pio run -vvv --environment "$PIO_ENV"
program="$PLATFORMIO_WORKSPACE_DIR/build/$PIO_ENV/meshtasticd" program="$PLATFORMIO_WORKSPACE_DIR/build/$PIO_ENV/program"
cp "$program" "$OUT/$fuzzer" cp "$program" "$OUT/$fuzzer"
# Copy shared libraries used by the fuzzer. # Copy shared libraries used by the fuzzer.

View File

@@ -76,7 +76,7 @@ bool loopCanSleep()
// Called just prior to starting Meshtastic. Allows for setting config values before startup. // Called just prior to starting Meshtastic. Allows for setting config values before startup.
void lateInitVariant() void lateInitVariant()
{ {
portduino_config.logoutputlevel = level_error; settingsMap[logoutputlevel] = level_error;
channelFile.channels[0] = meshtastic_Channel{ channelFile.channels[0] = meshtastic_Channel{
.has_settings = true, .has_settings = true,
.settings = .settings =
@@ -132,7 +132,7 @@ int portduino_main(int argc, char **argv); // Renamed "main" function from Mesht
// Start Meshtastic in a thread and wait till it has reached the ON state. // Start Meshtastic in a thread and wait till it has reached the ON state.
int LLVMFuzzerInitialize(int *argc, char ***argv) int LLVMFuzzerInitialize(int *argc, char ***argv)
{ {
portduino_config.maxtophone = 5; settingsMap[maxtophone] = 5;
meshtasticThread = std::thread([program = *argv[0]]() { meshtasticThread = std::thread([program = *argv[0]]() {
char nodeIdStr[12]; char nodeIdStr[12];

View File

@@ -1,7 +1,7 @@
# trunk-ignore-all(terrascan/AC_DOCKER_0002): Known terrascan issue # trunk-ignore-all(terrascan/AC_DOCKER_0002): Known terrascan issue
# trunk-ignore-all(hadolint/DL3008): Do not pin apt package versions # trunk-ignore-all(hadolint/DL3008): Do not pin apt package versions
# trunk-ignore-all(hadolint/DL3013): Do not pin pip package versions # trunk-ignore-all(hadolint/DL3013): Do not pin pip package versions
FROM mcr.microsoft.com/devcontainers/cpp:2-debian-13 FROM mcr.microsoft.com/devcontainers/cpp:1-debian-12
USER root USER root

View File

@@ -8,7 +8,7 @@
"features": { "features": {
"ghcr.io/devcontainers/features/python:1": { "ghcr.io/devcontainers/features/python:1": {
"installTools": true, "installTools": true,
"version": "3.14" "version": "latest"
} }
}, },
"customizations": { "customizations": {

View File

@@ -2,5 +2,4 @@
self-hosted-runner: self-hosted-runner:
# Labels of self-hosted runner in array of strings. # Labels of self-hosted runner in array of strings.
labels: labels:
- arctastic
- test-runner - test-runner

View File

@@ -100,9 +100,9 @@ runs:
id: version id: version
- name: Store binaries as an artifact - name: Store binaries as an artifact
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
with: with:
name: firmware-${{ inputs.arch }}-${{ inputs.board }}-${{ steps.version.outputs.long }} name: firmware-${{ inputs.arch }}-${{ inputs.board }}-${{ steps.version.outputs.long }}.zip
overwrite: true overwrite: true
path: | path: |
${{ inputs.artifact-paths }} ${{ inputs.artifact-paths }}

View File

@@ -5,12 +5,17 @@ runs:
using: composite using: composite
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v6 uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
ref: ${{github.event.pull_request.head.ref}} ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}} repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Uncomment build epoch
shell: bash
run: |
sed -i 's/#-DBUILD_EPOCH=$UNIX_TIME/-DBUILD_EPOCH=$UNIX_TIME/' platformio.ini
- name: Install dependencies - name: Install dependencies
shell: bash shell: bash
run: | run: |
@@ -18,7 +23,7 @@ runs:
sudo apt-get install -y cppcheck libbluetooth-dev libgpiod-dev libyaml-cpp-dev lsb-release sudo apt-get install -y cppcheck libbluetooth-dev libgpiod-dev libyaml-cpp-dev lsb-release
- name: Setup Python - name: Setup Python
uses: actions/setup-python@v6 uses: actions/setup-python@v5
with: with:
python-version: 3.x python-version: 3.x
cache: pip cache: pip

View File

@@ -24,7 +24,7 @@ jobs:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v6 uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
path: meshtasticd path: meshtasticd
@@ -64,7 +64,7 @@ jobs:
PKG_VERSION: ${{ steps.version.outputs.deb }} PKG_VERSION: ${{ steps.version.outputs.deb }}
- name: Store binaries as an artifact - name: Store binaries as an artifact
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
with: with:
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
overwrite: true overwrite: true

40
.github/workflows/build_esp32.yml vendored Normal file
View File

@@ -0,0 +1,40 @@
name: Build ESP32
on:
workflow_call:
inputs:
board:
required: true
type: string
permissions: read-all
jobs:
build-esp32:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Get release version string
shell: bash
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- name: Build ESP32
id: build
uses: meshtastic/gh-action-firmware@main
with:
pio_platform: esp32
pio_env: ${{ inputs.board }}
pio_target: build
ota_firmware_source: firmware.bin
ota_firmware_target: release/bleota.bin
- name: Store binaries as an artifact
uses: actions/upload-artifact@v4
with:
name: firmware-esp32-${{ inputs.board }}-${{ steps.version.outputs.long }}.zip
overwrite: true
path: |
release/*.bin
release/*.elf

40
.github/workflows/build_esp32_c3.yml vendored Normal file
View File

@@ -0,0 +1,40 @@
name: Build ESP32-C3
on:
workflow_call:
inputs:
board:
required: true
type: string
permissions: read-all
jobs:
build-esp32-c3:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Get release version string
shell: bash
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- name: Build ESP32-C3
id: build
uses: meshtastic/gh-action-firmware@main
with:
pio_platform: esp32
pio_env: ${{ inputs.board }}
pio_target: build
ota_firmware_source: firmware-c3.bin
ota_firmware_target: release/bleota-c3.bin
- name: Store binaries as an artifact
uses: actions/upload-artifact@v4
with:
name: firmware-esp32c3-${{ inputs.board }}-${{ steps.version.outputs.long }}.zip
overwrite: true
path: |
release/*.bin
release/*.elf

40
.github/workflows/build_esp32_c6.yml vendored Normal file
View File

@@ -0,0 +1,40 @@
name: Build ESP32-C6
on:
workflow_call:
inputs:
board:
required: true
type: string
permissions: read-all
jobs:
build-esp32-c6:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Get release version string
shell: bash
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- name: Build ESP32-C6
id: build
uses: meshtastic/gh-action-firmware@main
with:
pio_platform: esp32
pio_env: ${{ inputs.board }}
pio_target: build
ota_firmware_source: firmware-c3.bin
ota_firmware_target: release/bleota-c3.bin
- name: Store binaries as an artifact
uses: actions/upload-artifact@v4
with:
name: firmware-esp32c6-${{ inputs.board }}-${{ steps.version.outputs.long }}.zip
overwrite: true
path: |
release/*.bin
release/*.elf

40
.github/workflows/build_esp32_s3.yml vendored Normal file
View File

@@ -0,0 +1,40 @@
name: Build ESP32-S3
on:
workflow_call:
inputs:
board:
required: true
type: string
permissions: read-all
jobs:
build-esp32-s3:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Get release version string
shell: bash
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- name: Build ESP32-S3
id: build
uses: meshtastic/gh-action-firmware@main
with:
pio_platform: esp32
pio_env: ${{ inputs.board }}
pio_target: build
ota_firmware_source: firmware-s3.bin
ota_firmware_target: release/bleota-s3.bin
- name: Store binaries as an artifact
uses: actions/upload-artifact@v4
with:
name: firmware-esp32s3-${{ inputs.board }}-${{ steps.version.outputs.long }}.zip
overwrite: true
path: |
release/*.bin
release/*.elf

View File

@@ -1,84 +0,0 @@
name: Build
on:
workflow_call:
inputs:
version:
required: true
type: string
platform:
required: true
type: string
pio_env:
required: true
type: string
permissions: read-all
jobs:
pio-build:
name: build-${{ inputs.platform }}
# Use 'arctastic' self-hosted runner pool when building in the main repo
runs-on: ${{ github.repository_owner == 'meshtastic' && 'arctastic' || 'ubuntu-latest' }}
outputs:
artifact-id: ${{ steps.upload.outputs.artifact-id }}
steps:
- uses: actions/checkout@v6
with:
submodules: recursive
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Set OTA firmware source and target
if: startsWith(inputs.platform, 'esp32')
id: ota_dir
env:
PIO_PLATFORM: ${{ inputs.platform }}
run: |
if [ "$PIO_PLATFORM" = "esp32s3" ]; then
echo "src=firmware-s3.bin" >> $GITHUB_OUTPUT
echo "tgt=release/bleota-s3.bin" >> $GITHUB_OUTPUT
elif [ "$PIO_PLATFORM" = "esp32c3" ] || [ "$PIO_PLATFORM" = "esp32c6" ]; then
echo "src=firmware-c3.bin" >> $GITHUB_OUTPUT
echo "tgt=release/bleota-c3.bin" >> $GITHUB_OUTPUT
elif [ "$PIO_PLATFORM" = "esp32" ]; then
echo "src=firmware.bin" >> $GITHUB_OUTPUT
echo "tgt=release/bleota.bin" >> $GITHUB_OUTPUT
fi
- name: Build ${{ inputs.platform }}
id: build
uses: meshtastic/gh-action-firmware@main
with:
pio_platform: ${{ inputs.platform }}
pio_env: ${{ inputs.pio_env }}
pio_target: build
ota_firmware_source: ${{ steps.ota_dir.outputs.src || '' }}
ota_firmware_target: ${{ steps.ota_dir.outputs.tgt || '' }}
- name: Echo manifest from release/firmware-*.mt.json to job summary
if: ${{ always() }}
env:
PIO_ENV: ${{ inputs.pio_env }}
run: |
echo "## Manifest: \`$PIO_ENV\`" >> $GITHUB_STEP_SUMMARY
echo '```json' >> $GITHUB_STEP_SUMMARY
cat release/firmware-*.mt.json >> $GITHUB_STEP_SUMMARY
echo '' >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
- name: Store binaries as an artifact
uses: actions/upload-artifact@v5
id: upload
with:
name: firmware-${{ inputs.platform }}-${{ inputs.pio_env }}-${{ inputs.version }}
overwrite: true
path: |
release/*.mt.json
release/*.bin
release/*.elf
release/*.uf2
release/*.hex
release/*.zip
release/device-*.sh
release/device-*.bat

40
.github/workflows/build_nrf52.yml vendored Normal file
View File

@@ -0,0 +1,40 @@
name: Build NRF52
on:
workflow_call:
inputs:
board:
required: true
type: string
permissions: read-all
jobs:
build-nrf52:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Get release version string
shell: bash
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- name: Build NRF52
id: build
uses: meshtastic/gh-action-firmware@main
with:
pio_platform: nrf52
pio_env: ${{ inputs.board }}
pio_target: build
- name: Store binaries as an artifact
uses: actions/upload-artifact@v4
with:
name: firmware-nrf52840-${{ inputs.board }}-${{ steps.version.outputs.long }}.zip
overwrite: true
path: |
release/*.uf2
release/*.elf
release/*.hex
release/*-ota.zip

View File

@@ -1,161 +0,0 @@
name: Build One Target
on:
workflow_dispatch:
inputs:
# trunk-ignore(checkov/CKV_GHA_7)
arch:
type: choice
options:
- esp32
- esp32s3
- esp32c3
- esp32c6
- nrf52840
- rp2040
- rp2350
- stm32
target:
type: string
required: false
description: Choose the target board, e.g. nrf52_promicro_diy_tcxo. If blank, will find available targets.
# find-target:
# type: boolean
# default: true
# description: 'Find the available targets'
permissions: read-all
jobs:
find-targets:
if: ${{ inputs.target == '' }}
strategy:
fail-fast: false
matrix:
arch:
- esp32
- esp32s3
- esp32c3
- esp32c6
- nrf52840
- rp2040
- rp2350
- stm32
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: 3.x
cache: pip
- run: pip install -U platformio
- name: Generate matrix
id: jsonStep
run: |
TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}} --level extra)
echo "Name: $GITHUB_REF_NAME" >> $GITHUB_STEP_SUMMARY
echo "Base: $GITHUB_BASE_REF" >> $GITHUB_STEP_SUMMARY
echo "Arch: ${{matrix.arch}}" >> $GITHUB_STEP_SUMMARY
echo "Ref: $GITHUB_REF" >> $GITHUB_STEP_SUMMARY
echo "Targets:" >> $GITHUB_STEP_SUMMARY
echo $TARGETS | jq -r 'sort_by(.board) |.[] | "- " + .board' >> $GITHUB_STEP_SUMMARY
version:
if: ${{ inputs.target != '' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- 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 }}
build:
if: ${{ inputs.target != '' && inputs.arch != 'native' }}
needs: [version]
uses: ./.github/workflows/build_firmware.yml
with:
version: ${{ needs.version.outputs.long }}
pio_env: ${{ inputs.target }}
platform: ${{ inputs.arch }}
gather-artifacts:
permissions:
contents: write
pull-requests: write
runs-on: ubuntu-latest
needs: [version, build]
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- uses: actions/download-artifact@v6
with:
path: ./
pattern: firmware-*-*
merge-multiple: true
- name: Display structure of downloaded files
run: ls -R
- name: Move files up
run: mv -b -t ./ ./bin/device-*.sh ./bin/device-*.bat
- name: Repackage in single firmware zip
uses: actions/upload-artifact@v5
with:
name: firmware-${{inputs.target}}-${{ needs.version.outputs.long }}
overwrite: true
path: |
./firmware-*.bin
./firmware-*.uf2
./firmware-*.hex
./firmware-*.zip
./device-*.sh
./device-*.bat
./littlefs-*.bin
./bleota*bin
./Meshtastic_nRF52_factory_erase*.uf2
retention-days: 30
- uses: actions/download-artifact@v6
with:
pattern: firmware-*-${{ 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-${{inputs.target}}-${{ needs.version.outputs.long }}.zip ./output
- name: Repackage in single elfs zip
uses: actions/upload-artifact@v5
with:
name: debug-elfs-${{inputs.target}}-${{ needs.version.outputs.long }}.zip
overwrite: true
path: ./*.elf
retention-days: 30
- uses: scruplelesswizard/comment-artifact@main
if: ${{ github.event_name == 'pull_request' }}
with:
name: firmware-${{inputs.target}}-${{ needs.version.outputs.long }}
description: "Download firmware-${{inputs.target}}-${{ needs.version.outputs.long }}.zip. This artifact will be available for 90 days from creation"
github-token: ${{ secrets.GITHUB_TOKEN }}

38
.github/workflows/build_rpi2040.yml vendored Normal file
View File

@@ -0,0 +1,38 @@
name: Build RPI2040
on:
workflow_call:
inputs:
board:
required: true
type: string
permissions: read-all
jobs:
build-rpi2040:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Get release version string
shell: bash
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- name: Build Raspberry Pi 2040
id: build
uses: meshtastic/gh-action-firmware@main
with:
pio_platform: rp2xx0
pio_env: ${{ inputs.board }}
pio_target: build
- name: Store binaries as an artifact
uses: actions/upload-artifact@v4
with:
name: firmware-rp2040-${{ inputs.board }}-${{ steps.version.outputs.long }}.zip
overwrite: true
path: |
release/*.uf2
release/*.elf

39
.github/workflows/build_stm32.yml vendored Normal file
View File

@@ -0,0 +1,39 @@
name: Build STM32
on:
workflow_call:
inputs:
board:
required: true
type: string
permissions: read-all
jobs:
build-stm32:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Get release version string
shell: bash
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- name: Build STM32WL
id: build
uses: meshtastic/gh-action-firmware@main
with:
pio_platform: stm32wl
pio_env: ${{ inputs.board }}
pio_target: build
- name: Store binaries as an artifact
uses: actions/upload-artifact@v4
with:
name: firmware-stm32-${{ inputs.board }}-${{ steps.version.outputs.long }}.zip
overwrite: true
path: |
release/*.hex
release/*.bin
release/*.elf

View File

@@ -21,22 +21,16 @@ permissions:
jobs: jobs:
docker-multiarch: docker-multiarch:
if: github.repository == 'meshtastic/firmware'
uses: ./.github/workflows/docker_manifest.yml uses: ./.github/workflows/docker_manifest.yml
with: with:
release_channel: daily release_channel: daily
secrets: inherit secrets: inherit
package-ppa: package-ppa:
if: github.repository == 'meshtastic/firmware'
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
series: series: [plucky, noble, jammy]
- jammy # 22.04 LTS
- noble # 24.04 LTS
- plucky # 25.04
- questing # 25.10
uses: ./.github/workflows/package_ppa.yml uses: ./.github/workflows/package_ppa.yml
with: with:
ppa_repo: ppa:meshtastic/daily ppa_repo: ppa:meshtastic/daily
@@ -44,7 +38,6 @@ jobs:
secrets: inherit secrets: inherit
package-obs: package-obs:
if: github.repository == 'meshtastic/firmware'
uses: ./.github/workflows/package_obs.yml uses: ./.github/workflows/package_obs.yml
with: with:
obs_project: network:Meshtastic:daily obs_project: network:Meshtastic:daily
@@ -52,7 +45,6 @@ jobs:
secrets: inherit secrets: inherit
hook-copr: hook-copr:
if: github.repository == 'meshtastic/firmware'
uses: ./.github/workflows/hook_copr.yml uses: ./.github/workflows/hook_copr.yml
with: with:
copr_project: daily copr_project: daily

View File

@@ -47,7 +47,7 @@ jobs:
runs-on: ${{ inputs.runs-on }} runs-on: ${{ inputs.runs-on }}
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v6 uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
ref: ${{github.event.pull_request.head.ref}} ref: ${{github.event.pull_request.head.ref}}

View File

@@ -83,7 +83,7 @@ jobs:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v6 uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
ref: ${{github.event.pull_request.head.ref}} ref: ${{github.event.pull_request.head.ref}}

View File

@@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v6 uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
ref: ${{ github.ref }} ref: ${{ github.ref }}

View File

@@ -3,7 +3,7 @@ concurrency:
group: ci-${{ github.head_ref || github.run_id }} group: ci-${{ github.head_ref || github.run_id }}
cancel-in-progress: true cancel-in-progress: true
on: on:
# # Triggers the workflow on push but only for the main branches # # Triggers the workflow on push but only for the master branch
push: push:
branches: branches:
- master - master
@@ -28,77 +28,111 @@ on:
jobs: jobs:
setup: setup:
strategy: strategy:
fail-fast: true fail-fast: false
matrix: matrix:
arch: arch: [esp32, esp32s3, esp32c3, esp32c6, nrf52840, rp2040, stm32, check]
- all runs-on: ubuntu-latest
- check
runs-on: ubuntu-24.04
steps: steps:
- uses: actions/checkout@v6 - id: checkout
- uses: actions/setup-python@v6 uses: actions/checkout@v4
with: name: Checkout base
python-version: 3.x - id: jsonStep
cache: pip
- run: pip install -U platformio
- name: Generate matrix
id: jsonStep
run: | run: |
if [[ "$GITHUB_HEAD_REF" == "" ]]; then if [[ "$GITHUB_HEAD_REF" == "" ]]; then
TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}}) TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}})
else else
TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}} --level pr) TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}} quick)
fi fi
echo "Name: $GITHUB_REF_NAME Base: $GITHUB_BASE_REF Ref: $GITHUB_REF" echo "Name: $GITHUB_REF_NAME Base: $GITHUB_BASE_REF Ref: $GITHUB_REF Targets: $TARGETS"
echo "${{matrix.arch}}=$TARGETS" >> $GITHUB_OUTPUT echo "${{matrix.arch}}=$(jq -cn --argjson environments "$TARGETS" '{board: $environments}')" >> $GITHUB_OUTPUT
echo "$TARGETS" >> $GITHUB_STEP_SUMMARY
outputs: outputs:
all: ${{ steps.jsonStep.outputs.all }} esp32: ${{ steps.jsonStep.outputs.esp32 }}
esp32s3: ${{ steps.jsonStep.outputs.esp32s3 }}
esp32c3: ${{ steps.jsonStep.outputs.esp32c3 }}
esp32c6: ${{ steps.jsonStep.outputs.esp32c6 }}
nrf52840: ${{ steps.jsonStep.outputs.nrf52840 }}
rp2040: ${{ steps.jsonStep.outputs.rp2040 }}
stm32: ${{ steps.jsonStep.outputs.stm32 }}
check: ${{ steps.jsonStep.outputs.check }} check: ${{ steps.jsonStep.outputs.check }}
version:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- 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: check:
needs: setup needs: setup
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix: ${{ fromJson(needs.setup.outputs.check) }}
check: ${{ fromJson(needs.setup.outputs.check) }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: ${{ github.event_name != 'workflow_dispatch' && github.repository == 'meshtastic/firmware' }} if: ${{ github.event_name != 'workflow_dispatch' }}
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v4
- name: Build base - name: Build base
id: base id: base
uses: ./.github/actions/setup-base uses: ./.github/actions/setup-base
- name: Check ${{ matrix.check.board }} - name: Check ${{ matrix.board }}
run: bin/check-all.sh ${{ matrix.check.board }} run: bin/check-all.sh ${{ matrix.board }}
build: build-esp32:
needs: [setup, version] needs: setup
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix: ${{ fromJson(needs.setup.outputs.esp32) }}
build: ${{ fromJson(needs.setup.outputs.all) }} uses: ./.github/workflows/build_esp32.yml
uses: ./.github/workflows/build_firmware.yml
with: with:
version: ${{ needs.version.outputs.long }} board: ${{ matrix.board }}
pio_env: ${{ matrix.build.board }}
platform: ${{ matrix.build.platform }} build-esp32-s3:
needs: setup
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.setup.outputs.esp32s3) }}
uses: ./.github/workflows/build_esp32_s3.yml
with:
board: ${{ matrix.board }}
build-esp32-c3:
needs: setup
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.setup.outputs.esp32c3) }}
uses: ./.github/workflows/build_esp32_c3.yml
with:
board: ${{ matrix.board }}
build-esp32-c6:
needs: setup
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.setup.outputs.esp32c6) }}
uses: ./.github/workflows/build_esp32_c6.yml
with:
board: ${{ matrix.board }}
build-nrf52:
needs: setup
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.setup.outputs.nrf52840) }}
uses: ./.github/workflows/build_nrf52.yml
with:
board: ${{ matrix.board }}
build-rpi2040:
needs: setup
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.setup.outputs.rp2040) }}
uses: ./.github/workflows/build_rpi2040.yml
with:
board: ${{ matrix.board }}
build-stm32:
needs: setup
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.setup.outputs.stm32) }}
uses: ./.github/workflows/build_stm32.yml
with:
board: ${{ matrix.board }}
build-debian-src: build-debian-src:
if: github.repository == 'meshtastic/firmware' if: github.repository == 'meshtastic/firmware'
@@ -109,66 +143,93 @@ jobs:
secrets: inherit secrets: inherit
package-pio-deps-native-tft: package-pio-deps-native-tft:
if: ${{ github.repository == 'meshtastic/firmware' && github.event_name == 'workflow_dispatch' }} if: ${{ github.event_name == 'workflow_dispatch' }}
uses: ./.github/workflows/package_pio_deps.yml uses: ./.github/workflows/package_pio_deps.yml
with: with:
pio_env: native-tft pio_env: native-tft
secrets: inherit secrets: inherit
test-native: test-native:
if: ${{ !contains(github.ref_name, 'event/') && github.repository == 'meshtastic/firmware' }} if: ${{ !contains(github.ref_name, 'event/') }}
uses: ./.github/workflows/test_native.yml uses: ./.github/workflows/test_native.yml
docker: docker-deb-amd64:
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 uses: ./.github/workflows/docker_build.yml
with: with:
distro: ${{ matrix.distro }} distro: debian
platform: ${{ matrix.platform }} platform: linux/amd64
runs-on: ${{ contains(matrix.platform, 'arm') && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }} runs-on: ubuntu-24.04
pio_env: ${{ matrix.pio_env }} push: false
docker-deb-amd64-tft:
uses: ./.github/workflows/docker_build.yml
with:
distro: debian
platform: linux/amd64
runs-on: ubuntu-24.04
push: false
pio_env: native-tft
docker-alp-amd64:
uses: ./.github/workflows/docker_build.yml
with:
distro: alpine
platform: linux/amd64
runs-on: ubuntu-24.04
push: false
docker-alp-amd64-tft:
uses: ./.github/workflows/docker_build.yml
with:
distro: alpine
platform: linux/amd64
runs-on: ubuntu-24.04
push: false
pio_env: native-tft
docker-deb-arm64:
uses: ./.github/workflows/docker_build.yml
with:
distro: debian
platform: linux/arm64
runs-on: ubuntu-24.04-arm
push: false
docker-deb-armv7:
uses: ./.github/workflows/docker_build.yml
with:
distro: debian
platform: linux/arm/v7
runs-on: ubuntu-24.04-arm
push: false push: false
gather-artifacts: gather-artifacts:
# trunk-ignore(checkov/CKV2_GHA_1)
if: github.repository == 'meshtastic/firmware'
permissions: permissions:
contents: write contents: write
pull-requests: write pull-requests: write
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
arch: arch: [esp32, esp32s3, esp32c3, esp32c6, nrf52840, rp2040, stm32]
- esp32
- esp32s3
- esp32c3
- esp32c6
- nrf52840
- rp2040
- rp2350
- stm32
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [version, build] needs:
[
build-esp32,
build-esp32-s3,
build-esp32-c3,
build-esp32-c6,
build-nrf52,
build-rpi2040,
build-stm32,
]
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v6 uses: actions/checkout@v4
with: with:
ref: ${{github.event.pull_request.head.ref}} ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}} repository: ${{github.event.pull_request.head.repo.full_name}}
- uses: actions/download-artifact@v6 - uses: actions/download-artifact@v4
with: with:
path: ./ path: ./
pattern: firmware-${{matrix.arch}}-* pattern: firmware-${{matrix.arch}}-*
@@ -177,17 +238,23 @@ jobs:
- name: Display structure of downloaded files - name: Display structure of downloaded files
run: ls -R run: ls -R
- name: Get release version string
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- name: Move files up
run: mv -b -t ./ ./bin/device-*.sh ./bin/device-*.bat
- name: Repackage in single firmware zip - name: Repackage in single firmware zip
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
with: with:
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }} name: firmware-${{matrix.arch}}-${{ steps.version.outputs.long }}
overwrite: true overwrite: true
path: | path: |
./firmware-*.mt.json
./firmware-*.bin ./firmware-*.bin
./firmware-*.uf2 ./firmware-*.uf2
./firmware-*.hex ./firmware-*.hex
./firmware-*.zip ./firmware-*-ota.zip
./device-*.sh ./device-*.sh
./device-*.bat ./device-*.bat
./littlefs-*.bin ./littlefs-*.bin
@@ -195,9 +262,9 @@ jobs:
./Meshtastic_nRF52_factory_erase*.uf2 ./Meshtastic_nRF52_factory_erase*.uf2
retention-days: 30 retention-days: 30
- uses: actions/download-artifact@v6 - uses: actions/download-artifact@v4
with: with:
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }} name: firmware-${{matrix.arch}}-${{ steps.version.outputs.long }}
merge-multiple: true merge-multiple: true
path: ./output path: ./output
@@ -207,16 +274,16 @@ jobs:
- name: Device scripts permissions - name: Device scripts permissions
run: | run: |
chmod +x ./output/device-install.sh || true chmod +x ./output/device-install.sh
chmod +x ./output/device-update.sh || true chmod +x ./output/device-update.sh
- name: Zip firmware - name: Zip firmware
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ steps.version.outputs.long }}.zip ./output
- name: Repackage in single elfs zip - name: Repackage in single elfs zip
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
with: with:
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }} name: debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.long }}.zip
overwrite: true overwrite: true
path: ./*.elf path: ./*.elf
retention-days: 30 retention-days: 30
@@ -224,24 +291,35 @@ jobs:
- uses: scruplelesswizard/comment-artifact@main - uses: scruplelesswizard/comment-artifact@main
if: ${{ github.event_name == 'pull_request' }} if: ${{ github.event_name == 'pull_request' }}
with: with:
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }} name: firmware-${{matrix.arch}}-${{ steps.version.outputs.long }}
description: "Download firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip. This artifact will be available for 90 days from creation" description: "Download firmware-${{matrix.arch}}-${{ steps.version.outputs.long }}.zip. This artifact will be available for 90 days from creation"
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }}
release-artifacts: release-artifacts:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: ${{ github.event_name == 'workflow_dispatch' && github.repository == 'meshtastic/firmware' }} if: ${{ github.event_name == 'workflow_dispatch' }}
outputs: outputs:
upload_url: ${{ steps.create_release.outputs.upload_url }} upload_url: ${{ steps.create_release.outputs.upload_url }}
needs: needs:
- setup
- version
- gather-artifacts - gather-artifacts
- build-debian-src - build-debian-src
- package-pio-deps-native-tft - package-pio-deps-native-tft
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: 3.x
- 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
- name: Create release - name: Create release
uses: softprops/action-gh-release@v2 uses: softprops/action-gh-release@v2
@@ -249,56 +327,41 @@ jobs:
with: with:
draft: true draft: true
prerelease: true prerelease: true
name: Meshtastic Firmware ${{ needs.version.outputs.long }} Alpha name: Meshtastic Firmware ${{ steps.version.outputs.long }} Alpha
tag_name: v${{ needs.version.outputs.long }} tag_name: v${{ steps.version.outputs.long }}
body: | body: |
Autogenerated by github action, developer should edit as required before publishing... Autogenerated by github action, developer should edit as required before publishing...
- name: Download source deb - name: Download source deb
uses: actions/download-artifact@v6 uses: actions/download-artifact@v4
with: with:
pattern: firmware-debian-${{ needs.version.outputs.deb }}~UNRELEASED-src pattern: firmware-debian-${{ steps.version.outputs.deb }}~UNRELEASED-src
merge-multiple: true merge-multiple: true
path: ./output/debian-src path: ./output/debian-src
- name: Download `native-tft` pio deps - name: Download `native-tft` pio deps
uses: actions/download-artifact@v6 uses: actions/download-artifact@v4
with: with:
pattern: platformio-deps-native-tft-${{ needs.version.outputs.long }} pattern: platformio-deps-native-tft-${{ steps.version.outputs.long }}
merge-multiple: true merge-multiple: true
path: ./output/pio-deps-native-tft path: ./output/pio-deps-native-tft
- name: Zip Linux sources - name: Zip Linux sources
working-directory: output working-directory: output
run: | run: |
zip -j -9 -r ./meshtasticd-${{ needs.version.outputs.deb }}-src.zip ./debian-src zip -j -9 -r ./meshtasticd-${{ steps.version.outputs.deb }}-src.zip ./debian-src
zip -9 -r ./platformio-deps-native-tft-${{ needs.version.outputs.long }}.zip ./pio-deps-native-tft zip -9 -r ./platformio-deps-native-tft-${{ steps.version.outputs.long }}.zip ./pio-deps-native-tft
# For diagnostics # For diagnostics
- name: Display structure of downloaded files - name: Display structure of downloaded files
run: ls -lR run: ls -lR
- name: Generate Release manifest - name: Add Linux sources to GtiHub Release
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@v5
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 # Only run when targeting master branch with workflow_dispatch
if: ${{ github.ref_name == 'master' }} if: ${{ github.ref_name == 'master' }}
run: | run: |
gh release upload v${{ needs.version.outputs.long }} ./firmware-${{ needs.version.outputs.long }}.json gh release upload v${{ steps.version.outputs.long }} ./output/meshtasticd-${{ steps.version.outputs.deb }}-src.zip
gh release upload v${{ needs.version.outputs.long }} ./output/meshtasticd-${{ needs.version.outputs.deb }}-src.zip gh release upload v${{ steps.version.outputs.long }} ./output/platformio-deps-native-tft-${{ steps.version.outputs.long }}.zip
gh release upload v${{ needs.version.outputs.long }} ./output/platformio-deps-native-tft-${{ needs.version.outputs.long }}.zip
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -306,30 +369,26 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
arch: arch: [esp32, esp32s3, esp32c3, esp32c6, nrf52840, rp2040, stm32]
- esp32
- esp32s3
- esp32c3
- esp32c6
- nrf52840
- rp2040
- rp2350
- stm32
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: ${{ github.event_name == 'workflow_dispatch' && github.repository == 'meshtastic/firmware'}} if: ${{ github.event_name == 'workflow_dispatch' }}
needs: [release-artifacts, version] needs: [release-artifacts]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v4
- name: Setup Python - name: Setup Python
uses: actions/setup-python@v6 uses: actions/setup-python@v5
with: with:
python-version: 3.x python-version: 3.x
- uses: actions/download-artifact@v6 - name: Get release version string
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- uses: actions/download-artifact@v4
with: with:
pattern: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }} pattern: firmware-${{matrix.arch}}-${{ steps.version.outputs.long }}
merge-multiple: true merge-multiple: true
path: ./output path: ./output
@@ -338,20 +397,20 @@ jobs:
- name: Device scripts permissions - name: Device scripts permissions
run: | run: |
chmod +x ./output/device-install.sh || true chmod +x ./output/device-install.sh
chmod +x ./output/device-update.sh || true chmod +x ./output/device-update.sh
- name: Zip firmware - name: Zip firmware
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ steps.version.outputs.long }}.zip ./output
- uses: actions/download-artifact@v6 - uses: actions/download-artifact@v4
with: with:
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }} name: debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.long }}.zip
merge-multiple: true merge-multiple: true
path: ./elfs path: ./elfs
- name: Zip debug elfs - name: Zip debug elfs
run: zip -j -9 -r ./debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./elfs run: zip -j -9 -r ./debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.long }}.zip ./elfs
# For diagnostics # For diagnostics
- name: Display structure of downloaded files - name: Display structure of downloaded files
@@ -361,38 +420,34 @@ jobs:
# Only run when targeting master branch with workflow_dispatch # Only run when targeting master branch with workflow_dispatch
if: ${{ github.ref_name == 'master' }} if: ${{ github.ref_name == 'master' }}
run: | run: |
gh release upload v${{ needs.version.outputs.long }} ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip gh release upload v${{ steps.version.outputs.long }} ./firmware-${{matrix.arch}}-${{ steps.version.outputs.long }}.zip
gh release upload v${{ needs.version.outputs.long }} ./debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip gh release upload v${{ steps.version.outputs.long }} ./debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.long }}.zip
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
publish-firmware: publish-firmware:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
if: ${{ github.event_name == 'workflow_dispatch' }} if: ${{ github.event_name == 'workflow_dispatch' }}
needs: [release-firmware, version] needs: [release-firmware]
env: env:
targets: |- targets: esp32,esp32s3,esp32c3,esp32c6,nrf52840,rp2040,stm32
esp32,esp32s3,esp32c3,esp32c6,nrf52840,rp2040,rp2350,stm32
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v4
- name: Setup Python - name: Setup Python
uses: actions/setup-python@v6 uses: actions/setup-python@v5
with: with:
python-version: 3.x python-version: 3.x
- name: Get firmware artifacts - name: Get release version string
uses: actions/download-artifact@v6 run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
with: id: version
pattern: firmware-{${{ env.targets }}}-${{ needs.version.outputs.long }}
merge-multiple: true
path: ./publish
- name: Get manifest artifact - uses: actions/download-artifact@v4
uses: actions/download-artifact@v6
with: with:
pattern: manifest-${{ needs.version.outputs.long }} pattern: firmware-{${{ env.targets }}}-${{ steps.version.outputs.long }}
merge-multiple: true
path: ./publish path: ./publish
- name: Publish firmware to meshtastic.github.io - name: Publish firmware to meshtastic.github.io
@@ -405,9 +460,9 @@ jobs:
external_repository: meshtastic/meshtastic.github.io external_repository: meshtastic/meshtastic.github.io
publish_branch: master publish_branch: master
publish_dir: ./publish publish_dir: ./publish
destination_dir: ${{ env.DEST_PREFIX }}firmware-${{ needs.version.outputs.long }} destination_dir: ${{ env.DEST_PREFIX }}firmware-${{ steps.version.outputs.long }}
keep_files: true keep_files: true
user_name: github-actions[bot] user_name: github-actions[bot]
user_email: github-actions[bot]@users.noreply.github.com user_email: github-actions[bot]@users.noreply.github.com
commit_message: ${{ needs.version.outputs.long }} commit_message: ${{ steps.version.outputs.long }}
enable_jekyll: true enable_jekyll: true

View File

@@ -1,371 +0,0 @@
name: Merge Queue
# Not sure how concurrency works in merge_queue, removing for now.
# concurrency:
# group: merge-queue-${{ github.head_ref || github.run_id }}
# cancel-in-progress: true
on:
# Merge group is a special trigger that is used to trigger the workflow when a merge group is created.
merge_group:
jobs:
setup:
strategy:
fail-fast: true
matrix:
arch:
- all
- check
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
- 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
outputs:
all: ${{ steps.jsonStep.outputs.all }}
check: ${{ steps.jsonStep.outputs.check }}
version:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- 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: true
matrix:
check: ${{ fromJson(needs.setup.outputs.check) }}
runs-on: ubuntu-latest
if: ${{ github.event_name != 'workflow_dispatch' }}
steps:
- uses: actions/checkout@v6
- name: Build base
id: base
uses: ./.github/actions/setup-base
- name: Check ${{ matrix.check.board }}
run: bin/check-all.sh ${{ matrix.check.board }}
build:
needs: [setup, version]
strategy:
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'
uses: ./.github/workflows/build_debian_src.yml
with:
series: UNRELEASED
build_location: local
secrets: inherit
package-pio-deps-native-tft:
if: ${{ 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/') }}
uses: ./.github/workflows/test_native.yml
docker:
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)
permissions:
contents: write
pull-requests: write
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@v6
with:
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- uses: actions/download-artifact@v6
with:
path: ./
pattern: firmware-${{matrix.arch}}-*
merge-multiple: true
- name: Display structure of downloaded files
run: ls -R
- name: Move files up
run: mv -b -t ./ ./bin/device-*.sh ./bin/device-*.bat
- name: Repackage in single firmware zip
uses: actions/upload-artifact@v5
with:
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
overwrite: true
path: |
./firmware-*.bin
./firmware-*.uf2
./firmware-*.hex
./firmware-*.zip
./device-*.sh
./device-*.bat
./littlefs-*.bin
./bleota*bin
./Meshtastic_nRF52_factory_erase*.uf2
retention-days: 30
- uses: actions/download-artifact@v6
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@v5
with:
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}
overwrite: true
path: ./*.elf
retention-days: 30
- uses: scruplelesswizard/comment-artifact@main
if: ${{ github.event_name == 'pull_request' }}
with:
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
description: "Download firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip. This artifact will be available for 90 days from creation"
github-token: ${{ secrets.GITHUB_TOKEN }}
release-artifacts:
runs-on: ubuntu-latest
if: ${{ github.event_name == 'workflow_dispatch' }}
outputs:
upload_url: ${{ steps.create_release.outputs.upload_url }}
needs:
- version
- gather-artifacts
- build-debian-src
- package-pio-deps-native-tft
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Create release
uses: softprops/action-gh-release@v2
id: create_release
with:
draft: true
prerelease: true
name: Meshtastic Firmware ${{ needs.version.outputs.long }} Alpha
tag_name: v${{ needs.version.outputs.long }}
body: |
Autogenerated by github action, developer should edit as required before publishing...
- name: Download source deb
uses: actions/download-artifact@v6
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@v6
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: Add Linux sources to GtiHub Release
# Only run when targeting master branch with workflow_dispatch
if: ${{ github.ref_name == 'master' }}
run: |
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:
strategy:
fail-fast: false
matrix:
arch:
- esp32
- esp32s3
- esp32c3
- esp32c6
- nrf52840
- rp2040
- rp2350
- stm32
runs-on: ubuntu-latest
if: ${{ github.event_name == 'workflow_dispatch' }}
needs: [release-artifacts, version]
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: 3.x
- uses: actions/download-artifact@v6
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@v6
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' }}
needs: [release-firmware, version]
env:
targets: |-
esp32,esp32s3,esp32c3,esp32c6,nrf52840,rp2040,rp2350,stm32
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: 3.x
- uses: actions/download-artifact@v6
with:
pattern: firmware-{${{ env.targets }}}-${{ needs.version.outputs.long }}
merge-multiple: true
path: ./publish
- 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

View File

@@ -14,7 +14,7 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v4
- name: Trunk Check - name: Trunk Check
uses: trunk-io/trunk-action@v1 uses: trunk-io/trunk-action@v1
@@ -31,7 +31,7 @@ jobs:
pull-requests: write # For trunk to create PRs pull-requests: write # For trunk to create PRs
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v4
- name: Trunk Upgrade - name: Trunk Upgrade
uses: trunk-io/trunk-action/upgrade@v1 uses: trunk-io/trunk-action/upgrade@v1

View File

@@ -34,7 +34,7 @@ jobs:
needs: build-debian-src needs: build-debian-src
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v6 uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
path: meshtasticd path: meshtasticd
@@ -58,7 +58,7 @@ jobs:
id: version id: version
- name: Download artifacts - name: Download artifacts
uses: actions/download-artifact@v6 uses: actions/download-artifact@v4
with: with:
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
merge-multiple: true merge-multiple: true

View File

@@ -24,14 +24,14 @@ jobs:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v6 uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
ref: ${{github.event.pull_request.head.ref}} ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}} repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Setup Python - name: Setup Python
uses: actions/setup-python@v6 uses: actions/setup-python@v5
with: with:
python-version: 3.x python-version: 3.x
@@ -56,7 +56,7 @@ jobs:
PLATFORMIO_CORE_DIR: pio/core PLATFORMIO_CORE_DIR: pio/core
- name: Store binaries as an artifact - name: Store binaries as an artifact
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
with: with:
name: platformio-deps-${{ inputs.pio_env }}-${{ steps.version.outputs.long }} name: platformio-deps-${{ inputs.pio_env }}-${{ steps.version.outputs.long }}
overwrite: true overwrite: true

View File

@@ -32,7 +32,7 @@ jobs:
needs: build-debian-src needs: build-debian-src
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v6 uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
path: meshtasticd path: meshtasticd
@@ -60,7 +60,7 @@ jobs:
id: version id: version
- name: Download artifacts - name: Download artifacts
uses: actions/download-artifact@v6 uses: actions/download-artifact@v4
with: with:
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
merge-multiple: true merge-multiple: true

View File

@@ -1,24 +0,0 @@
name: Check PR Labels
on:
pull_request:
types: [opened, edited, labeled, unlabeled, synchronize, reopened]
permissions:
pull-requests: read
contents: read
jobs:
check-label:
runs-on: ubuntu-latest
steps:
- name: Check for PR labels
uses: actions/github-script@v8
with:
script: |
const labels = context.payload.pull_request.labels.map(label => label.name);
const requiredLabels = ['bugfix', 'enhancement', 'hardware-support', 'dependencies', 'submodules', 'github_actions', 'trunk', 'cleanup'];
const hasRequiredLabel = labels.some(label => requiredLabels.includes(label));
if (!hasRequiredLabel) {
core.setFailed(`PR must have at least one of the following labels before it can be merged: ${requiredLabels.join(', ')}.`);
}

View File

@@ -1,238 +0,0 @@
name: Tests
# DISABLED: Changed from automatic PR triggers to manual only
on:
workflow_dispatch:
inputs:
reason:
description: "Reason for manual test run"
required: false
default: "Manual test execution"
concurrency:
group: tests-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
permissions:
contents: read
actions: read
checks: write
pull-requests: write
jobs:
native-tests:
name: "🧪 Native Tests"
if: github.repository == 'meshtastic/firmware'
uses: ./.github/workflows/test_native.yml
permissions:
contents: read
actions: read
checks: write
test-summary:
name: "📊 Test Results"
runs-on: ubuntu-latest
needs: [native-tests]
if: always()
permissions:
contents: read
actions: read
checks: write
pull-requests: write
steps:
- uses: actions/checkout@v6
with:
submodules: recursive
- name: Get release version string
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- name: Download test artifacts
if: needs.native-tests.result != 'skipped'
uses: actions/download-artifact@v6
with:
name: platformio-test-report-${{ steps.version.outputs.long }}
merge-multiple: true
- name: Parse test results and create detailed summary
id: test-results
run: |
echo "## 🧪 Test Results Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# Check overall job status first
if [[ "${{ needs.native-tests.result }}" == "success" ]]; then
echo "✅ **Overall Status**: PASSED" >> $GITHUB_STEP_SUMMARY
elif [[ "${{ needs.native-tests.result }}" == "failure" ]]; then
echo "❌ **Overall Status**: FAILED" >> $GITHUB_STEP_SUMMARY
elif [[ "${{ needs.native-tests.result }}" == "cancelled" ]]; then
echo "⏸️ **Overall Status**: CANCELLED" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Tests were cancelled before completion." >> $GITHUB_STEP_SUMMARY
exit 0
else
echo "⚠️ **Overall Status**: SKIPPED" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Tests were skipped." >> $GITHUB_STEP_SUMMARY
exit 0
fi
echo "" >> $GITHUB_STEP_SUMMARY
# Parse detailed test results if available
if [ -f "testreport.xml" ]; then
echo "### 🔍 Individual Test Results" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
python3 << 'EOF'
import xml.etree.ElementTree as ET
import os
try:
tree = ET.parse('testreport.xml')
root = tree.getroot()
total_tests = 0
passed_tests = 0
failed_tests = 0
skipped_tests = 0
# Parse testsuite elements
for testsuite in root.findall('.//testsuite'):
suite_name = testsuite.get('name', 'Unknown')
suite_tests = int(testsuite.get('tests', '0'))
suite_failures = int(testsuite.get('failures', '0'))
suite_errors = int(testsuite.get('errors', '0'))
suite_skipped = int(testsuite.get('skipped', '0'))
total_tests += suite_tests
failed_tests += suite_failures + suite_errors
skipped_tests += suite_skipped
passed_tests += suite_tests - suite_failures - suite_errors - suite_skipped
if suite_tests > 0:
status = "✅" if (suite_failures + suite_errors) == 0 else "❌"
print(f"**{status} Test Suite: {suite_name}**")
print(f"- Total: {suite_tests}")
print(f"- Passed: ✅ {suite_tests - suite_failures - suite_errors - suite_skipped}")
print(f"- Failed: ❌ {suite_failures + suite_errors}")
if suite_skipped > 0:
print(f"- Skipped: ⏭️ {suite_skipped}")
print("")
# Show individual test results for failed suites
if suite_failures + suite_errors > 0:
print("**Failed Tests:**")
for testcase in testsuite.findall('testcase'):
test_name = testcase.get('name', 'Unknown')
failure = testcase.find('failure')
error = testcase.find('error')
if failure is not None:
msg = failure.get('message', 'Unknown error')[:100]
print(f"- ❌ `{test_name}`: {msg}")
elif error is not None:
msg = error.get('message', 'Unknown error')[:100]
print(f"- ❌ `{test_name}`: ERROR - {msg}")
print("")
else:
# Show passed tests for successful suites
passed_count = 0
for testcase in testsuite.findall('testcase'):
if testcase.find('failure') is None and testcase.find('error') is None:
if passed_count < 5: # Limit to first 5 to avoid spam
test_name = testcase.get('name', 'Unknown')
print(f"- ✅ `{test_name}`: PASSED")
passed_count += 1
if passed_count > 5:
print(f"- ... and {passed_count - 5} more tests passed")
print("")
# Summary statistics
print("### 📊 Test Statistics")
print(f"- **Total Tests**: {total_tests}")
print(f"- **Passed**: ✅ {passed_tests}")
print(f"- **Failed**: ❌ {failed_tests}")
if skipped_tests > 0:
print(f"- **Skipped**: ⏭️ {skipped_tests}")
if failed_tests > 0:
print(f"\n❌ **{failed_tests} tests failed out of {total_tests} total**")
else:
print(f"\n✅ **All {total_tests} tests passed!**")
except Exception as e:
print(f"❌ Error parsing test results: {e}")
EOF
else
echo "⚠️ **No detailed test report available**" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Test artifacts may not have been generated properly." >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "---" >> $GITHUB_STEP_SUMMARY
echo "View detailed logs in the [Actions tab](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})" >> $GITHUB_STEP_SUMMARY
- name: Comment test results on PR
if: github.event_name == 'pull_request' && needs.native-tests.result != 'skipped'
uses: actions/github-script@v8
with:
script: |
const fs = require('fs');
// Read the step summary to use as PR comment
let testSummary = "## 🧪 Test Results Summary\n\n";
if ("${{ needs.native-tests.result }}" === "success") {
testSummary += "✅ **All tests passed!**\n\n";
} else if ("${{ needs.native-tests.result }}" === "failure") {
testSummary += "❌ **Some tests failed.**\n\n";
} else {
testSummary += "⚠️ **Tests did not complete normally.**\n\n";
}
testSummary += `View detailed results: [Actions Run](${context.payload.repository.html_url}/actions/runs/${context.runId})\n\n`;
testSummary += "---\n";
testSummary += "*This comment will be automatically updated when new commits are pushed.*";
// Find existing comment
const comments = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number
});
const botComment = comments.data.find(comment =>
comment.user.type === 'Bot' &&
comment.body.includes('🧪 Test Results Summary')
);
if (botComment) {
// Update existing comment
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: testSummary
});
} else {
// Create new comment
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: testSummary
});
}
- name: Set overall status
run: |
if [[ "${{ needs.native-tests.result }}" == "success" ]]; then
echo "All tests passed! ✅"
exit 0
else
echo "Some tests failed! ❌"
exit 1
fi

View File

@@ -20,11 +20,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
series: series: [plucky, noble, jammy]
- jammy # 22.04 LTS
- noble # 24.04 LTS
- plucky # 25.04
- questing # 25.10
uses: ./.github/workflows/package_ppa.yml uses: ./.github/workflows/package_ppa.yml
with: with:
ppa_repo: |- ppa_repo: |-
@@ -60,13 +56,10 @@ jobs:
shell: bash shell: bash
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v4
with:
# Always use master branch for version bumps
ref: master
- name: Setup Python - name: Setup Python
uses: actions/setup-python@v6 uses: actions/setup-python@v5
with: with:
python-version: 3.x python-version: 3.x
@@ -106,9 +99,8 @@ jobs:
with: with:
base: ${{ github.event.repository.default_branch }} base: ${{ github.event.repository.default_branch }}
branch: create-pull-request/bump-version branch: create-pull-request/bump-version
labels: github_actions
title: Bump release version title: Bump release version
commit-message: Automated version bumps commit-message: automated bumps
add-paths: | add-paths: |
version.properties version.properties
debian/changelog debian/changelog

View File

@@ -21,7 +21,7 @@ jobs:
steps: steps:
# step 1 # step 1
- name: clone application source code - name: clone application source code
uses: actions/checkout@v6 uses: actions/checkout@v4
# step 2 # step 2
- name: full scan - name: full scan
@@ -33,7 +33,7 @@ jobs:
# step 3 # step 3
- name: save report as pipeline artifact - name: save report as pipeline artifact
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
with: with:
name: report.sarif name: report.sarif
overwrite: true overwrite: true
@@ -41,7 +41,7 @@ jobs:
# step 4 # step 4
- name: publish code scanning alerts - name: publish code scanning alerts
uses: github/codeql-action/upload-sarif@v4 uses: github/codeql-action/upload-sarif@v3
with: with:
sarif_file: report.sarif sarif_file: report.sarif
category: semgrep category: semgrep

View File

@@ -13,7 +13,7 @@ jobs:
steps: steps:
# step 1 # step 1
- name: clone application source code - name: clone application source code
uses: actions/checkout@v6 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0

View File

@@ -17,10 +17,8 @@ jobs:
steps: steps:
- name: Stale PR+Issues - name: Stale PR+Issues
uses: actions/stale@v10.1.1 uses: actions/stale@v9.1.0
with: with:
days-before-stale: 45 days-before-stale: 45
stale-issue-message: This issue has not had any comment or update in the last month. If it is still relevant, please post update comments. If no comments are made, this issue will be closed automagically in 7 days. exempt-issue-labels: pinned,3.0
close-issue-message: This issue has not had any comment since the last notice. It has been closed automatically. If this is incorrect, or the issue becomes relevant again, please request that it is reopened. exempt-pr-labels: pinned,3.0
exempt-issue-labels: pinned,3.0,triaged,backlog
exempt-pr-labels: pinned,3.0,triaged,backlog

View File

@@ -14,7 +14,7 @@ jobs:
name: Native Simulator Tests name: Native Simulator Tests
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v4
with: with:
ref: ${{github.event.pull_request.head.ref}} ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}} repository: ${{github.event.pull_request.head.repo.full_name}}
@@ -40,7 +40,7 @@ jobs:
- name: Integration test - name: Integration test
run: | run: |
.pio/build/coverage/meshtasticd -s & .pio/build/coverage/program &
PID=$! PID=$!
timeout 20 bash -c "until ls -al /proc/$PID/fd | grep socket; do sleep 1; done" timeout 20 bash -c "until ls -al /proc/$PID/fd | grep socket; do sleep 1; done"
echo "Simulator started, launching python test..." echo "Simulator started, launching python test..."
@@ -59,10 +59,10 @@ jobs:
id: version id: version
- name: Save coverage information - name: Save coverage information
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
if: always() # run this step even if previous step failed if: always() # run this step even if previous step failed
with: with:
name: lcov-coverage-info-native-simulator-test-${{ steps.version.outputs.long }} name: lcov-coverage-info-native-simulator-test-${{ steps.version.outputs.long }}.zip
overwrite: true overwrite: true
path: ./coverage_*.info path: ./coverage_*.info
@@ -70,7 +70,7 @@ jobs:
name: Native PlatformIO Tests name: Native PlatformIO Tests
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v4
with: with:
ref: ${{github.event.pull_request.head.ref}} ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}} repository: ${{github.event.pull_request.head.repo.full_name}}
@@ -94,9 +94,9 @@ jobs:
- name: Save test results - name: Save test results
if: always() # run this step even if previous step failed if: always() # run this step even if previous step failed
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
with: with:
name: platformio-test-report-${{ steps.version.outputs.long }} name: platformio-test-report-${{ steps.version.outputs.long }}.zip
overwrite: true overwrite: true
path: ./testreport.xml path: ./testreport.xml
@@ -108,10 +108,10 @@ jobs:
sed -i -e "s#${PWD}#.#" coverage_tests.info # Make paths relative. sed -i -e "s#${PWD}#.#" coverage_tests.info # Make paths relative.
- name: Save coverage information - name: Save coverage information
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
if: always() # run this step even if previous step failed if: always() # run this step even if previous step failed
with: with:
name: lcov-coverage-info-native-platformio-tests-${{ steps.version.outputs.long }} name: lcov-coverage-info-native-platformio-tests-${{ steps.version.outputs.long }}.zip
overwrite: true overwrite: true
path: ./coverage_*.info path: ./coverage_*.info
@@ -127,7 +127,7 @@ jobs:
- platformio-tests - platformio-tests
if: always() if: always()
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v4
with: with:
ref: ${{github.event.pull_request.head.ref}} ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}} repository: ${{github.event.pull_request.head.repo.full_name}}
@@ -137,22 +137,22 @@ jobs:
id: version id: version
- name: Download test artifacts - name: Download test artifacts
uses: actions/download-artifact@v6 uses: actions/download-artifact@v4
with: with:
name: platformio-test-report-${{ steps.version.outputs.long }} name: platformio-test-report-${{ steps.version.outputs.long }}.zip
merge-multiple: true merge-multiple: true
- name: Test Report - name: Test Report
uses: dorny/test-reporter@v2.3.0 uses: dorny/test-reporter@v2.1.1
with: with:
name: PlatformIO Tests name: PlatformIO Tests
path: testreport.xml path: testreport.xml
reporter: java-junit reporter: java-junit
- name: Download coverage artifacts - name: Download coverage artifacts
uses: actions/download-artifact@v6 uses: actions/download-artifact@v4
with: with:
pattern: lcov-coverage-info-native-*-${{ steps.version.outputs.long }} pattern: lcov-coverage-info-native-*-${{ steps.version.outputs.long }}.zip
path: code-coverage-report path: code-coverage-report
merge-multiple: true merge-multiple: true
@@ -163,7 +163,7 @@ jobs:
genhtml --quiet --legend --prefix "${PWD}" code-coverage-report/coverage_src.info --output-directory code-coverage-report genhtml --quiet --legend --prefix "${PWD}" code-coverage-report/coverage_src.info --output-directory code-coverage-report
- name: Save Code Coverage Report - name: Save Code Coverage Report
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
with: with:
name: code-coverage-report-${{ steps.version.outputs.long }} name: code-coverage-report-${{ steps.version.outputs.long }}.zip
path: code-coverage-report path: code-coverage-report

View File

@@ -20,9 +20,9 @@ jobs:
runs-on: test-runner runs-on: test-runner
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v6 uses: actions/checkout@v4
# - uses: actions/setup-python@v6 # - uses: actions/setup-python@v5
# with: # with:
# python-version: '3.10' # python-version: '3.10'
@@ -47,9 +47,9 @@ jobs:
pio upgrade pio upgrade
- name: Setup Node - name: Setup Node
uses: actions/setup-node@v6 uses: actions/setup-node@v4
with: with:
node-version: 24 node-version: 22
- name: Setup pnpm - name: Setup pnpm
uses: pnpm/action-setup@v4 uses: pnpm/action-setup@v4

View File

@@ -18,7 +18,7 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v4
- name: Trunk Check - name: Trunk Check
uses: trunk-io/trunk-action@v1 uses: trunk-io/trunk-action@v1

View File

@@ -16,7 +16,7 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v4
- name: Trunk Check - name: Trunk Check
uses: trunk-io/trunk-action@v1 uses: trunk-io/trunk-action@v1

View File

@@ -15,7 +15,7 @@ jobs:
pull-requests: write pull-requests: write
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v6 uses: actions/checkout@v4
with: with:
ref: ${{github.event.pull_request.head.ref}} ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}} repository: ${{github.event.pull_request.head.repo.full_name}}
@@ -39,7 +39,7 @@ jobs:
git push git push
- name: Comment on PR - name: Comment on PR
uses: actions/github-script@v8 uses: actions/github-script@v7
with: with:
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }}
script: | script: |

View File

@@ -11,7 +11,7 @@ jobs:
pull-requests: write pull-requests: write
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v6 uses: actions/checkout@v4
with: with:
submodules: true submodules: true
@@ -34,9 +34,7 @@ jobs:
uses: peter-evans/create-pull-request@v7 uses: peter-evans/create-pull-request@v7
with: with:
branch: create-pull-request/update-protobufs branch: create-pull-request/update-protobufs
labels: submodules
title: Update protobufs and classes title: Update protobufs and classes
commit-message: Update protobufs
add-paths: | add-paths: |
protobufs protobufs
src/mesh src/mesh

View File

@@ -1,34 +1,34 @@
version: 0.1 version: 0.1
cli: cli:
version: 1.25.0 version: 1.24.0
plugins: plugins:
sources: sources:
- id: trunk - id: trunk
ref: v1.7.4 ref: v1.7.1
uri: https://github.com/trunk-io/plugins uri: https://github.com/trunk-io/plugins
lint: lint:
enabled: enabled:
- checkov@3.2.495 - checkov@3.2.450
- renovate@42.30.4 - renovate@41.29.1
- prettier@3.7.4 - prettier@3.6.2
- trufflehog@3.91.2 - trufflehog@3.89.2
- yamllint@1.37.1 - yamllint@1.37.1
- bandit@1.9.2 - bandit@1.8.6
- trivy@0.67.2 - trivy@0.64.1
- taplo@0.10.0 - taplo@0.9.3
- ruff@0.14.7 - ruff@0.12.2
- isort@7.0.0 - isort@6.0.1
- markdownlint@0.46.0 - markdownlint@0.45.0
- oxipng@9.1.5 - oxipng@9.1.5
- svgo@4.0.0 - svgo@4.0.0
- actionlint@1.7.9 - actionlint@1.7.7
- flake8@7.3.0 - flake8@7.3.0
- hadolint@2.14.0 - hadolint@2.12.1-beta
- shfmt@3.6.0 - shfmt@3.6.0
- shellcheck@0.11.0 - shellcheck@0.10.0
- black@25.11.0 - black@25.1.0
- git-diff-check - git-diff-check
- gitleaks@8.30.0 - gitleaks@8.27.2
- clang-format@16.0.3 - clang-format@16.0.3
ignore: ignore:
- linters: [ALL] - linters: [ALL]

View File

@@ -3,7 +3,7 @@
# trunk-ignore-all(hadolint/DL3008): Do not pin apt package versions # trunk-ignore-all(hadolint/DL3008): Do not pin apt package versions
# trunk-ignore-all(hadolint/DL3013): Do not pin pip package versions # trunk-ignore-all(hadolint/DL3013): Do not pin pip package versions
FROM python:3.14-slim-trixie AS builder FROM python:3.13-bookworm AS builder
ARG PIO_ENV=native ARG PIO_ENV=native
ENV DEBIAN_FRONTEND=noninteractive ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Etc/UTC ENV TZ=Etc/UTC
@@ -36,7 +36,7 @@ RUN curl -L "https://github.com/meshtastic/web/releases/download/v$(cat /tmp/fir
##### PRODUCTION BUILD ############# ##### PRODUCTION BUILD #############
FROM debian:trixie-slim FROM debian:bookworm-slim
LABEL org.opencontainers.image.title="Meshtastic" \ LABEL org.opencontainers.image.title="Meshtastic" \
org.opencontainers.image.description="Debian Meshtastic daemon and web interface" \ org.opencontainers.image.description="Debian Meshtastic daemon and web interface" \
org.opencontainers.image.url="https://meshtastic.org" \ org.opencontainers.image.url="https://meshtastic.org" \
@@ -51,8 +51,8 @@ ENV TZ=Etc/UTC
USER root USER root
RUN apt-get update && apt-get --no-install-recommends -y install \ RUN apt-get update && apt-get --no-install-recommends -y install \
libc-bin libc6 libgpiod3 libyaml-cpp0.8 libi2c0 libuv1t64 libusb-1.0-0-dev \ libc-bin libc6 libgpiod2 libyaml-cpp0.7 libi2c0 libuv1 libusb-1.0-0-dev \
liborcania2.3 libulfius2.7t64 libssl3t64 \ liborcania2.3 libulfius2.7 libssl3 \
libx11-6 libinput10 libxkbcommon-x11-0 \ libx11-6 libinput10 libxkbcommon-x11-0 \
&& apt-get clean && rm -rf /var/lib/apt/lists/* \ && apt-get clean && rm -rf /var/lib/apt/lists/* \
&& mkdir -p /var/lib/meshtasticd \ && mkdir -p /var/lib/meshtasticd \
@@ -61,7 +61,7 @@ RUN apt-get update && apt-get --no-install-recommends -y install \
# Fetch compiled binary from the builder # Fetch compiled binary from the builder
COPY --from=builder /tmp/firmware/release/meshtasticd /usr/bin/ COPY --from=builder /tmp/firmware/release/meshtasticd /usr/bin/
COPY --from=builder /tmp/web /usr/share/meshtasticd/web/ COPY --from=builder /tmp/web /usr/share/meshtasticd/
# Copy config templates # Copy config templates
COPY ./bin/config.d /etc/meshtasticd/available.d COPY ./bin/config.d /etc/meshtasticd/available.d

View File

@@ -37,3 +37,4 @@ Join our community and help improve Meshtastic! 🚀
## Stats ## Stats
![Alt](https://repobeats.axiom.co/api/embed/8025e56c482ec63541593cc5bd322c19d5c0bdcf.svg "Repobeats analytics image") ![Alt](https://repobeats.axiom.co/api/embed/8025e56c482ec63541593cc5bd322c19d5c0bdcf.svg "Repobeats analytics image")

View File

@@ -3,13 +3,12 @@
# trunk-ignore-all(hadolint/DL3018): Do not pin apk package versions # trunk-ignore-all(hadolint/DL3018): Do not pin apk package versions
# trunk-ignore-all(hadolint/DL3013): Do not pin pip package versions # trunk-ignore-all(hadolint/DL3013): Do not pin pip package versions
FROM python:3.14-alpine3.22 AS builder FROM python:3.13-alpine3.22 AS builder
ARG PIO_ENV=native ARG PIO_ENV=native
ENV PIP_ROOT_USER_ACTION=ignore ENV PIP_ROOT_USER_ACTION=ignore
RUN apk --no-cache add \ RUN apk --no-cache add \
bash g++ libstdc++-dev linux-headers zip git ca-certificates libbsd-dev \ bash g++ libstdc++-dev linux-headers zip git ca-certificates libgpiod-dev yaml-cpp-dev bluez-dev \
libgpiod-dev yaml-cpp-dev bluez-dev \
libusb-dev i2c-tools-dev libuv-dev openssl-dev pkgconf argp-standalone \ libusb-dev i2c-tools-dev libuv-dev openssl-dev pkgconf argp-standalone \
libx11-dev libinput-dev libxkbcommon-dev \ libx11-dev libinput-dev libxkbcommon-dev \
&& rm -rf /var/cache/apk/* \ && rm -rf /var/cache/apk/* \
@@ -28,7 +27,7 @@ RUN bash ./bin/build-native.sh "$PIO_ENV" && \
# ##### PRODUCTION BUILD ############# # ##### PRODUCTION BUILD #############
FROM alpine:3.23 FROM alpine:3.22
LABEL org.opencontainers.image.title="Meshtastic" \ LABEL org.opencontainers.image.title="Meshtastic" \
org.opencontainers.image.description="Alpine Meshtastic daemon" \ org.opencontainers.image.description="Alpine Meshtastic daemon" \
org.opencontainers.image.url="https://meshtastic.org" \ org.opencontainers.image.url="https://meshtastic.org" \
@@ -41,8 +40,8 @@ LABEL org.opencontainers.image.title="Meshtastic" \
USER root USER root
RUN apk --no-cache add \ RUN apk --no-cache add \
shadow libstdc++ libbsd libgpiod yaml-cpp libusb \ shadow libstdc++ libgpiod yaml-cpp libusb i2c-tools libuv \
i2c-tools libuv libx11 libinput libxkbcommon \ libx11 libinput libxkbcommon \
&& rm -rf /var/cache/apk/* \ && rm -rf /var/cache/apk/* \
&& mkdir -p /var/lib/meshtasticd \ && mkdir -p /var/lib/meshtasticd \
&& mkdir -p /etc/meshtasticd/config.d \ && mkdir -p /etc/meshtasticd/config.d \

View File

@@ -2,16 +2,10 @@
[esp32_base] [esp32_base]
extends = arduino_base extends = arduino_base
custom_esp32_kind = esp32 custom_esp32_kind = esp32
custom_mtjson_part =
platform = platform =
# renovate: datasource=custom.pio depName=platformio/espressif32 packageName=platformio/platform/espressif32 # renovate: datasource=custom.pio depName=platformio/espressif32 packageName=platformio/platform/espressif32
platformio/espressif32@6.11.0 platformio/espressif32@6.11.0
extra_scripts =
${env.extra_scripts}
pre:extra_scripts/esp32_pre.py
extra_scripts/esp32_extra.py
build_src_filter = build_src_filter =
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2xx0> -<mesh/eth/> -<mesh/raspihttp> ${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2xx0> -<mesh/eth/> -<mesh/raspihttp>
@@ -37,13 +31,11 @@ build_flags =
-DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL
-DAXP_DEBUG_PORT=Serial -DAXP_DEBUG_PORT=Serial
-DCONFIG_BT_NIMBLE_ENABLED -DCONFIG_BT_NIMBLE_ENABLED
-DCONFIG_BT_NIMBLE_MAX_BONDS=6 # default is 3
-DCONFIG_NIMBLE_CPP_LOG_LEVEL=2 -DCONFIG_NIMBLE_CPP_LOG_LEVEL=2
-DCONFIG_BT_NIMBLE_MAX_CCCDS=20 -DCONFIG_BT_NIMBLE_MAX_CCCDS=20
-DCONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=8192 -DCONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=8192
-DESP_OPENSSL_SUPPRESS_LEGACY_WARNING -DESP_OPENSSL_SUPPRESS_LEGACY_WARNING
-DSERIAL_BUFFER_SIZE=4096 -DSERIAL_BUFFER_SIZE=4096
-DSERIAL_HAS_ON_RECEIVE
-DLIBPAX_ARDUINO -DLIBPAX_ARDUINO
-DLIBPAX_WIFI -DLIBPAX_WIFI
-DLIBPAX_BLE -DLIBPAX_BLE
@@ -62,8 +54,8 @@ lib_deps =
h2zero/NimBLE-Arduino@^1.4.3 h2zero/NimBLE-Arduino@^1.4.3
# renovate: datasource=git-refs depName=libpax packageName=https://github.com/dbinfrago/libpax gitBranch=master # renovate: datasource=git-refs depName=libpax packageName=https://github.com/dbinfrago/libpax gitBranch=master
https://github.com/dbinfrago/libpax/archive/3cdc0371c375676a97967547f4065607d4c53fd1.zip https://github.com/dbinfrago/libpax/archive/3cdc0371c375676a97967547f4065607d4c53fd1.zip
# renovate: datasource=github-tags depName=XPowersLib packageName=lewisxhe/XPowersLib # renovate: datasource=custom.pio depName=XPowersLib packageName=lewisxhe/library/XPowersLib
https://github.com/lewisxhe/XPowersLib/archive/v0.3.2.zip lewisxhe/XPowersLib@0.3.0
# renovate: datasource=git-refs depName=meshtastic-ESP32_Codec2 packageName=https://github.com/meshtastic/ESP32_Codec2 gitBranch=master # renovate: datasource=git-refs depName=meshtastic-ESP32_Codec2 packageName=https://github.com/meshtastic/ESP32_Codec2 gitBranch=master
https://github.com/meshtastic/ESP32_Codec2/archive/633326c78ac251c059ab3a8c430fcdf25b41672f.zip https://github.com/meshtastic/ESP32_Codec2/archive/633326c78ac251c059ab3a8c430fcdf25b41672f.zip
# renovate: datasource=custom.pio depName=rweather/Crypto packageName=rweather/library/Crypto # renovate: datasource=custom.pio depName=rweather/Crypto packageName=rweather/library/Crypto

View File

@@ -28,7 +28,7 @@ lib_deps =
${environmental_extra.lib_deps} ${environmental_extra.lib_deps}
${radiolib_base.lib_deps} ${radiolib_base.lib_deps}
# renovate: datasource=custom.pio depName=XPowersLib packageName=lewisxhe/library/XPowersLib # renovate: datasource=custom.pio depName=XPowersLib packageName=lewisxhe/library/XPowersLib
lewisxhe/XPowersLib@0.3.2 lewisxhe/XPowersLib@0.3.0
# renovate: datasource=git-refs depName=meshtastic-ESP32_Codec2 packageName=https://github.com/meshtastic/ESP32_Codec2 gitBranch=master # renovate: datasource=git-refs depName=meshtastic-ESP32_Codec2 packageName=https://github.com/meshtastic/ESP32_Codec2 gitBranch=master
https://github.com/meshtastic/ESP32_Codec2/archive/633326c78ac251c059ab3a8c430fcdf25b41672f.zip https://github.com/meshtastic/ESP32_Codec2/archive/633326c78ac251c059ab3a8c430fcdf25b41672f.zip
# renovate: datasource=custom.pio depName=rweather/Crypto packageName=rweather/library/Crypto # renovate: datasource=custom.pio depName=rweather/Crypto packageName=rweather/library/Crypto

View File

@@ -7,17 +7,13 @@ extends = arduino_base
platform_packages = platform_packages =
; our custom Git version until they merge our PR ; our custom Git version until they merge our PR
# TODO renovate # TODO renovate
platformio/framework-arduinoadafruitnrf52 @ https://github.com/meshtastic/Adafruit_nRF52_Arduino#c770c8a16a351b55b86e347a3d9d7b74ad0bbf39 platformio/framework-arduinoadafruitnrf52 @ https://github.com/meshtastic/Adafruit_nRF52_Arduino#e13f5820002a4fb2a5e6754b42ace185277e5adf
; Don't renovate toolchain-gccarmnoneeabi ; Don't renovate toolchain-gccarmnoneeabi
platformio/toolchain-gccarmnoneeabi@~1.90301.0 platformio/toolchain-gccarmnoneeabi@~1.90301.0
extra_scripts = build_type = debug
${env.extra_scripts}
extra_scripts/nrf52_extra.py
build_type = release
build_flags = build_flags =
-include variants/nrf52840/cpp_overrides/lfs_util.h -include arch/nrf52/cpp_overrides/lfs_util.h
${arduino_base.build_flags} ${arduino_base.build_flags}
-DSERIAL_BUFFER_SIZE=1024 -DSERIAL_BUFFER_SIZE=1024
-Wno-unused-variable -Wno-unused-variable
@@ -25,20 +21,9 @@ build_flags =
-DLFS_NO_ASSERT ; Disable LFS assertions , see https://github.com/meshtastic/firmware/pull/3818 -DLFS_NO_ASSERT ; Disable LFS assertions , see https://github.com/meshtastic/firmware/pull/3818
-DMESHTASTIC_EXCLUDE_AUDIO=1 -DMESHTASTIC_EXCLUDE_AUDIO=1
-DMESHTASTIC_EXCLUDE_PAXCOUNTER=1 -DMESHTASTIC_EXCLUDE_PAXCOUNTER=1
-Os
build_unflags =
-Ofast
-Og
-ggdb3
-ggdb2
-g3
-g2
-g
-g1
-g0
build_src_filter = build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/wifi/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<platform/rp2xx0> -<mesh/eth/> -<mesh/raspihttp> -<serialization/> ${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/wifi/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<platform/rp2xx0> -<mesh/eth/> -<mesh/raspihttp>
lib_deps= lib_deps=
${arduino_base.lib_deps} ${arduino_base.lib_deps}

View File

@@ -8,7 +8,7 @@ lib_deps =
${environmental_base.lib_deps} ${environmental_base.lib_deps}
${environmental_extra.lib_deps} ${environmental_extra.lib_deps}
# renovate: datasource=git-refs depName=Kongduino-Adafruit_nRFCrypto packageName=https://github.com/Kongduino/Adafruit_nRFCrypto gitBranch=master # renovate: datasource=git-refs depName=Kongduino-Adafruit_nRFCrypto packageName=https://github.com/Kongduino/Adafruit_nRFCrypto gitBranch=master
https://github.com/Kongduino/Adafruit_nRFCrypto/archive/8cde7189b5ead9dcd49f72601b43b969c0bbc06e.zip https://github.com/Kongduino/Adafruit_nRFCrypto/archive/5f838d2709461a2c981f642917aa50254a25c14c.zip
; Common NRF52 debugging settings follow. See the Meshtastic developer docs for how to connect SWD debugging probes to your board. ; Common NRF52 debugging settings follow. See the Meshtastic developer docs for how to connect SWD debugging probes to your board.

View File

@@ -2,7 +2,7 @@
[portduino_base] [portduino_base]
platform = platform =
# renovate: datasource=git-refs depName=platform-native packageName=https://github.com/meshtastic/platform-native gitBranch=develop # renovate: datasource=git-refs depName=platform-native packageName=https://github.com/meshtastic/platform-native gitBranch=develop
https://github.com/meshtastic/platform-native/archive/f566d364204416cdbf298e349213f7d551f793d9.zip https://github.com/meshtastic/platform-native/archive/6cb7a455b440dd0738e8ed74a18136ed5cf7ea63.zip
framework = arduino framework = arduino
build_src_filter = build_src_filter =
@@ -17,6 +17,7 @@ build_src_filter =
+<mesh/raspihttp/> +<mesh/raspihttp/>
-<mesh/eth/> -<mesh/eth/>
-<modules/esp32> -<modules/esp32>
+<../variants/portduino>
lib_deps = lib_deps =
${env.lib_deps} ${env.lib_deps}
@@ -31,17 +32,15 @@ lib_deps =
https://github.com/pine64/libch341-spi-userspace/archive/af9bc27c9c30fa90772279925b7c5913dff789b4.zip https://github.com/pine64/libch341-spi-userspace/archive/af9bc27c9c30fa90772279925b7c5913dff789b4.zip
# renovate: datasource=custom.pio depName=adafruit/Adafruit seesaw Library packageName=adafruit/library/Adafruit seesaw Library # renovate: datasource=custom.pio depName=adafruit/Adafruit seesaw Library packageName=adafruit/library/Adafruit seesaw Library
adafruit/Adafruit seesaw Library@1.7.9 adafruit/Adafruit seesaw Library@1.7.9
# renovate: datasource=git-refs depName=RAK12034-BMX160 packageName=https://github.com/RAKWireless/RAK12034-BMX160 gitBranch=main
https://github.com/RAKWireless/RAK12034-BMX160/archive/dcead07ffa267d3c906e9ca4a1330ab989e957e2.zip
build_flags = build_flags =
${arduino_base.build_flags} ${arduino_base.build_flags}
-D ARCH_PORTDUINO
-fPIC -fPIC
-Isrc/platform/portduino -Isrc/platform/portduino
-DRADIOLIB_EEPROM_UNSUPPORTED -DRADIOLIB_EEPROM_UNSUPPORTED
-DPORTDUINO_LINUX_HARDWARE -DPORTDUINO_LINUX_HARDWARE
-DHAS_UDP_MULTICAST=1 -DNXP_WIRE=Wire
-DHAS_UDP_MULTICAST
-lpthread -lpthread
-lstdc++fs -lstdc++fs
-lbluetooth -lbluetooth

View File

@@ -2,13 +2,13 @@
extends = arduino_base extends = arduino_base
platform = platform =
# renovate: datasource=custom.pio depName=platformio/ststm32 packageName=platformio/platform/ststm32 # renovate: datasource=custom.pio depName=platformio/ststm32 packageName=platformio/platform/ststm32
platformio/ststm32@19.4.0 platformio/ststm32@19.2.0
platform_packages = platform_packages =
# TODO renovate # TODO renovate
platformio/framework-arduinoststm32@https://github.com/stm32duino/Arduino_Core_STM32/archive/2.10.1.zip platformio/framework-arduinoststm32@https://github.com/stm32duino/Arduino_Core_STM32/archive/2.10.1.zip
extra_scripts = extra_scripts =
${env.extra_scripts} ${env.extra_scripts}
extra_scripts/stm32_extra.py post:extra_scripts/extra_stm32.py
build_type = release build_type = release
@@ -23,23 +23,14 @@ build_flags =
-DMESHTASTIC_EXCLUDE_SCREEN=1 -DMESHTASTIC_EXCLUDE_SCREEN=1
-DMESHTASTIC_EXCLUDE_MQTT=1 -DMESHTASTIC_EXCLUDE_MQTT=1
-DMESHTASTIC_EXCLUDE_BLUETOOTH=1 -DMESHTASTIC_EXCLUDE_BLUETOOTH=1
-DMESHTASTIC_EXCLUDE_GPS=1
-DMESHTASTIC_EXCLUDE_WIFI=1 -DMESHTASTIC_EXCLUDE_WIFI=1
-DMESHTASTIC_EXCLUDE_TZ=1 ; Exclude TZ to save some flash space. -DMESHTASTIC_EXCLUDE_TZ=1 ; Exclude TZ to save some flash space.
-DSERIAL_RX_BUFFER_SIZE=256 ; For GPS - the default of 64 is too small.
-DHAS_SCREEN=0 ; Always disable screen for STM32, it is not supported.
-DPIO_FRAMEWORK_ARDUINO_NANOLIB_FLOAT_PRINTF ; This is REQUIRED for at least traceroute debug prints - without it the length ends up uninitialized. -DPIO_FRAMEWORK_ARDUINO_NANOLIB_FLOAT_PRINTF ; This is REQUIRED for at least traceroute debug prints - without it the length ends up uninitialized.
-DDEBUG_MUTE ; You can #undef DEBUG_MUTE in certain source files if you need the logs. ;-DDEBUG_MUTE
-fmerge-all-constants -fmerge-all-constants
-ffunction-sections -ffunction-sections
-fdata-sections -fdata-sections
-DRADIOLIB_EXCLUDE_SX128X=1
-DRADIOLIB_EXCLUDE_SX127X=1
-DRADIOLIB_EXCLUDE_LR11X0=1
-DHAL_DAC_MODULE_ONLY
-DHAL_RNG_MODULE_ENABLED
-Wl,--wrap=__assert_func
-Wl,--wrap=strerror
-Wl,--wrap=_tzset_unlocked_r
build_src_filter = build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<input> -<buzz> -<modules/RemoteHardwareModule.cpp> -<platform/nrf52> -<platform/portduino> -<platform/rp2xx0> -<mesh/raspihttp> ${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<input> -<buzz> -<modules/RemoteHardwareModule.cpp> -<platform/nrf52> -<platform/portduino> -<platform/rp2xx0> -<mesh/raspihttp>
@@ -53,7 +44,7 @@ lib_deps =
${radiolib_base.lib_deps} ${radiolib_base.lib_deps}
# renovate: datasource=git-refs depName=caveman99-stm32-Crypto packageName=https://github.com/caveman99/Crypto gitBranch=main # renovate: datasource=git-refs depName=caveman99-stm32-Crypto packageName=https://github.com/caveman99/Crypto gitBranch=main
https://github.com/caveman99/Crypto/archive/1aa30eb536bd52a576fde6dfa393bf7349cf102d.zip https://github.com/caveman99/Crypto/archive/eae9c768054118a9399690f8af202853d1ae8516.zip
lib_ignore = lib_ignore =
OneButton OneButton

View File

@@ -1,165 +0,0 @@
#!/usr/bin/env python3
"""Summarise linker map output to highlight heavy object files and libraries.
Usage:
python bin/analyze_map.py --map .pio/build/rak4631/output.map --top 20
The script parses GNU ld map files and aggregates section sizes per object file
and per archive/library, then prints sortable tables that make it easy to spot
modules worth trimming or hiding behind feature flags.
"""
from __future__ import annotations
import argparse
import collections
import os
import re
import sys
from typing import DefaultDict, Dict, Tuple
SECTION_LINE_RE = re.compile(r"^\s+(?P<section>\S+)\s+0x[0-9A-Fa-f]+\s+0x(?P<size>[0-9A-Fa-f]+)\s+(?P<object>.+)$")
ARCHIVE_MEMBER_RE = re.compile(r"^(?P<archive>.+)\((?P<object>[^)]+)\)$")
def human_size(num_bytes: int) -> str:
"""Return a friendly size string with one decimal place."""
if num_bytes < 1024:
return f"{num_bytes:,} B"
num = float(num_bytes)
for unit in ("KB", "MB", "GB"):
num /= 1024.0
if num < 1024.0:
return f"{num:.1f} {unit}"
return f"{num:.1f} TB"
def shorten_path(path: str, root: str) -> str:
"""Prefer repository-relative paths for readability."""
path = path.strip()
if not path:
return path
# Normalise Windows archives (backslashes) to POSIX style for consistency.
path = path.replace("\\", "/")
# Attempt to strip the root when an absolute path lives inside the repo.
if os.path.isabs(path):
try:
rel = os.path.relpath(path, root)
if not rel.startswith(".."):
return rel
except ValueError:
# relpath can fail on mixed drives on Windows; fall back to basename.
pass
return path
def describe_object(raw_object: str, root: str) -> Tuple[str, str]:
"""Return a human friendly object label and the library it belongs to."""
raw_object = raw_object.strip()
lib_label = "[app]"
match = ARCHIVE_MEMBER_RE.match(raw_object)
if match:
archive = shorten_path(match.group("archive"), root)
obj = match.group("object")
lib_label = os.path.basename(archive) or archive
label = f"{archive}:{obj}"
else:
label = shorten_path(raw_object, root)
# If the object lives under libs, hint at the containing directory.
parent = os.path.basename(os.path.dirname(label))
if parent:
lib_label = parent
return label, lib_label
def parse_map(map_path: str, repo_root: str) -> Tuple[Dict[str, int], Dict[str, int], Dict[str, Dict[str, int]]]:
per_object: DefaultDict[str, int] = collections.defaultdict(int)
per_library: DefaultDict[str, int] = collections.defaultdict(int)
per_object_sections: DefaultDict[str, DefaultDict[str, int]] = collections.defaultdict(lambda: collections.defaultdict(int))
try:
with open(map_path, "r", encoding="utf-8", errors="ignore") as handle:
for line in handle:
match = SECTION_LINE_RE.match(line)
if not match:
continue
section = match.group("section")
if section.startswith("*") or section in {"LOAD", "ORIGIN"}:
continue
size = int(match.group("size"), 16)
if size == 0:
continue
obj_token = match.group("object").strip()
if not obj_token or obj_token.startswith("*") or "load address" in obj_token:
continue
label, lib_label = describe_object(obj_token, repo_root)
per_object[label] += size
per_library[lib_label] += size
per_object_sections[label][section] += size
except FileNotFoundError:
raise SystemExit(f"error: map file '{map_path}' not found. Run a build first.")
return per_object, per_library, per_object_sections
def format_section_breakdown(section_sizes: Dict[str, int], total: int, limit: int = 3) -> str:
items = sorted(section_sizes.items(), key=lambda kv: kv[1], reverse=True)
parts = []
for section, size in items[:limit]:
pct = (size / total) * 100 if total else 0
parts.append(f"{section} {pct:.1f}%")
if len(items) > limit:
remainder = total - sum(size for _, size in items[:limit])
pct = (remainder / total) * 100 if total else 0
parts.append(f"other {pct:.1f}%")
return ", ".join(parts)
def print_report(map_path: str, top_n: int, per_object: Dict[str, int], per_library: Dict[str, int], per_object_sections: Dict[str, Dict[str, int]]):
total_bytes = sum(per_object.values())
if total_bytes == 0:
print("No section data found in map file.")
return
print(f"Map file: {map_path}")
print(f"Accounted size: {human_size(total_bytes)} across {len(per_object)} object files\n")
sorted_objects = sorted(per_object.items(), key=lambda kv: kv[1], reverse=True)
print(f"Top {min(top_n, len(sorted_objects))} object files by linked size:")
for idx, (obj, size) in enumerate(sorted_objects[:top_n], 1):
pct = (size / total_bytes) * 100
breakdown = format_section_breakdown(per_object_sections[obj], size)
print(f"{idx:2}. {human_size(size):>9} ({size:,} B, {pct:5.2f}% of linked size)")
print(f" {obj}")
if breakdown:
print(f" sections: {breakdown}")
print()
sorted_libs = sorted(per_library.items(), key=lambda kv: kv[1], reverse=True)
print(f"Top {min(top_n, len(sorted_libs))} libraries or source roots:")
for idx, (lib, size) in enumerate(sorted_libs[:top_n], 1):
pct = (size / total_bytes) * 100
print(f"{idx:2}. {human_size(size):>9} ({size:,} B, {pct:5.2f}% of linked size) {lib}")
def main() -> None:
parser = argparse.ArgumentParser(description="Highlight heavy object files from a GNU ld map file.")
parser.add_argument("--map", default=".pio/build/rak4631/output.map", help="Path to the map file (default: %(default)s)")
parser.add_argument("--top", type=int, default=20, help="Number of entries to display per table (default: %(default)s)")
args = parser.parse_args()
map_path = os.path.abspath(args.map)
repo_root = os.path.abspath(os.getcwd())
per_object, per_library, per_object_sections = parse_map(map_path, repo_root)
print_report(os.path.relpath(map_path, repo_root), args.top, per_object, per_library, per_object_sections)
if __name__ == "__main__":
main()

View File

@@ -5,8 +5,7 @@ set -e
VERSION=`bin/buildinfo.py long` VERSION=`bin/buildinfo.py long`
SHORT_VERSION=`bin/buildinfo.py short` SHORT_VERSION=`bin/buildinfo.py short`
BUILDDIR=.pio/build/$1 OUTDIR=release/
OUTDIR=release
rm -f $OUTDIR/firmware* rm -f $OUTDIR/firmware*
rm -r $OUTDIR/* || true rm -r $OUTDIR/* || true
@@ -15,7 +14,7 @@ rm -r $OUTDIR/* || true
platformio pkg install -e $1 platformio pkg install -e $1
echo "Building for $1 with $PLATFORMIO_BUILD_FLAGS" echo "Building for $1 with $PLATFORMIO_BUILD_FLAGS"
rm -f $BUILDDIR/firmware* rm -f .pio/build/$1/firmware.*
# The shell vars the build tool expects to find # The shell vars the build tool expects to find
export APP_VERSION=$VERSION export APP_VERSION=$VERSION
@@ -23,14 +22,16 @@ export APP_VERSION=$VERSION
basename=firmware-$1-$VERSION basename=firmware-$1-$VERSION
pio run --environment $1 # -v pio run --environment $1 # -v
SRCELF=.pio/build/$1/firmware.elf
cp $BUILDDIR/$basename.elf $OUTDIR/$basename.elf cp $SRCELF $OUTDIR/$basename.elf
echo "Copying ESP32 bin file" echo "Copying ESP32 bin file"
cp $BUILDDIR/$basename.factory.bin $OUTDIR/$basename.factory.bin SRCBIN=.pio/build/$1/firmware.factory.bin
cp $SRCBIN $OUTDIR/$basename.bin
echo "Copying ESP32 update bin file" echo "Copying ESP32 update bin file"
cp $BUILDDIR/$basename.bin $OUTDIR/$basename.bin SRCBIN=.pio/build/$1/firmware.bin
cp $SRCBIN $OUTDIR/$basename-update.bin
echo "Building Filesystem for ESP32 targets" echo "Building Filesystem for ESP32 targets"
# If you want to build the webui, uncomment the following lines # If you want to build the webui, uncomment the following lines
@@ -39,13 +40,7 @@ echo "Building Filesystem for ESP32 targets"
# # Remove webserver files from the filesystem and rebuild # # Remove webserver files from the filesystem and rebuild
# ls -l data/static # Diagnostic list of files # ls -l data/static # Diagnostic list of files
# rm -rf data/static # rm -rf data/static
pio run --environment $1 -t buildfs --disable-auto-clean pio run --environment $1 -t buildfs
cp $BUILDDIR/littlefs-$1-$VERSION.bin $OUTDIR/littlefs-$1-$VERSION.bin cp .pio/build/$1/littlefs.bin $OUTDIR/littlefs-$1-$VERSION.bin
cp bin/device-install.* $OUTDIR/ cp bin/device-install.* $OUTDIR
cp bin/device-update.* $OUTDIR/ cp bin/device-update.* $OUTDIR
# Generate the manifest file
echo "Generating Meshtastic manifest"
TIMEFORMAT="Generated manifest in %E seconds"
time pio run --environment $1 -t mtjson --silent --disable-auto-clean
cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json

View File

@@ -1,5 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
sed -i 's/#-DBUILD_EPOCH=$UNIX_TIME/-DBUILD_EPOCH=$UNIX_TIME/' platformio.ini
export PIP_BREAK_SYSTEM_PACKAGES=1 export PIP_BREAK_SYSTEM_PACKAGES=1
if (echo $2 | grep -q "esp32"); then if (echo $2 | grep -q "esp32"); then
@@ -9,7 +11,7 @@ elif (echo $2 | grep -q "nrf52"); then
elif (echo $2 | grep -q "stm32"); then elif (echo $2 | grep -q "stm32"); then
bin/build-stm32.sh $1 bin/build-stm32.sh $1
elif (echo $2 | grep -q "rpi2040"); then elif (echo $2 | grep -q "rpi2040"); then
bin/build-rp2xx0.sh $1 bin/build-rpi2040.sh $1
else else
echo "Unknown target $2" echo "Unknown target $2"
exit 1 exit 1

View File

@@ -17,19 +17,15 @@ VERSION=$(bin/buildinfo.py long)
SHORT_VERSION=$(bin/buildinfo.py short) SHORT_VERSION=$(bin/buildinfo.py short)
PIO_ENV=${1:-native} PIO_ENV=${1:-native}
BUILDDIR=.pio/build/$PIO_ENV OUTDIR=release/
OUTDIR=release
rm -f $OUTDIR/meshtasticd* rm -f $OUTDIR/firmware*
mkdir -p $OUTDIR/ mkdir -p $OUTDIR/
rm -r $OUTDIR/* || true rm -r $OUTDIR/* || true
basename=meshtasticd-$1-$VERSION
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale # Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
pio pkg install --environment "$PIO_ENV" || platformioFailed pio pkg install --environment "$PIO_ENV" || platformioFailed
pio run --environment "$PIO_ENV" || platformioFailed pio run --environment "$PIO_ENV" || platformioFailed
cp ".pio/build/$PIO_ENV/program" "$OUTDIR/meshtasticd_linux_$(uname -m)"
cp "$BUILDDIR/meshtasticd" "$OUTDIR/meshtasticd_linux_$(uname -m)" cp bin/native-install.* $OUTDIR
cp bin/native-install.* $OUTDIR/

View File

@@ -5,8 +5,7 @@ set -e
VERSION=$(bin/buildinfo.py long) VERSION=$(bin/buildinfo.py long)
SHORT_VERSION=$(bin/buildinfo.py short) SHORT_VERSION=$(bin/buildinfo.py short)
BUILDDIR=.pio/build/$1 OUTDIR=release/
OUTDIR=release
rm -f $OUTDIR/firmware* rm -f $OUTDIR/firmware*
rm -r $OUTDIR/* || true rm -r $OUTDIR/* || true
@@ -15,7 +14,7 @@ rm -r $OUTDIR/* || true
platformio pkg install -e $1 platformio pkg install -e $1
echo "Building for $1 with $PLATFORMIO_BUILD_FLAGS" echo "Building for $1 with $PLATFORMIO_BUILD_FLAGS"
rm -f $BUILDDIR/firmware* rm -f .pio/build/$1/firmware.*
# The shell vars the build tool expects to find # The shell vars the build tool expects to find
export APP_VERSION=$VERSION export APP_VERSION=$VERSION
@@ -23,32 +22,32 @@ export APP_VERSION=$VERSION
basename=firmware-$1-$VERSION basename=firmware-$1-$VERSION
pio run --environment $1 # -v pio run --environment $1 # -v
SRCELF=.pio/build/$1/firmware.elf
cp $SRCELF $OUTDIR/$basename.elf
cp $BUILDDIR/$basename.elf $OUTDIR/$basename.elf echo "Generating NRF52 dfu file"
DFUPKG=.pio/build/$1/firmware.zip
cp $DFUPKG $OUTDIR/$basename-ota.zip
echo "Copying NRF52 dfu (OTA) file" echo "Generating NRF52 uf2 file"
cp $BUILDDIR/$basename.zip $OUTDIR/$basename.zip SRCHEX=.pio/build/$1/firmware.hex
echo "Copying NRF52 UF2 file" # if WM1110 target, merge hex with softdevice 7.3.0
cp $BUILDDIR/$basename.uf2 $OUTDIR/$basename.uf2
cp bin/*.uf2 $OUTDIR/
SRCHEX=$BUILDDIR/$basename.hex
# if WM1110 target, copy the merged.hex
if (echo $1 | grep -q "wio-sdk-wm1110"); then if (echo $1 | grep -q "wio-sdk-wm1110"); then
echo "Copying .merged.hex file" echo "Merging with softdevice"
SRCHEX=$BUILDDIR/$basename.merged.hex bin/mergehex -m bin/s140_nrf52_7.3.0_softdevice.hex $SRCHEX -o .pio/build/$1/$basename.hex
cp $SRCHEX $OUTDIR/ SRCHEX=.pio/build/$1/$basename.hex
bin/uf2conv.py $SRCHEX -c -o $OUTDIR/$basename.uf2 -f 0xADA52840
cp $SRCHEX $OUTDIR
cp bin/*.uf2 $OUTDIR
else
bin/uf2conv.py $SRCHEX -c -o $OUTDIR/$basename.uf2 -f 0xADA52840
cp bin/device-install.* $OUTDIR
cp bin/device-update.* $OUTDIR
cp bin/*.uf2 $OUTDIR
fi fi
if (echo $1 | grep -q "rak4631"); then if (echo $1 | grep -q "rak4631"); then
echo "Copying .hex file" echo "Copying hex file"
cp $SRCHEX $OUTDIR/ cp .pio/build/$1/firmware.hex $OUTDIR/$basename.hex
fi fi
# Generate the manifest file
echo "Generating Meshtastic manifest"
TIMEFORMAT="Generated manifest in %E seconds"
time pio run --environment $1 -t mtjson --silent --disable-auto-clean
cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json

View File

@@ -5,8 +5,7 @@ set -e
VERSION=`bin/buildinfo.py long` VERSION=`bin/buildinfo.py long`
SHORT_VERSION=`bin/buildinfo.py short` SHORT_VERSION=`bin/buildinfo.py short`
BUILDDIR=.pio/build/$1 OUTDIR=release/
OUTDIR=release
rm -f $OUTDIR/firmware* rm -f $OUTDIR/firmware*
rm -r $OUTDIR/* || true rm -r $OUTDIR/* || true
@@ -15,7 +14,7 @@ rm -r $OUTDIR/* || true
platformio pkg install -e $1 platformio pkg install -e $1
echo "Building for $1 with $PLATFORMIO_BUILD_FLAGS" echo "Building for $1 with $PLATFORMIO_BUILD_FLAGS"
rm -f $BUILDDIR/firmware* rm -f .pio/build/$1/firmware.*
# The shell vars the build tool expects to find # The shell vars the build tool expects to find
export APP_VERSION=$VERSION export APP_VERSION=$VERSION
@@ -23,14 +22,12 @@ export APP_VERSION=$VERSION
basename=firmware-$1-$VERSION basename=firmware-$1-$VERSION
pio run --environment $1 # -v pio run --environment $1 # -v
SRCELF=.pio/build/$1/firmware.elf
cp $BUILDDIR/$basename.elf $OUTDIR/$basename.elf cp $SRCELF $OUTDIR/$basename.elf
echo "Copying uf2 file" echo "Copying uf2 file"
cp $BUILDDIR/$basename.uf2 $OUTDIR/$basename.uf2 SRCBIN=.pio/build/$1/firmware.uf2
cp $SRCBIN $OUTDIR/$basename.uf2
# Generate the manifest file cp bin/device-install.* $OUTDIR
echo "Generating Meshtastic manifest" cp bin/device-update.* $OUTDIR
TIMEFORMAT="Generated manifest in %E seconds"
time pio run --environment $1 -t mtjson --silent --disable-auto-clean
cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json

View File

@@ -5,8 +5,7 @@ set -e
VERSION=$(bin/buildinfo.py long) VERSION=$(bin/buildinfo.py long)
SHORT_VERSION=$(bin/buildinfo.py short) SHORT_VERSION=$(bin/buildinfo.py short)
BUILDDIR=.pio/build/$1 OUTDIR=release/
OUTDIR=release
rm -f $OUTDIR/firmware* rm -f $OUTDIR/firmware*
rm -r $OUTDIR/* || true rm -r $OUTDIR/* || true
@@ -15,7 +14,7 @@ rm -r $OUTDIR/* || true
platformio pkg install -e $1 platformio pkg install -e $1
echo "Building for $1 with $PLATFORMIO_BUILD_FLAGS" echo "Building for $1 with $PLATFORMIO_BUILD_FLAGS"
rm -f $BUILDDIR/firmware* rm -f .pio/build/$1/firmware.*
# The shell vars the build tool expects to find # The shell vars the build tool expects to find
export APP_VERSION=$VERSION export APP_VERSION=$VERSION
@@ -23,14 +22,8 @@ export APP_VERSION=$VERSION
basename=firmware-$1-$VERSION basename=firmware-$1-$VERSION
pio run --environment $1 # -v pio run --environment $1 # -v
SRCELF=.pio/build/$1/firmware.elf
cp $SRCELF $OUTDIR/$basename.elf
cp $BUILDDIR/$basename.elf $OUTDIR/$basename.elf SRCBIN=.pio/build/$1/firmware.bin
cp $SRCBIN $OUTDIR/$basename.bin
echo "Copying STM32 bin file"
cp $BUILDDIR/$basename.bin $OUTDIR/$basename.bin
# Generate the manifest file
echo "Generating Meshtastic manifest"
TIMEFORMAT="Generated manifest in %E seconds"
time pio run --environment $1 -t mtjson --silent --disable-auto-clean
cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json

View File

@@ -1,8 +0,0 @@
Lora:
### RAK13300in Slot 2 pins
IRQ: 18 #IO6
Reset: 24 # IO4
Busy: 19 # IO5
# Ant_sw: 23 # IO3
spidev: spidev0.1
# CS: 7

View File

@@ -10,3 +10,12 @@ Lora:
DIO2_AS_RF_SWITCH: true DIO2_AS_RF_SWITCH: true
spidev: spidev0.0 spidev: spidev0.0
# CS: 8 # CS: 8
### RAK13300in Slot 2 pins
# IRQ: 18 #IO6
# Reset: 24 # IO4
# Busy: 19 # IO5
# # Ant_sw: 23 # IO3
# spidev: spidev0.1
# # CS: 7

View File

@@ -5,14 +5,20 @@ TITLE Meshtastic device-install
SET "SCRIPT_NAME=%~nx0" SET "SCRIPT_NAME=%~nx0"
SET "DEBUG=0" SET "DEBUG=0"
SET "PYTHON=" SET "PYTHON="
SET "TFT_BUILD=0"
SET "BIGDB8=0"
SET "BIGDB16=0"
SET "ESPTOOL_BAUD=115200" SET "ESPTOOL_BAUD=115200"
SET "ESPTOOL_CMD=" SET "ESPTOOL_CMD="
SET "LOGCOUNTER=0" SET "LOGCOUNTER=0"
SET "BPS_RESET=0" SET "BPS_RESET=0"
@REM Default offsets.
@REM https://github.com/meshtastic/web-flasher/blob/main/stores/firmwareStore.ts#L202 @REM FIXME: Determine mcu from PlatformIO variant, this is unmaintainable.
SET "OTA_OFFSET=0x260000" SET "S3=s3 v3 t-deck wireless-paper wireless-tracker station-g2 unphone"
SET "SPIFFS_OFFSET=0x300000" SET "C3=esp32c3"
@REM FIXME: Determine flash size from PlatformIO variant, this is unmaintainable.
SET "BIGDB_8MB=picomputer-s3 unphone seeed-sensecap-indicator crowpanel-esp32s3 heltec_capsule_sensor_v3 heltec-v3 heltec-vision-master-e213 heltec-vision-master-e290 heltec-vision-master-t190 heltec-wireless-paper heltec-wireless-tracker heltec-wsl-v3 icarus seeed-xiao-s3 tbeam-s3-core tracksenger"
SET "BIGDB_16MB=t-deck mesh-tab t-energy-s3 dreamcatcher ESP32-S3-Pico m5stack-cores3 station-g2 t-eth-elite t-watch-s3"
GOTO getopts GOTO getopts
:help :help
@@ -21,7 +27,7 @@ ECHO.
ECHO Usage: %SCRIPT_NAME% -f filename [-p PORT] [-P python] [--1200bps-reset] ECHO Usage: %SCRIPT_NAME% -f filename [-p PORT] [-P python] [--1200bps-reset]
ECHO. ECHO.
ECHO Options: ECHO Options:
ECHO -f filename The firmware .factory.bin file to flash. Custom to your device type and region. (required) ECHO -f filename The firmware .bin file to flash. Custom to your device type and region. (required)
ECHO The file must be located in this current directory. ECHO The file must be located in this current directory.
ECHO -p PORT Set the environment variable for ESPTOOL_PORT. ECHO -p PORT Set the environment variable for ESPTOOL_PORT.
ECHO If not set, ESPTOOL iterates all ports (Dangerous). ECHO If not set, ESPTOOL iterates all ports (Dangerous).
@@ -32,12 +38,12 @@ ECHO --1200bps-reset Attempt to place the device in correct mode. (1200bps
ECHO Some hardware requires this twice. ECHO Some hardware requires this twice.
ECHO. ECHO.
ECHO Example: %SCRIPT_NAME% -p COM17 --1200bps-reset ECHO Example: %SCRIPT_NAME% -p COM17 --1200bps-reset
ECHO Example: %SCRIPT_NAME% -f firmware-t-deck-tft-2.6.0.0b106d4.factory.bin -p COM11 ECHO Example: %SCRIPT_NAME% -f firmware-t-deck-tft-2.6.0.0b106d4.bin -p COM11
ECHO Example: %SCRIPT_NAME% -f firmware-unphone-2.6.0.0b106d4.factory.bin -p COM11 ECHO Example: %SCRIPT_NAME% -f firmware-unphone-2.6.0.0b106d4.bin -p COM11
GOTO eof GOTO eof
:version :version
ECHO %SCRIPT_NAME% [Version 2.7.0] ECHO %SCRIPT_NAME% [Version 2.6.2]
ECHO Meshtastic ECHO Meshtastic
GOTO eof GOTO eof
@@ -70,8 +76,8 @@ IF "__!FILENAME!__"=="____" (
CALL :LOG_MESSAGE ERROR "Filename containing spaces are not supported." CALL :LOG_MESSAGE ERROR "Filename containing spaces are not supported."
GOTO help GOTO help
) )
IF NOT "__!FILENAME:.factory.bin=!__"=="__!FILENAME!__" ( IF "__!FILENAME:firmware-=!__"=="__!FILENAME!__" (
CALL :LOG_MESSAGE ERROR "Filename must be a firmware-*.factory.bin file." CALL :LOG_MESSAGE ERROR "Filename must be a firmware-* file."
GOTO help GOTO help
) )
@REM Remove ".\" or "./" file prefix if present. @REM Remove ".\" or "./" file prefix if present.
@@ -85,36 +91,23 @@ IF NOT EXIST !FILENAME! (
GOTO eof GOTO eof
) )
CALL :LOG_MESSAGE DEBUG "Checking for metadata..." IF NOT "!FILENAME:update=!"=="!FILENAME!" (
@REM Derive metadata filename from firmware filename. CALL :LOG_MESSAGE DEBUG "We are working with a *update* file. !FILENAME!"
SET "METAFILE=!FILENAME:.factory.bin=!.mt.json" CALL :LOG_MESSAGE INFO "Use script device-update.bat to flash update !FILENAME!."
IF EXIST !METAFILE! (
@REM Print parsed json with powershell
CALL :LOG_MESSAGE INFO "Firmware metadata: !METAFILE!"
powershell -NoProfile -Command "(Get-Content '!METAFILE!' | ConvertFrom-Json | Out-String).Trim()"
@REM Save metadata values to variables for later use.
FOR /f "usebackq" %%A IN (`powershell -NoProfile -Command ^
"(Get-Content '!METAFILE!' | ConvertFrom-Json).mcu"`) DO SET "MCU=%%A"
FOR /f "usebackq" %%A IN (`powershell -NoProfile -Command ^
"(Get-Content '!METAFILE!' | ConvertFrom-Json).part | Where-Object { $_.subtype -eq 'ota_1' } | Select-Object -ExpandProperty offset"`
) DO SET "OTA_OFFSET=%%A"
FOR /f "usebackq" %%A IN (`powershell -NoProfile -Command ^
"(Get-Content '!METAFILE!' | ConvertFrom-Json).part | Where-Object { $_.subtype -eq 'spiffs' } | Select-Object -ExpandProperty offset"`
) DO SET "SPIFFS_OFFSET=%%A"
) ELSE (
CALL :LOG_MESSAGE ERROR "No metadata file found: !METAFILE!"
GOTO eof GOTO eof
) ELSE (
CALL :LOG_MESSAGE DEBUG "We are NOT working with a *update* file. !FILENAME!"
) )
:skip-filename :skip-filename
SET "ESPTOOL_BAUD=1200"
CALL :LOG_MESSAGE DEBUG "Determine the correct esptool command to use..." CALL :LOG_MESSAGE DEBUG "Determine the correct esptool command to use..."
IF NOT "__%PYTHON%__"=="____" ( IF NOT "__%PYTHON%__"=="____" (
SET "ESPTOOL_CMD=!PYTHON! -m esptool" SET "ESPTOOL_CMD=!PYTHON! -m esptool"
CALL :LOG_MESSAGE DEBUG "Python interpreter supplied." CALL :LOG_MESSAGE DEBUG "Python interpreter supplied."
) ELSE ( ) ELSE (
CALL :LOG_MESSAGE DEBUG "Python interpreter NOT supplied. Looking for esptool..." CALL :LOG_MESSAGE DEBUG "Python interpreter NOT supplied. Looking for esptool...
WHERE esptool >nul 2>&1 WHERE esptool >nul 2>&1
IF %ERRORLEVEL% EQU 0 ( IF %ERRORLEVEL% EQU 0 (
@REM WHERE exits with code 0 if esptool is found. @REM WHERE exits with code 0 if esptool is found.
@@ -127,10 +120,11 @@ IF NOT "__%PYTHON%__"=="____" (
CALL :LOG_MESSAGE DEBUG "Checking esptool command !ESPTOOL_CMD!..." CALL :LOG_MESSAGE DEBUG "Checking esptool command !ESPTOOL_CMD!..."
!ESPTOOL_CMD! >nul 2>&1 !ESPTOOL_CMD! >nul 2>&1
IF %ERRORLEVEL% EQU 9009 ( IF %ERRORLEVEL% GEQ 2 (
@REM 9009 = command not found on Windows @REM esptool exits with code 1 if help is displayed.
CALL :LOG_MESSAGE ERROR "esptool not found: !ESPTOOL_CMD!" CALL :LOG_MESSAGE ERROR "esptool not found: !ESPTOOL_CMD!"
EXIT /B 1 EXIT /B 1
GOTO eof
) )
IF %DEBUG% EQU 1 ( IF %DEBUG% EQU 1 (
CALL :LOG_MESSAGE DEBUG "Skipping ESPTOOL_CMD steps." CALL :LOG_MESSAGE DEBUG "Skipping ESPTOOL_CMD steps."
@@ -148,30 +142,88 @@ CALL :LOG_MESSAGE INFO "Using esptool baud: !ESPTOOL_BAUD!."
IF %BPS_RESET% EQU 1 ( IF %BPS_RESET% EQU 1 (
@REM Attempt to change mode via 1200bps Reset. @REM Attempt to change mode via 1200bps Reset.
CALL :RUN_ESPTOOL 1200 --after no_reset read_flash_status CALL :RUN_ESPTOOL !ESPTOOL_BAUD! --after no_reset read_flash_status
GOTO eof GOTO eof
) )
@REM Extract PROGNAME from %FILENAME% for later use. @REM Check if FILENAME contains "-tft-" and set target partitionScheme accordingly.
SET "PROGNAME=!FILENAME:.factory.bin=!" @REM https://github.com/meshtastic/web-flasher/blob/main/types/resources.ts#L3
CALL :LOG_MESSAGE DEBUG "Computed PROGNAME: !PROGNAME!" IF NOT "!FILENAME:-tft-=!"=="!FILENAME!" (
CALL :LOG_MESSAGE DEBUG "We are working with a *-tft-* file. !FILENAME!"
IF "__!MCU!__" == "__esp32s3__" ( SET "TFT_BUILD=1"
@REM We are working with ESP32-S3
SET "OTA_FILENAME=bleota-s3.bin"
) ELSE IF "__!MCU!__" == "__esp32c3__" (
@REM We are working with ESP32-C3
SET "OTA_FILENAME=bleota-c3.bin"
) ELSE ( ) ELSE (
@REM Everything else CALL :LOG_MESSAGE DEBUG "We are NOT working with a *-tft-* file. !FILENAME!"
SET "OTA_FILENAME=bleota.bin"
) )
FOR %%a IN (%BIGDB_8MB%) DO (
IF NOT "!FILENAME:%%a=!"=="!FILENAME!" (
@REM We are working with any of %BIGDB_8MB%.
SET "BIGDB8=1"
GOTO end_loop_bigdb_8mb
)
)
:end_loop_bigdb_8mb
FOR %%a IN (%BIGDB_16MB%) DO (
IF NOT "!FILENAME:%%a=!"=="!FILENAME!" (
@REM We are working with any of %BIGDB_16MB%.
SET "BIGDB16=1"
GOTO end_loop_bigdb_16mb
)
)
:end_loop_bigdb_16mb
IF %BIGDB8% EQU 1 CALL :LOG_MESSAGE INFO "BigDB 8mb partition selected."
IF %BIGDB16% EQU 1 CALL :LOG_MESSAGE INFO "BigDB 16mb partition selected."
@REM Extract BASENAME from %FILENAME% for later use.
SET "BASENAME=!FILENAME:firmware-=!"
CALL :LOG_MESSAGE DEBUG "Computed firmware basename: !BASENAME!"
@REM Account for S3 and C3 board's different OTA partition.
FOR %%a IN (%S3%) DO (
IF NOT "!FILENAME:%%a=!"=="!FILENAME!" (
@REM We are working with any of %S3%.
SET "OTA_FILENAME=bleota-s3.bin"
GOTO :end_loop_s3
)
)
FOR %%a IN (%C3%) DO (
IF NOT "!FILENAME:%%a=!"=="!FILENAME!" (
@REM We are working with any of %C3%.
SET "OTA_FILENAME=bleota-c3.bin"
GOTO :end_loop_c3
)
)
@REM Everything else
SET "OTA_FILENAME=bleota.bin"
:end_loop_s3
:end_loop_c3
CALL :LOG_MESSAGE DEBUG "Set OTA_FILENAME to: !OTA_FILENAME!" CALL :LOG_MESSAGE DEBUG "Set OTA_FILENAME to: !OTA_FILENAME!"
@REM Set SPIFFS filename with "littlefs-" prefix. @REM Set SPIFFS filename with "littlefs-" prefix.
SET "SPIFFS_FILENAME=littlefs-!PROGNAME:firmware-=!.bin" SET "SPIFFS_FILENAME=littlefs-%BASENAME%"
CALL :LOG_MESSAGE DEBUG "Set SPIFFS_FILENAME to: !SPIFFS_FILENAME!" CALL :LOG_MESSAGE DEBUG "Set SPIFFS_FILENAME to: !SPIFFS_FILENAME!"
@REM Default offsets.
@REM https://github.com/meshtastic/web-flasher/blob/main/stores/firmwareStore.ts#L202
SET "OTA_OFFSET=0x260000"
SET "SPIFFS_OFFSET=0x300000"
@REM Offsets for BigDB 8mb.
IF %BIGDB8% EQU 1 (
SET "OTA_OFFSET=0x340000"
SET "SPIFFS_OFFSET=0x670000"
)
@REM Offsets for BigDB 16mb.
IF %BIGDB16% EQU 1 (
SET "OTA_OFFSET=0x650000"
SET "SPIFFS_OFFSET=0xc90000"
)
CALL :LOG_MESSAGE DEBUG "Set OTA_OFFSET to: !OTA_OFFSET!" CALL :LOG_MESSAGE DEBUG "Set OTA_OFFSET to: !OTA_OFFSET!"
CALL :LOG_MESSAGE DEBUG "Set SPIFFS_OFFSET to: !SPIFFS_OFFSET!" CALL :LOG_MESSAGE DEBUG "Set SPIFFS_OFFSET to: !SPIFFS_OFFSET!"

View File

@@ -1,16 +1,62 @@
#!/usr/bin/env bash #!/bin/bash
PYTHON=${PYTHON:-$(which python3 python | head -n 1)} PYTHON=${PYTHON:-$(which python3 python | head -n 1)}
BPS_RESET=false BPS_RESET=false
TFT_BUILD=false
MCU="" MCU=""
# Constants # Variant groups
RESET_BAUD=1200 BIGDB_8MB=(
FIRMWARE_OFFSET=0x00 "picomputer-s3"
# Default littlefs* offset. "unphone"
OFFSET=0x300000 "seeed-sensecap-indicator"
# Default OTA Offset "crowpanel-esp32s3"
OTA_OFFSET=0x260000 "heltec_capsule_sensor_v3"
"heltec-v3"
"heltec-vision-master-e213"
"heltec-vision-master-e290"
"heltec-vision-master-t190"
"heltec-wireless-paper"
"heltec-wireless-tracker"
"heltec-wsl-v3"
"icarus"
"seeed-xiao-s3"
"tbeam-s3-core"
"tracksenger"
)
BIGDB_16MB=(
"t-deck"
"mesh-tab"
"t-energy-s3"
"dreamcatcher"
"ESP32-S3-Pico"
"m5stack-cores3"
"station-g2"
"t-eth-elite"
"t-watch-s3"
"elecrow-adv-35-tft"
"elecrow-adv-24-28-tft"
"elecrow-adv1-43-50-70-tft"
)
S3_VARIANTS=(
"s3"
"-v3"
"t-deck"
"wireless-paper"
"wireless-tracker"
"station-g2"
"unphone"
"t-eth-elite"
"mesh-tab"
"dreamcatcher"
"ESP32-S3-Pico"
"seeed-sensecap-indicator"
"heltec_capsule_sensor_v3"
"vision-master"
"icarus"
"tracksenger"
"elecrow-adv"
)
# Determine the correct esptool command to use # Determine the correct esptool command to use
if "$PYTHON" -m esptool version >/dev/null 2>&1; then if "$PYTHON" -m esptool version >/dev/null 2>&1; then
@@ -24,14 +70,6 @@ else
exit 1 exit 1
fi fi
# Check for jq
if ! command -v jq >/dev/null 2>&1; then
echo "Error: jq not found" >&2
echo "Install jq with your package manager." >&2
echo "e.g. 'apt install jq', 'dnf install jq', 'brew install jq', etc." >&2
exit 1
fi
set -e set -e
# Usage info # Usage info
@@ -43,7 +81,7 @@ Flash image file to device, but first erasing and writing system information.
-h Display this help and exit. -h Display this help and exit.
-p ESPTOOL_PORT Set the environment variable for ESPTOOL_PORT. If not set, ESPTOOL iterates all ports (Dangerous). -p ESPTOOL_PORT Set the environment variable for ESPTOOL_PORT. If not set, ESPTOOL iterates all ports (Dangerous).
-P PYTHON Specify alternate python interpreter to use to invoke esptool. (Default: "$PYTHON") -P PYTHON Specify alternate python interpreter to use to invoke esptool. (Default: "$PYTHON")
-f FILENAME The firmware *.factory.bin file to flash. Custom to your device type and region. -f FILENAME The firmware .bin file to flash. Custom to your device type and region.
--1200bps-reset Attempt to place the device in correct mode. Some hardware requires this twice. (1200bps Reset) --1200bps-reset Attempt to place the device in correct mode. Some hardware requires this twice. (1200bps Reset)
EOF EOF
@@ -68,8 +106,8 @@ while [ $# -gt 0 ]; do
shift shift
;; ;;
--1200bps-reset) --1200bps-reset)
BPS_RESET=true BPS_RESET=true
;; ;;
--) # Stop parsing options --) # Stop parsing options
shift shift
break break
@@ -83,7 +121,7 @@ while [ $# -gt 0 ]; do
done done
if [[ $BPS_RESET == true ]]; then if [[ $BPS_RESET == true ]]; then
$ESPTOOL_CMD --baud $RESET_BAUD --after no_reset read_flash_status $ESPTOOL_CMD --baud 1200 --after no_reset read_flash_status
exit 0 exit 0
fi fi
@@ -92,43 +130,62 @@ fi
shift shift
} }
if [[ $(basename "$FILENAME") != firmware-*.factory.bin ]]; then if [[ "$FILENAME" != firmware-* ]]; then
echo "Filename must be a firmware-*.factory.bin file." echo "Filename must be a firmware-* file."
exit 1 exit 1
fi fi
# Extract PROGNAME from %FILENAME% for later use. # Check if FILENAME contains "-tft-" and set target partitionScheme accordingly.
PROGNAME="${FILENAME/.factory.bin/}" if [[ "${FILENAME//-tft-/}" != "$FILENAME" ]]; then
# Derive metadata filename from %PROGNAME%. TFT_BUILD=true
METAFILE="${PROGNAME}.mt.json" fi
if [[ -f "$FILENAME" && "$FILENAME" == *.factory.bin ]]; then # Extract BASENAME from %FILENAME% for later use.
# Display metadata if it exists BASENAME="${FILENAME/firmware-/}"
if [[ -f "$METAFILE" ]]; then
echo "Firmware metadata: ${METAFILE}" if [ -f "${FILENAME}" ] && [ -n "${FILENAME##*"update"*}" ]; then
jq . "$METAFILE" # Default littlefs* offset.
# Extract relevant fields from metadata OFFSET=0x300000
if [[ $(jq -r '.part' "$METAFILE") != "null" ]]; then
OTA_OFFSET=$(jq -r '.part[] | select(.subtype == "ota_1") | .offset' "$METAFILE") # Default OTA Offset
SPIFFS_OFFSET=$(jq -r '.part[] | select(.subtype == "spiffs") | .offset' "$METAFILE") OTA_OFFSET=0x260000
# littlefs* offset for BigDB 8mb and OTA OFFSET.
for variant in "${BIGDB_8MB[@]}"; do
if [ -z "${FILENAME##*"$variant"*}" ]; then
OFFSET=0x670000
OTA_OFFSET=0x340000
fi fi
MCU=$(jq -r '.mcu' "$METAFILE") done
else
echo "ERROR: No metadata file found at ${METAFILE}"
exit 1
fi
# Determine OTA filename based on MCU type # littlefs* offset for BigDB 16mb and OTA OFFSET.
if [ "$MCU" == "esp32s3" ]; then for variant in "${BIGDB_16MB[@]}"; do
OTAFILE=bleota-s3.bin if [ -z "${FILENAME##*"$variant"*}" ]; then
elif [ "$MCU" == "esp32c3" ]; then OFFSET=0xc90000
OTAFILE=bleota-c3.bin OTA_OFFSET=0x650000
fi
done
# Account for S3 board's different OTA partition
# FIXME: Use PlatformIO info to determine MCU type, this is unmaintainable
for variant in "${S3_VARIANTS[@]}"; do
if [ -z "${FILENAME##*"$variant"*}" ]; then
MCU="esp32s3"
fi
done
if [ "$MCU" != "esp32s3" ]; then
if [ -n "${FILENAME##*"esp32c3"*}" ]; then
OTAFILE=bleota.bin
else
OTAFILE=bleota-c3.bin
fi
else else
OTAFILE=bleota.bin OTAFILE=bleota-s3.bin
fi fi
# Set SPIFFS filename with "littlefs-" prefix. # Set SPIFFS filename with "littlefs-" prefix.
SPIFFSFILE="littlefs-${PROGNAME/firmware-/}.bin" SPIFFSFILE=littlefs-${BASENAME}
if [[ ! -f "$FILENAME" ]]; then if [[ ! -f "$FILENAME" ]]; then
echo "Error: file ${FILENAME} wasn't found. Terminating." echo "Error: file ${FILENAME} wasn't found. Terminating."
@@ -144,8 +201,8 @@ if [[ -f "$FILENAME" && "$FILENAME" == *.factory.bin ]]; then
fi fi
echo "Trying to flash ${FILENAME}, but first erasing and writing system information" echo "Trying to flash ${FILENAME}, but first erasing and writing system information"
$ESPTOOL_CMD erase-flash $ESPTOOL_CMD erase_flash
$ESPTOOL_CMD write-flash $FIRMWARE_OFFSET "${FILENAME}" $ESPTOOL_CMD write_flash 0x00 "${FILENAME}"
echo "Trying to flash ${OTAFILE} at offset ${OTA_OFFSET}" echo "Trying to flash ${OTAFILE} at offset ${OTA_OFFSET}"
$ESPTOOL_CMD write_flash $OTA_OFFSET "${OTAFILE}" $ESPTOOL_CMD write_flash $OTA_OFFSET "${OTAFILE}"
echo "Trying to flash ${SPIFFSFILE}, at offset ${OFFSET}" echo "Trying to flash ${SPIFFSFILE}, at offset ${OFFSET}"

View File

@@ -6,8 +6,6 @@ SET "SCRIPT_NAME=%~nx0"
SET "DEBUG=0" SET "DEBUG=0"
SET "PYTHON=" SET "PYTHON="
SET "ESPTOOL_BAUD=115200" SET "ESPTOOL_BAUD=115200"
SET "RESET_BAUD=1200"
SET "UPDATE_OFFSET=0x10000"
SET "ESPTOOL_CMD=" SET "ESPTOOL_CMD="
SET "LOGCOUNTER=0" SET "LOGCOUNTER=0"
SET "CHANGE_MODE=0" SET "CHANGE_MODE=0"
@@ -30,11 +28,11 @@ ECHO --change-mode Attempt to place the device in correct mode. (1200bps
ECHO Some hardware requires this twice. ECHO Some hardware requires this twice.
ECHO. ECHO.
ECHO Example: %SCRIPT_NAME% -p COM17 --change-mode ECHO Example: %SCRIPT_NAME% -p COM17 --change-mode
ECHO Example: %SCRIPT_NAME% -f firmware-t-deck-tft-2.6.0.0b106d4.bin -p COM11 ECHO Example: %SCRIPT_NAME% -f firmware-t-deck-tft-2.6.0.0b106d4-update.bin -p COM11
GOTO eof GOTO eof
:version :version
ECHO %SCRIPT_NAME% [Version 2.7.0] ECHO %SCRIPT_NAME% [Version 2.6.2]
ECHO Meshtastic ECHO Meshtastic
GOTO eof GOTO eof
@@ -78,22 +76,23 @@ IF NOT EXIST !FILENAME! (
GOTO eof GOTO eof
) )
IF NOT "__!FILENAME:.factory.bin=!__"=="__!FILENAME!__" ( IF "!FILENAME:update=!"=="!FILENAME!" (
CALL :LOG_MESSAGE DEBUG "We are working with a *.factory.bin* file. !FILENAME!" CALL :LOG_MESSAGE DEBUG "We are NOT working with a *update* file. !FILENAME!"
CALL :LOG_MESSAGE INFO "Use script device-install.bat to flash !FILENAME!." CALL :LOG_MESSAGE INFO "Use script device-install.bat to flash !FILENAME!."
GOTO eof GOTO eof
) ELSE ( ) ELSE (
CALL :LOG_MESSAGE DEBUG "We are not working with a *.factory.bin* file. !FILENAME!" CALL :LOG_MESSAGE DEBUG "We are working with a *update* file. !FILENAME!"
) )
:skip-filename :skip-filename
SET "ESPTOOL_BAUD=1200"
CALL :LOG_MESSAGE DEBUG "Determine the correct esptool command to use..." CALL :LOG_MESSAGE DEBUG "Determine the correct esptool command to use..."
IF NOT "__%PYTHON%__"=="____" ( IF NOT "__%PYTHON%__"=="____" (
SET "ESPTOOL_CMD=""!PYTHON!"" -m esptool" SET "ESPTOOL_CMD=!PYTHON! -m esptool"
CALL :LOG_MESSAGE DEBUG "Python interpreter supplied." CALL :LOG_MESSAGE DEBUG "Python interpreter supplied."
) ELSE ( ) ELSE (
CALL :LOG_MESSAGE DEBUG "Python interpreter NOT supplied. Looking for esptool..." CALL :LOG_MESSAGE DEBUG "Python interpreter NOT supplied. Looking for esptool...
WHERE esptool >nul 2>&1 WHERE esptool >nul 2>&1
IF %ERRORLEVEL% EQU 0 ( IF %ERRORLEVEL% EQU 0 (
@REM WHERE exits with code 0 if esptool is found. @REM WHERE exits with code 0 if esptool is found.
@@ -106,11 +105,11 @@ IF NOT "__%PYTHON%__"=="____" (
CALL :LOG_MESSAGE DEBUG "Checking esptool command !ESPTOOL_CMD!..." CALL :LOG_MESSAGE DEBUG "Checking esptool command !ESPTOOL_CMD!..."
!ESPTOOL_CMD! >nul 2>&1 !ESPTOOL_CMD! >nul 2>&1
CALL :LOG_MESSAGE DEBUG "esptool exit code: %ERRORLEVEL%" IF %ERRORLEVEL% GEQ 2 (
IF %ERRORLEVEL% EQU 9009 ( @REM esptool exits with code 1 if help is displayed.
@REM 9009 = command not found on Windows
CALL :LOG_MESSAGE ERROR "esptool not found: !ESPTOOL_CMD!" CALL :LOG_MESSAGE ERROR "esptool not found: !ESPTOOL_CMD!"
EXIT /B 1 EXIT /B 1
GOTO eof
) )
IF %DEBUG% EQU 1 ( IF %DEBUG% EQU 1 (
CALL :LOG_MESSAGE DEBUG "Skipping ESPTOOL_CMD steps." CALL :LOG_MESSAGE DEBUG "Skipping ESPTOOL_CMD steps."
@@ -128,13 +127,13 @@ CALL :LOG_MESSAGE INFO "Using esptool baud: !ESPTOOL_BAUD!."
IF %CHANGE_MODE% EQU 1 ( IF %CHANGE_MODE% EQU 1 (
@REM Attempt to change mode via 1200bps Reset. @REM Attempt to change mode via 1200bps Reset.
CALL :RUN_ESPTOOL !RESET_BAUD! --after no_reset read_flash_status CALL :RUN_ESPTOOL !ESPTOOL_BAUD! --after no_reset read_flash_status
GOTO eof GOTO eof
) )
@REM Flashing operations. @REM Flashing operations.
CALL :LOG_MESSAGE INFO "Trying to flash update "!FILENAME!" at OFFSET !UPDATE_OFFSET!..." CALL :LOG_MESSAGE INFO "Trying to flash update "!FILENAME!" at OFFSET 0x10000..."
CALL :RUN_ESPTOOL !ESPTOOL_BAUD! write-flash !UPDATE_OFFSET! "!FILENAME!" || GOTO eof CALL :RUN_ESPTOOL !ESPTOOL_BAUD! write_flash 0x10000 "!FILENAME!" || GOTO eof
CALL :LOG_MESSAGE INFO "Script complete!." CALL :LOG_MESSAGE INFO "Script complete!."
@@ -146,9 +145,9 @@ EXIT /B %ERRORLEVEL%
:RUN_ESPTOOL :RUN_ESPTOOL
@REM Subroutine used to run ESPTOOL_CMD with arguments. @REM Subroutine used to run ESPTOOL_CMD with arguments.
@REM Also handles %ERRORLEVEL%. @REM Also handles %ERRORLEVEL%.
@REM CALL :RUN_ESPTOOL [Baud] [erase-flash|write-flash] [OFFSET] [Filename] @REM CALL :RUN_ESPTOOL [Baud] [erase_flash|write_flash] [OFFSET] [Filename]
@REM. @REM.
@REM Example:: CALL :RUN_ESPTOOL 115200 write-flash 0x10000 "firmwarefile.bin" @REM Example:: CALL :RUN_ESPTOOL 115200 write_flash 0x10000 "firmwarefile.bin"
IF %DEBUG% EQU 1 CALL :LOG_MESSAGE DEBUG "About to run command: !ESPTOOL_CMD! --baud %~1 %~2 %~3 %~4" IF %DEBUG% EQU 1 CALL :LOG_MESSAGE DEBUG "About to run command: !ESPTOOL_CMD! --baud %~1 %~2 %~3 %~4"
CALL :RESET_ERROR CALL :RESET_ERROR
!ESPTOOL_CMD! --baud %~1 %~2 %~3 %~4 !ESPTOOL_CMD! --baud %~1 %~2 %~3 %~4

View File

@@ -1,13 +1,8 @@
#!/usr/bin/env bash #!/bin/sh
PYTHON=${PYTHON:-$(which python3 python|head -n 1)} PYTHON=${PYTHON:-$(which python3 python|head -n 1)}
CHANGE_MODE=false CHANGE_MODE=false
# Constants
FLASH_BAUD=115200
RESET_BAUD=1200
UPDATE_OFFSET=0x10000
# Determine the correct esptool command to use # Determine the correct esptool command to use
if "$PYTHON" -m esptool version >/dev/null 2>&1; then if "$PYTHON" -m esptool version >/dev/null 2>&1; then
ESPTOOL_CMD="$PYTHON -m esptool" ESPTOOL_CMD="$PYTHON -m esptool"
@@ -29,7 +24,7 @@ Flash image file to device, leave existing system intact."
-h Display this help and exit -h Display this help and exit
-p ESPTOOL_PORT Set the environment variable for ESPTOOL_PORT. If not set, ESPTOOL iterates all ports (Dangerous). -p ESPTOOL_PORT Set the environment variable for ESPTOOL_PORT. If not set, ESPTOOL iterates all ports (Dangerous).
-P PYTHON Specify alternate python interpreter to use to invoke esptool. (Default: "$PYTHON") -P PYTHON Specify alternate python interpreter to use to invoke esptool. (Default: "$PYTHON")
-f FILENAME The *.bin file to flash. Custom to your device type. -f FILENAME The *update.bin file to flash. Custom to your device type.
--change-mode Attempt to place the device in correct mode. Some hardware requires this twice. (1200bps Reset) --change-mode Attempt to place the device in correct mode. Some hardware requires this twice. (1200bps Reset)
EOF EOF
@@ -69,7 +64,7 @@ done
shift "$((OPTIND-1))" shift "$((OPTIND-1))"
if [ "$CHANGE_MODE" = true ]; then if [ "$CHANGE_MODE" = true ]; then
$ESPTOOL_CMD --baud $RESET_BAUD --after no_reset read_flash_status $ESPTOOL_CMD --baud 1200 --after no_reset read_flash_status
exit 0 exit 0
fi fi
@@ -78,9 +73,9 @@ fi
shift shift
} }
if [[ -f "$FILENAME" && "$FILENAME" != *.factory.bin ]]; then if [ -f "${FILENAME}" ] && [ -z "${FILENAME##*"update"*}" ]; then
echo "Trying to flash update ${FILENAME}" echo "Trying to flash update ${FILENAME}"
$ESPTOOL_CMD --baud $FLASH_BAUD write-flash $UPDATE_OFFSET "${FILENAME}" $ESPTOOL_CMD --baud 115200 write_flash 0x10000 "${FILENAME}"
else else
show_help show_help
echo "Invalid file: ${FILENAME}" echo "Invalid file: ${FILENAME}"

View File

@@ -75,7 +75,7 @@ TOOLS = {
} }
BACKTRACE_REGEX = re.compile( BACKTRACE_REGEX = re.compile(
r"\b(0x4[0-9a-fA-F]{7,8}):0x[0-9a-fA-F]{8}\b" r"(?:\s+(0x40[0-2](?:\d|[a-f]|[A-F]){5}):0x(?:\d|[a-f]|[A-F]){8})\b"
) )
EXCEPTION_REGEX = re.compile("^Exception \\((?P<exc>[0-9]*)\\):$") EXCEPTION_REGEX = re.compile("^Exception \\((?P<exc>[0-9]*)\\):$")
COUNTER_REGEX = re.compile( COUNTER_REGEX = re.compile(
@@ -89,7 +89,7 @@ POINTER_REGEX = re.compile(
STACK_BEGIN = ">>>stack>>>" STACK_BEGIN = ">>>stack>>>"
STACK_END = "<<<stack<<<" STACK_END = "<<<stack<<<"
STACK_REGEX = re.compile( STACK_REGEX = re.compile(
r"^(?P<off>[0-9a-f]+):\W+(?P<c1>[0-9a-f]+) (?P<c2>[0-9a-f]+) (?P<c3>[0-9a-f]+) (?P<c4>[0-9a-f]+)(\W.*)?$" "^(?P<off>[0-9a-f]+):\W+(?P<c1>[0-9a-f]+) (?P<c2>[0-9a-f]+) (?P<c3>[0-9a-f]+) (?P<c4>[0-9a-f]+)(\W.*)?$"
) )
StackLine = namedtuple("StackLine", ["offset", "content"]) StackLine = namedtuple("StackLine", ["offset", "content"])
@@ -223,7 +223,7 @@ class AddressResolver(object):
if match is None: if match is None:
if last is not None and line.startswith("(inlined by)"): if last is not None and line.startswith("(inlined by)"):
line = line[12:].strip() line = line[12:].strip()
self._address_map[last] += "\n \\-> inlined by: " + line self._address_map[last] += "\n \-> inlined by: " + line
continue continue
if match.group("result") == "?? ??:0": if match.group("result") == "?? ??:0":

View File

@@ -1,75 +1,51 @@
#!/usr/bin/env python3 #!/usr/bin/env python
"""Generate the CI matrix.""" """Generate the CI matrix."""
import argparse import configparser
import json import json
import re import os
from platformio.project.config import ProjectConfig import sys
import random
parser = argparse.ArgumentParser(description="Generate the CI matrix") rootdir = "variants/"
parser.add_argument("platform", help="Platform to build for")
parser.add_argument( options = sys.argv[1:]
"--level",
choices=["extra", "pr"],
nargs="*",
default=[],
help="Board level to build for (omit for full release boards)",
)
args = parser.parse_args()
outlist = [] outlist = []
cfg = ProjectConfig.get_instance() if len(options) < 1:
pio_envs = cfg.envs() print(json.dumps(outlist))
exit()
# Gather all PlatformIO environments for filtering later for subdir, dirs, files in os.walk(rootdir):
all_envs = [] for file in files:
for pio_env in pio_envs: if file == "platformio.ini":
env_build_flags = cfg.get(f"env:{pio_env}", "build_flags") config = configparser.ConfigParser()
env_platform = None config.read(subdir + "/" + file)
for flag in env_build_flags: for c in config.sections():
# Extract the platform from the build flags if c.startswith("env:"):
# Example flag: -I variants/esp32s3/heltec-v3 section = config[c].name[4:]
match = re.search(r"-I\s?variants/([^/]+)", flag) if "extends" in config[config[c].name]:
if match: if options[0] + "_base" in config[config[c].name]["extends"]:
env_platform = match.group(1) if "board_level" in config[config[c].name]:
break if (
# Intentionally fail if platform cannot be determined config[config[c].name]["board_level"] == "extra"
if not env_platform: ) & ("extra" in options):
print(f"Error: Could not determine platform for environment '{pio_env}'") outlist.append(section)
exit(1) else:
# Store env details as a dictionary, and add to 'all_envs' list outlist.append(section)
env = { # Add the TFT variants if the base variant is selected
"ci": {"board": pio_env, "platform": env_platform}, elif section.replace("-tft", "") in outlist and config[config[c].name].get("board_level") != "extra":
"board_level": cfg.get(f"env:{pio_env}", "board_level", default=None), outlist.append(section)
"board_check": bool(cfg.get(f"env:{pio_env}", "board_check", default=False)), elif section.replace("-inkhud", "") in outlist and config[config[c].name].get("board_level") != "extra":
} outlist.append(section)
all_envs.append(env) if "board_check" in config[config[c].name]:
if (config[config[c].name]["board_check"] == "true") & (
# Filter outputs based on options "check" in options
# Check is mutually exclusive with other options (except 'pr') ):
if "check" in args.platform: outlist.append(section)
for env in all_envs: if ("quick" in options) & (len(outlist) > 3):
if env["board_check"]: print(json.dumps(random.sample(outlist, 3)))
if "pr" in args.level:
if env["board_level"] == "pr":
outlist.append(env["ci"])
else:
outlist.append(env["ci"])
# Filter (non-check) builds by platform
else: else:
for env in all_envs: print(json.dumps(outlist))
if args.platform == env["ci"]["platform"] or args.platform == "all":
# Always include board_level = 'pr'
if env["board_level"] == "pr":
outlist.append(env["ci"])
# Include board_level = 'extra' when requested
elif "extra" in args.level and env["board_level"] == "extra":
outlist.append(env["ci"])
# If no board level is specified, include in release builds (not PR)
elif "pr" not in args.level and not env["board_level"]:
outlist.append(env["ci"])
# Return as a JSON list
print(json.dumps(outlist))

View File

@@ -1,116 +0,0 @@
#!/bin/bash
# Script to cancel all running GitHub Actions workflows
# Requires GitHub CLI (gh) to be installed and authenticated
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Function to print colored output
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Check if gh CLI is installed
if ! command -v gh &> /dev/null; then
print_error "GitHub CLI (gh) is not installed. Please install it first:"
echo " brew install gh"
echo " Or visit: https://cli.github.com/"
exit 1
fi
# Check if authenticated
if ! gh auth status &> /dev/null; then
print_error "GitHub CLI is not authenticated. Please run:"
echo " gh auth login"
exit 1
fi
# Get repository info
REPO=$(gh repo view --json owner,name -q '.owner.login + "/" + .name')
if [[ -z "$REPO" ]]; then
print_error "Could not determine repository. Make sure you're in a GitHub repository."
exit 1
fi
print_status "Working with repository: $REPO"
# Get all active workflows (both queued and in-progress)
print_status "Fetching active workflows (queued and in-progress)..."
QUEUED_WORKFLOWS=$(gh run list --status queued --json databaseId,displayTitle,headBranch,status --limit 100)
IN_PROGRESS_WORKFLOWS=$(gh run list --status in_progress --json databaseId,displayTitle,headBranch,status --limit 100)
# Combine both lists
ALL_WORKFLOWS=$(echo "$QUEUED_WORKFLOWS $IN_PROGRESS_WORKFLOWS" | jq -s 'add | unique_by(.databaseId)')
if [[ "$ALL_WORKFLOWS" == "[]" ]]; then
print_status "No active workflows found."
exit 0
fi
# Parse and display active workflows
echo
print_warning "Found active workflows:"
echo "$ALL_WORKFLOWS" | jq -r '.[] | " - \(.displayTitle) (Branch: \(.headBranch), Status: \(.status), ID: \(.databaseId))"'
echo
read -p "Do you want to cancel ALL these workflows? (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
print_status "Cancelled by user."
exit 0
fi
# Cancel each workflow
print_status "Cancelling workflows..."
CANCELLED_COUNT=0
FAILED_COUNT=0
while IFS= read -r WORKFLOW_ID; do
if [[ -n "$WORKFLOW_ID" ]]; then
print_status "Cancelling workflow ID: $WORKFLOW_ID"
if gh run cancel "$WORKFLOW_ID" 2>/dev/null; then
((CANCELLED_COUNT++))
else
print_error "Failed to cancel workflow ID: $WORKFLOW_ID"
((FAILED_COUNT++))
fi
fi
done < <(echo "$ALL_WORKFLOWS" | jq -r '.[].databaseId')
echo
print_status "Summary:"
echo " - Cancelled: $CANCELLED_COUNT workflows"
if [[ $FAILED_COUNT -gt 0 ]]; then
echo " - Failed: $FAILED_COUNT workflows"
fi
print_status "Done!"
# Optional: Show remaining active workflows
echo
print_status "Checking for any remaining active workflows..."
REMAINING_QUEUED=$(gh run list --status queued --json databaseId --limit 10)
REMAINING_IN_PROGRESS=$(gh run list --status in_progress --json databaseId --limit 10)
REMAINING_ALL=$(echo "$REMAINING_QUEUED $REMAINING_IN_PROGRESS" | jq -s 'add | unique_by(.databaseId)')
if [[ "$REMAINING_ALL" == "[]" ]]; then
print_status "All workflows successfully cancelled."
else
REMAINING_COUNT=$(echo "$REMAINING_ALL" | jq '. | length')
print_warning "Still $REMAINING_COUNT workflows active (may take a moment to update status)"
fi

View File

@@ -2,4 +2,4 @@
set -e set -e
pio run --environment native pio run --environment native
gdbserver --once localhost:2345 .pio/build/native/meshtasticd "$@" gdbserver --once localhost:2345 .pio/build/native/program "$@"

View File

@@ -2,4 +2,4 @@
set -e set -e
pio run --environment native pio run --environment native
.pio/build/native/meshtasticd "$@" .pio/build/native/program "$@"

View File

@@ -87,48 +87,6 @@
</screenshots> </screenshots>
<releases> <releases>
<release version="2.7.17" date="2025-11-28">
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.17</url>
</release>
<release version="2.7.16" date="2025-11-19">
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.16</url>
</release>
<release version="2.7.15" date="2025-11-13">
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.15</url>
</release>
<release version="2.7.14" date="2025-11-03">
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.14</url>
</release>
<release version="2.7.13" date="2025-10-11">
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.13</url>
</release>
<release version="2.7.12" date="2025-10-01">
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.12</url>
</release>
<release version="2.7.11" date="2025-09-24">
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.11</url>
</release>
<release version="2.7.10" date="2025-09-18">
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.10</url>
</release>
<release version="2.7.9" date="2025-09-03">
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.9</url>
</release>
<release version="2.7.8" date="2025-08-30">
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.8</url>
</release>
<release version="2.7.7" date="2025-08-28">
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.7</url>
</release>
<release version="2.7.6" date="2025-08-12">
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.6</url>
</release>
<release version="2.7.5" date="2025-08-09">
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.5</url>
</release>
<release version="2.7.4" date="2025-07-19">
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.4</url>
</release>
<release version="2.7.3" date="2025-07-10"> <release version="2.7.3" date="2025-07-10">
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.3</url> <url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.3</url>
</release> </release>

View File

@@ -2,88 +2,95 @@
# trunk-ignore-all(ruff/F821) # trunk-ignore-all(ruff/F821)
# trunk-ignore-all(flake8/F821): For SConstruct imports # trunk-ignore-all(flake8/F821): For SConstruct imports
import sys import sys
from os.path import join, basename, isfile from os.path import join
import subprocess
import json import json
import re import re
from datetime import datetime
from readprops import readProps from readprops import readProps
Import("env") Import("env")
platform = env.PioPlatform() platform = env.PioPlatform()
progname = env.get("PROGNAME")
lfsbin = f"{progname.replace('firmware-', 'littlefs-')}.bin"
def manifest_gather(source, target, env):
out = [] def esp32_create_combined_bin(source, target, env):
check_paths = [ # this sub is borrowed from ESPEasy build toolchain. It's licensed under GPL V3
progname, # https://github.com/letscontrolit/ESPEasy/blob/mega/tools/pio/post_esp32.py
f"{progname}.elf", print("Generating combined binary for serial flashing")
f"{progname}.bin",
f"{progname}.factory.bin", app_offset = 0x10000
f"{progname}.hex",
f"{progname}.merged.hex", new_file_name = env.subst("$BUILD_DIR/${PROGNAME}.factory.bin")
f"{progname}.uf2", sections = env.subst(env.get("FLASH_EXTRA_IMAGES"))
f"{progname}.factory.uf2", firmware_name = env.subst("$BUILD_DIR/${PROGNAME}.bin")
f"{progname}.zip", chip = env.get("BOARD_MCU")
lfsbin flash_size = env.BoardConfig().get("upload.flash_size")
flash_freq = env.BoardConfig().get("build.f_flash", "40m")
flash_freq = flash_freq.replace("000000L", "m")
flash_mode = env.BoardConfig().get("build.flash_mode", "dio")
memory_type = env.BoardConfig().get("build.arduino.memory_type", "qio_qspi")
if flash_mode == "qio" or flash_mode == "qout":
flash_mode = "dio"
if memory_type == "opi_opi" or memory_type == "opi_qspi":
flash_mode = "dout"
cmd = [
"--chip",
chip,
"merge_bin",
"-o",
new_file_name,
"--flash_mode",
flash_mode,
"--flash_freq",
flash_freq,
"--flash_size",
flash_size,
] ]
for p in check_paths:
f = env.File(env.subst(f"$BUILD_DIR/{p}"))
if f.exists():
d = {
"name": p,
"md5": f.get_content_hash(), # Returns MD5 hash
"bytes": f.get_size() # Returns file size in bytes
}
out.append(d)
print(d)
manifest_write(out, env)
def manifest_write(files, env): print(" Offset | File")
manifest = { for section in sections:
"version": verObj["long"], sect_adr, sect_file = section.split(" ", 1)
"build_epoch": build_epoch, print(f" - {sect_adr} | {sect_file}")
"board": env.get("PIOENV"), cmd += [sect_adr, sect_file]
"mcu": env.get("BOARD_MCU"),
"repo": repo_owner,
"files": files,
"part": None,
"has_mui": False,
"has_inkhud": False,
}
# Get partition table (generated in esp32_pre.py) if it exists
if env.get("custom_mtjson_part"):
# custom_mtjson_part is a JSON string, convert it back to a dict
pj = json.loads(env.get("custom_mtjson_part"))
manifest["part"] = pj
# Enable has_mui for TFT builds
if ("HAS_TFT", 1) in env.get("CPPDEFINES", []):
manifest["has_mui"] = True
if "MESHTASTIC_INCLUDE_INKHUD" in env.get("CPPDEFINES", []):
manifest["has_inkhud"] = True
# Write the manifest to the build directory print(f" - {hex(app_offset)} | {firmware_name}")
with open(env.subst("$BUILD_DIR/${PROGNAME}.mt.json"), "w") as f: cmd += [hex(app_offset), firmware_name]
json.dump(manifest, f, indent=2)
print("Using esptool.py arguments: %s" % " ".join(cmd))
esptool.main(cmd)
if platform.name == "espressif32":
sys.path.append(join(platform.get_package_dir("tool-esptoolpy")))
import esptool
env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", esp32_create_combined_bin)
esp32_kind = env.GetProjectOption("custom_esp32_kind")
if esp32_kind == "esp32":
# Free up some IRAM by removing auxiliary SPI flash chip drivers.
# Wrapped stub symbols are defined in src/platform/esp32/iram-quirk.c.
env.Append(
LINKFLAGS=[
"-Wl,--wrap=esp_flash_chip_gd",
"-Wl,--wrap=esp_flash_chip_issi",
"-Wl,--wrap=esp_flash_chip_winbond",
]
)
else:
# For newer ESP32 targets, using newlib nano works better.
env.Append(LINKFLAGS=["--specs=nano.specs", "-u", "_printf_float"])
if platform.name == "nordicnrf52":
env.AddPostAction("$BUILD_DIR/${PROGNAME}.hex",
env.VerboseAction(f"\"{sys.executable}\" ./bin/uf2conv.py $BUILD_DIR/firmware.hex -c -f 0xADA52840 -o $BUILD_DIR/firmware.uf2",
"Generating UF2 file"))
Import("projenv") Import("projenv")
prefsLoc = projenv["PROJECT_DIR"] + "/version.properties" prefsLoc = projenv["PROJECT_DIR"] + "/version.properties"
verObj = readProps(prefsLoc) verObj = readProps(prefsLoc)
print(f"Using meshtastic platformio-custom.py, firmware version {verObj['long']} on {env.get('PIOENV')}") print("Using meshtastic platformio-custom.py, firmware version " + verObj["long"] + " on " + env.get("PIOENV"))
# get repository owner if git is installed
try:
r_owner = (
subprocess.check_output(["git", "config", "--get", "remote.origin.url"])
.decode("utf-8")
.strip().split("/")
)
repo_owner = r_owner[-2] + "/" + r_owner[-1].replace(".git", "")
except subprocess.CalledProcessError:
repo_owner = "unknown"
jsonLoc = env["PROJECT_DIR"] + "/userPrefs.jsonc" jsonLoc = env["PROJECT_DIR"] + "/userPrefs.jsonc"
with open(jsonLoc) as f: with open(jsonLoc) as f:
@@ -106,19 +113,13 @@ for pref in userPrefs:
pref_flags.append("-D" + pref + "=" + env.StringifyMacro(userPrefs[pref]) + "") pref_flags.append("-D" + pref + "=" + env.StringifyMacro(userPrefs[pref]) + "")
# General options that are passed to the C and C++ compilers # General options that are passed to the C and C++ compilers
# Calculate unix epoch for current day (midnight)
current_date = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
build_epoch = int(current_date.timestamp())
flags = [ flags = [
"-DAPP_VERSION=" + verObj["long"], "-DAPP_VERSION=" + verObj["long"],
"-DAPP_VERSION_SHORT=" + verObj["short"], "-DAPP_VERSION_SHORT=" + verObj["short"],
"-DAPP_ENV=" + env.get("PIOENV"), "-DAPP_ENV=" + env.get("PIOENV"),
"-DAPP_REPO=" + repo_owner,
"-DBUILD_EPOCH=" + str(build_epoch),
] + pref_flags ] + pref_flags
print("Using flags:") print ("Using flags:")
for flag in flags: for flag in flags:
print(flag) print(flag)
@@ -160,19 +161,3 @@ def load_boot_logo(source, target, env):
# Load the boot logo on TFT builds # Load the boot logo on TFT builds
if ("HAS_TFT", 1) in env.get("CPPDEFINES", []): if ("HAS_TFT", 1) in env.get("CPPDEFINES", []):
env.AddPreAction('$BUILD_DIR/littlefs.bin', load_boot_logo) env.AddPreAction('$BUILD_DIR/littlefs.bin', load_boot_logo)
# Rename (mv) littlefs.bin to include the PROGNAME
# This ensures the littlefs.bin is named consistently with the firmware
env.AddPostAction('$BUILD_DIR/littlefs.bin', env.VerboseAction(
f'mv $BUILD_DIR/littlefs.bin $BUILD_DIR/{lfsbin}',
f'Renaming littlefs.bin to {lfsbin}'
))
env.AddCustomTarget(
name="mtjson",
dependencies=None,
actions=[manifest_gather],
title="Meshtastic Manifest",
description="Generating Meshtastic manifest JSON + Checksums",
always_build=True,
)

View File

@@ -1,16 +0,0 @@
#!/usr/bin/env python3
# trunk-ignore-all(ruff/F821)
# trunk-ignore-all(flake8/F821): For SConstruct imports
Import("env")
platform = env.PioPlatform()
if platform.name == "native":
env.Replace(PROGNAME="meshtasticd")
else:
from readprops import readProps
prefsLoc = env["PROJECT_DIR"] + "/version.properties"
verObj = readProps(prefsLoc)
env.Replace(PROGNAME=f"firmware-{env.get('PIOENV')}-{verObj['long']}")
# Print the new program name for verification
print(f"PROGNAME: {env.get('PROGNAME')}")

View File

@@ -3,7 +3,7 @@
set -e set -e
echo "Starting simulator" echo "Starting simulator"
.pio/build/native/meshtasticd -s & .pio/build/native/program &
sleep 20 # 5 seconds was not enough sleep 20 # 5 seconds was not enough
echo "Simulator started, launching python test..." echo "Simulator started, launching python test..."

View File

@@ -1 +1 @@
2.6.7 2.6.4

View File

@@ -1,53 +0,0 @@
{
"build": {
"arduino": {
"ldscript": "nrf52840_s140_v6.ld"
},
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DNRF52840_XXAA",
"f_cpu": "64000000L",
"hwids": [
["0x239A", "0x4405"],
["0x239A", "0x0029"],
["0x239A", "0x002A"]
],
"usb_product": "elecrow_eink",
"mcu": "nrf52840",
"variant": "ELECROW-ThinkNode-M3",
"variants_dir": "variants",
"bsp": {
"name": "adafruit"
},
"softdevice": {
"sd_flags": "-DS140",
"sd_name": "s140",
"sd_version": "6.1.1",
"sd_fwid": "0x00B6"
},
"bootloader": {
"settings_addr": "0xFF000"
}
},
"connectivity": ["bluetooth"],
"debug": {
"jlink_device": "nRF52840_xxAA",
"onboard_tools": ["jlink"],
"svd_path": "nrf52840.svd",
"openocd_target": "nrf52840-mdk-rs"
},
"frameworks": ["arduino"],
"name": "elecrow nrf",
"upload": {
"maximum_ram_size": 248832,
"maximum_size": 815104,
"speed": 115200,
"protocol": "nrfutil",
"protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"],
"use_1200bps_touch": true,
"require_upload_port": true,
"wait_for_upload_port": true
},
"url": "",
"vendor": "ELECROW"
}

View File

@@ -1,53 +0,0 @@
{
"build": {
"arduino": {
"ldscript": "nrf52840_s140_v6.ld"
},
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DARDUINO_NRF52840_ELECROW_M6 -DNRF52840_XXAA",
"f_cpu": "64000000L",
"hwids": [
["0x239A", "0x4405"],
["0x239A", "0x0029"],
["0x239A", "0x002A"]
],
"usb_product": "elecrow_thinknode_m6",
"mcu": "nrf52840",
"variant": "ELECROW-ThinkNode-M6",
"variants_dir": "variants",
"bsp": {
"name": "adafruit"
},
"softdevice": {
"sd_flags": "-DS140",
"sd_name": "s140",
"sd_version": "6.1.1",
"sd_fwid": "0x00B6"
},
"bootloader": {
"settings_addr": "0xFF000"
}
},
"connectivity": ["bluetooth"],
"debug": {
"jlink_device": "nRF52840_xxAA",
"onboard_tools": ["jlink"],
"svd_path": "nrf52840.svd",
"openocd_target": "nrf52840-mdk-rs"
},
"frameworks": ["arduino"],
"name": "ELECROW ThinkNode M6",
"upload": {
"maximum_ram_size": 248832,
"maximum_size": 815104,
"speed": 115200,
"protocol": "nrfutil",
"protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"],
"use_1200bps_touch": true,
"require_upload_port": true,
"wait_for_upload_port": true
},
"url": "https://www.elecrow.com/thinknode-m6-outdoor-solar-power-for-lora-powered-by-nrf52840-supports-gps.html",
"vendor": "ELECROW"
}

View File

@@ -1,41 +0,0 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"memory_type": "qio_opi"
},
"core": "esp32",
"extra_flags": [
"-DBOARD_HAS_PSRAM",
"-DARDUINO_USB_CDC_ON_BOOT=1",
"-DARDUINO_USB_MODE=0",
"-DARDUINO_RUNNING_CORE=1",
"-DARDUINO_EVENT_RUNNING_CORE=1"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"hwids": [["0x303A", "0x1001"]],
"mcu": "esp32s3",
"variant": "hackaday-communicator"
},
"connectivity": ["wifi", "bluetooth", "lora"],
"debug": {
"default_tool": "esp-builtin",
"onboard_tools": ["esp-builtin"],
"openocd_target": "esp32s3.cfg"
},
"frameworks": ["arduino", "espidf"],
"name": "hackaday-communicator (16 MB FLASH, 8 MB PSRAM)",
"upload": {
"flash_size": "16MB",
"maximum_ram_size": 327680,
"maximum_size": 16777216,
"use_1200bps_touch": true,
"wait_for_upload_port": true,
"require_upload_port": true,
"speed": 1500000
},
"url": "hackaday.com",
"vendor": "hackaday"
}

View File

@@ -1,54 +0,0 @@
{
"build": {
"arduino": {
"ldscript": "nrf52840_s140_v6.ld"
},
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DNRF52840_XXAA",
"f_cpu": "64000000L",
"hwids": [
["0x239A", "0x4405"],
["0x239A", "0x0029"],
["0x239A", "0x002A"],
["0x239A", "0x0071"]
],
"usb_product": "HT-n5262",
"mcu": "nrf52840",
"variant": "heltec_mesh_solar",
"variants_dir": "variants",
"bsp": {
"name": "adafruit"
},
"softdevice": {
"sd_flags": "-DS140",
"sd_name": "s140",
"sd_version": "6.1.1",
"sd_fwid": "0x00B6"
},
"bootloader": {
"settings_addr": "0xFF000"
}
},
"connectivity": ["bluetooth"],
"debug": {
"jlink_device": "nRF52840_xxAA",
"onboard_tools": ["jlink"],
"svd_path": "nrf52840.svd",
"openocd_target": "nrf52840-mdk-rs"
},
"frameworks": ["arduino"],
"name": "Heltec nrf (Adafruit BSP)",
"upload": {
"maximum_ram_size": 248832,
"maximum_size": 815104,
"speed": 115200,
"protocol": "nrfutil",
"protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"],
"use_1200bps_touch": true,
"require_upload_port": true,
"wait_for_upload_port": true
},
"url": "https://heltec.org/project/meshsolar/",
"vendor": "Heltec"
}

View File

@@ -1,43 +0,0 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"partitions": "default_16MB.csv",
"memory_type": "qio_qspi"
},
"core": "esp32",
"extra_flags": [
"-DBOARD_HAS_PSRAM",
"-DARDUINO_USB_CDC_ON_BOOT=1",
"-DARDUINO_USB_MODE=1",
"-DARDUINO_RUNNING_CORE=1",
"-DARDUINO_EVENT_RUNNING_CORE=1"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"psram_type": "qspi",
"hwids": [["0x303A", "0x1001"]],
"mcu": "esp32s3",
"variant": "heltec_v4"
},
"connectivity": ["wifi", "bluetooth", "lora"],
"debug": {
"default_tool": "esp-builtin",
"onboard_tools": ["esp-builtin"],
"openocd_target": "esp32s3.cfg"
},
"frameworks": ["arduino", "espidf"],
"name": "heltec_wifi_lora_32 v4 (16 MB FLASH, 2 MB PSRAM)",
"upload": {
"flash_size": "16MB",
"maximum_ram_size": 2097152,
"maximum_size": 16777216,
"use_1200bps_touch": true,
"wait_for_upload_port": true,
"require_upload_port": true,
"speed": 921600
},
"url": "https://heltec.org/",
"vendor": "heltec"
}

View File

@@ -1,37 +0,0 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"partitions": "default_8MB.csv"
},
"core": "esp32",
"extra_flags": [
"-DARDUINO_USB_CDC_ON_BOOT=1",
"-DARDUINO_USB_MODE=0",
"-DARDUINO_RUNNING_CORE=1",
"-DARDUINO_EVENT_RUNNING_CORE=1"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"hwids": [["0x303A", "0x1001"]],
"mcu": "esp32s3",
"variant": "heltec_wireless_tracker_v2"
},
"connectivity": ["wifi", "bluetooth", "lora"],
"debug": {
"openocd_target": "esp32s3.cfg"
},
"frameworks": ["arduino", "espidf"],
"name": "Heltec Wireless Tracker V2",
"upload": {
"flash_size": "8MB",
"maximum_ram_size": 327680,
"maximum_size": 8388608,
"wait_for_upload_port": true,
"require_upload_port": true,
"speed": 921600
},
"url": "https://heltec.org",
"vendor": "Heltec"
}

View File

@@ -1,52 +0,0 @@
{
"build": {
"arduino": {
"ldscript": "nrf52840_s140_v6.ld"
},
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA",
"f_cpu": "64000000L",
"hwids": [
["0x239A", "0x8029"],
["0x239A", "0x0029"],
["0x239A", "0x002A"],
["0x239A", "0x802A"]
],
"usb_product": "MeshTiny",
"mcu": "nrf52840",
"variant": "meshtiny",
"bsp": {
"name": "adafruit"
},
"softdevice": {
"sd_flags": "-DS140",
"sd_name": "s140",
"sd_version": "6.1.1",
"sd_fwid": "0x00B6"
},
"bootloader": {
"settings_addr": "0xFF000"
}
},
"connectivity": ["bluetooth"],
"debug": {
"jlink_device": "nRF52840_xxAA",
"svd_path": "nrf52840.svd",
"openocd_target": "nrf52840-mdk-rs"
},
"frameworks": ["arduino", "freertos"],
"name": "MeshTiny",
"upload": {
"maximum_ram_size": 248832,
"maximum_size": 815104,
"speed": 115200,
"protocol": "nrfutil",
"protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"],
"use_1200bps_touch": true,
"require_upload_port": true,
"wait_for_upload_port": true
},
"url": "https://github.com/meshtastic/firmware",
"vendor": "MTools Tec"
}

View File

@@ -1,56 +0,0 @@
{
"build": {
"arduino": {
"ldscript": "nrf52840_s140_v6.ld"
},
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DARDUINO_NRF52840_MUZI_BASE -DNRF52840_XXAA",
"f_cpu": "64000000L",
"hwids": [["0x239A", "0xcafe"]],
"mcu": "nrf52840",
"variant": "muzi-base",
"variants_dir": "variants",
"bsp": {
"name": "adafruit"
},
"softdevice": {
"sd_flags": "-DS140",
"sd_name": "s140",
"sd_version": "6.1.1",
"sd_fwid": "0x00B6"
},
"bootloader": {
"settings_addr": "0xFF000"
}
},
"connectivity": ["bluetooth"],
"debug": {
"jlink_device": "nRF52840_xxAA",
"onboard_tools": ["jlink"],
"svd_path": "nrf52840.svd",
"openocd_target": "nrf52840-mdk-rs"
},
"frameworks": ["arduino"],
"name": "Muzi Base",
"url": "https://muzi.works/",
"vendor": "MuziWorks",
"upload": {
"maximum_ram_size": 248832,
"maximum_size": 815104,
"speed": 115200,
"protocol": "nrfutil",
"protocols": [
"jlink",
"nrfjprog",
"nrfutil",
"blackmagic",
"cmsis-dap",
"mbed",
"stlink"
],
"use_1200bps_touch": true,
"require_upload_port": true,
"wait_for_upload_port": true
}
}

View File

@@ -1,52 +0,0 @@
{
"build": {
"arduino": {
"ldscript": "nrf52840_s140_v6.ld"
},
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA",
"f_cpu": "64000000L",
"hwids": [
["0x239A", "0x8029"],
["0x239A", "0x0029"],
["0x239A", "0x002A"],
["0x239A", "0x802A"]
],
"usb_product": "Muzi R1 Neo",
"mcu": "nrf52840",
"variant": "r1-neo",
"bsp": {
"name": "adafruit"
},
"softdevice": {
"sd_flags": "-DS140",
"sd_name": "s140",
"sd_version": "6.1.1",
"sd_fwid": "0x00B6"
},
"bootloader": {
"settings_addr": "0xFF000"
}
},
"connectivity": ["bluetooth"],
"debug": {
"jlink_device": "nRF52840_xxAA",
"svd_path": "nrf52840.svd",
"openocd_target": "nrf52840-mdk-rs"
},
"frameworks": ["arduino", "freertos"],
"name": "WisCore RAK4631 Board",
"upload": {
"maximum_ram_size": 248832,
"maximum_size": 815104,
"speed": 115200,
"protocol": "nrfutil",
"protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"],
"use_1200bps_touch": true,
"require_upload_port": true,
"wait_for_upload_port": true
},
"url": "https://muzi.works/",
"vendor": "Muzi Works"
}

View File

@@ -2,7 +2,7 @@
"build": { "build": {
"arduino": { "arduino": {
"ldscript": "esp32s3_out.ld", "ldscript": "esp32s3_out.ld",
"partitions": "partition-table-8MB.csv", "partitions": "default_8MB.csv",
"memory_type": "qio_opi" "memory_type": "qio_opi"
}, },
"core": "esp32", "core": "esp32",

View File

@@ -1,43 +0,0 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"memory_type": "qio_qspi",
"partitions": "default_16MB.csv"
},
"core": "esp32",
"extra_flags": [
"-DBOARD_HAS_PSRAM",
"-DARDUINO_USB_CDC_ON_BOOT=1",
"-DARDUINO_USB_MODE=1",
"-DARDUINO_RUNNING_CORE=1",
"-DARDUINO_EVENT_RUNNING_CORE=1"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"hwids": [["0x303A", "0x1001"]],
"mcu": "esp32s3",
"variant": "esp32s3"
},
"connectivity": ["wifi", "bluetooth", "lora"],
"debug": {
"default_tool": "esp-builtin",
"onboard_tools": ["esp-builtin"],
"openocd_target": "esp32s3.cfg"
},
"frameworks": ["arduino", "espidf"],
"name": "LilyGo T-Deck Pro S3 (16M Flash 8M QSPI PSRAM )",
"upload": {
"flash_size": "16MB",
"maximum_ram_size": 327680,
"maximum_size": 16777216,
"require_upload_port": true,
"speed": 921600
},
"monitor": {
"speed": 115200
},
"url": "https://lilygo.cc/products/t-deck-pro",
"vendor": "LilyGo"
}

View File

@@ -3,7 +3,7 @@
"arduino": { "arduino": {
"ldscript": "esp32s3_out.ld", "ldscript": "esp32s3_out.ld",
"memory_type": "qio_opi", "memory_type": "qio_opi",
"partitions": "partition-table-8MB.csv" "partitions": "default_8MB.csv"
}, },
"core": "esp32", "core": "esp32",
"extra_flags": [ "extra_flags": [

View File

@@ -5,7 +5,7 @@
}, },
"core": "stm32", "core": "stm32",
"cpu": "cortex-m4", "cpu": "cortex-m4",
"extra_flags": "-DSTM32WLxx -DSTM32WLE5xx -DARDUINO_RAK3172_MODULE", "extra_flags": "-DSTM32WLxx -DSTM32WLE5xx -DARDUINO_GENERIC_WLE5CCUX",
"f_cpu": "48000000L", "f_cpu": "48000000L",
"mcu": "stm32wle5ccu", "mcu": "stm32wle5ccu",
"variant": "STM32WLxx/WL54CCU_WL55CCU_WLE4C(8-B-C)U_WLE5C(8-B-C)U", "variant": "STM32WLxx/WL54CCU_WL55CCU_WLE4C(8-B-C)U_WLE5C(8-B-C)U",

62
debian/changelog vendored
View File

@@ -1,44 +1,34 @@
meshtasticd (2.7.17.0) unstable; urgency=medium meshtasticd (2.7.3.0) UNRELEASED; urgency=medium
* Version 2.7.17
-- GitHub Actions <github-actions[bot]@users.noreply.github.com> Fri, 28 Nov 2025 15:11:34 +0000
meshtasticd (2.7.16.0) unstable; urgency=medium
* Version 2.7.16
-- GitHub Actions <github-actions[bot]@users.noreply.github.com> Wed, 19 Nov 2025 16:12:32 +0000
meshtasticd (2.7.15.0) unstable; urgency=medium
* Version 2.7.15
-- GitHub Actions <github-actions[bot]@users.noreply.github.com> Thu, 13 Nov 2025 12:31:57 +0000
meshtasticd (2.7.14.0) unstable; urgency=medium
* Version 2.7.14
-- GitHub Actions <github-actions[bot]@users.noreply.github.com> Mon, 03 Nov 2025 16:11:31 +0000
meshtasticd (2.7.13.0) unstable; urgency=medium
* Version 2.7.13
-- GitHub Actions <github-actions[bot]@users.noreply.github.com> Sat, 11 Oct 2025 15:27:28 +0000
meshtasticd (2.7.12.0) unstable; urgency=medium
[ Austin Lane ] [ Austin Lane ]
* Initial packaging * Initial packaging
* Version 2.5.19 * GitHub Actions Automatic version bump
* GitHub Actions Automatic version bump
* GitHub Actions Automatic version bump
* GitHub Actions Automatic version bump
[ ] [ ]
* GitHub Actions Automatic version bump * GitHub Actions Automatic version bump
[ GitHub Actions ] [ ]
* Version 2.7.12 * GitHub Actions Automatic version bump
-- GitHub Actions <github-actions[bot]@users.noreply.github.com> Wed, 01 Oct 2025 19:51:41 +0000 [ ]
* GitHub Actions Automatic version bump
[ ]
* GitHub Actions Automatic version bump
[ ]
* GitHub Actions Automatic version bump
[ ]
* GitHub Actions Automatic version bump
[ ]
* GitHub Actions Automatic version bump
[ Ubuntu ]
* GitHub Actions Automatic version bump
-- Ubuntu <github-actions[bot]@users.noreply.github.com> Thu, 10 Jul 2025 16:29:27 +0000

View File

@@ -1,8 +1,7 @@
#!/usr/bin/bash #!/usr/bin/bash
export DEBFULLNAME="GitHub Actions"
export DEBEMAIL="github-actions[bot]@users.noreply.github.com" export DEBEMAIL="github-actions[bot]@users.noreply.github.com"
PKG_VERSION=$(python3 bin/buildinfo.py short) PKG_VERSION=$(python3 bin/buildinfo.py short)
dch --newversion "$PKG_VERSION.0" \ dch --newversion "$PKG_VERSION.0" \
--distribution unstable \ --distribution UNRELEASED \
"Version $PKG_VERSION" "GitHub Actions Automatic version bump"

1
debian/control vendored
View File

@@ -3,7 +3,6 @@ Section: misc
Priority: optional Priority: optional
Maintainer: Austin Lane <vidplace7@gmail.com> Maintainer: Austin Lane <vidplace7@gmail.com>
Build-Depends: debhelper-compat (= 13), Build-Depends: debhelper-compat (= 13),
libc6-dev (>= 2.38) | libbsd-dev,
lsb-release, lsb-release,
tar, tar,
gzip, gzip,

1
debian/rules vendored
View File

@@ -28,4 +28,5 @@ override_dh_auto_build:
# Build with platformio # Build with platformio
$(PIO_ENV) platformio run -e native-tft $(PIO_ENV) platformio run -e native-tft
# Move the binary and default config to the correct name # Move the binary and default config to the correct name
mv .pio/build/native-tft/program .pio/build/native-tft/meshtasticd
cp bin/config-dist.yaml bin/config.yaml cp bin/config-dist.yaml bin/config.yaml

View File

@@ -1,9 +1,10 @@
#!/usr/bin/env python3
# trunk-ignore-all(flake8/F821) # trunk-ignore-all(flake8/F821)
# trunk-ignore-all(ruff/F821) # trunk-ignore-all(ruff/F821)
Import("env") Import("env")
# NOTE: This is not currently used, but can serve as an example on how to write extra_scripts
# print("Current CLI targets", COMMAND_LINE_TARGETS) # print("Current CLI targets", COMMAND_LINE_TARGETS)
# print("Current Build targets", BUILD_TARGETS) # print("Current Build targets", BUILD_TARGETS)
# print("CPP defs", env.get("CPPDEFINES")) # print("CPP defs", env.get("CPPDEFINES"))

View File

@@ -1,80 +0,0 @@
#!/usr/bin/env python3
# trunk-ignore-all(ruff/F821)
# trunk-ignore-all(flake8/F821): For SConstruct imports
# trunk-ignore-all(ruff/E402): Hacky esptool import
# trunk-ignore-all(flake8/E402): Hacky esptool import
import sys
from os.path import join
Import("env")
platform = env.PioPlatform()
sys.path.append(join(platform.get_package_dir("tool-esptoolpy")))
import esptool
def esp32_create_combined_bin(source, target, env):
# this sub is borrowed from ESPEasy build toolchain. It's licensed under GPL V3
# https://github.com/letscontrolit/ESPEasy/blob/mega/tools/pio/post_esp32.py
print("Generating combined binary for serial flashing")
app_offset = 0x10000
new_file_name = env.subst("$BUILD_DIR/${PROGNAME}.factory.bin")
sections = env.subst(env.get("FLASH_EXTRA_IMAGES"))
firmware_name = env.subst("$BUILD_DIR/${PROGNAME}.bin")
chip = env.get("BOARD_MCU")
board = env.BoardConfig()
flash_size = board.get("upload.flash_size")
flash_freq = board.get("build.f_flash", "40m")
flash_freq = flash_freq.replace("000000L", "m")
flash_mode = board.get("build.flash_mode", "dio")
memory_type = board.get("build.arduino.memory_type", "qio_qspi")
if flash_mode == "qio" or flash_mode == "qout":
flash_mode = "dio"
if memory_type == "opi_opi" or memory_type == "opi_qspi":
flash_mode = "dout"
cmd = [
"--chip",
chip,
"merge_bin",
"-o",
new_file_name,
"--flash_mode",
flash_mode,
"--flash_freq",
flash_freq,
"--flash_size",
flash_size,
]
print(" Offset | File")
for section in sections:
sect_adr, sect_file = section.split(" ", 1)
print(f" - {sect_adr} | {sect_file}")
cmd += [sect_adr, sect_file]
print(f" - {hex(app_offset)} | {firmware_name}")
cmd += [hex(app_offset), firmware_name]
print("Using esptool.py arguments: %s" % " ".join(cmd))
esptool.main(cmd)
env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", esp32_create_combined_bin)
esp32_kind = env.GetProjectOption("custom_esp32_kind")
if esp32_kind == "esp32":
# Free up some IRAM by removing auxiliary SPI flash chip drivers.
# Wrapped stub symbols are defined in src/platform/esp32/iram-quirk.c.
env.Append(
LINKFLAGS=[
"-Wl,--wrap=esp_flash_chip_gd",
"-Wl,--wrap=esp_flash_chip_issi",
"-Wl,--wrap=esp_flash_chip_winbond",
]
)
else:
# For newer ESP32 targets, using newlib nano works better.
env.Append(LINKFLAGS=["--specs=nano.specs", "-u", "_printf_float"])

View File

@@ -1,73 +0,0 @@
#!/usr/bin/env python3
# trunk-ignore-all(ruff/F821)
# trunk-ignore-all(flake8/F821): For SConstruct imports
import json
import sys
from os.path import isfile
Import("env")
# From https://github.com/platformio/platform-espressif32/blob/develop/builder/main.py
def _parse_size(value):
if isinstance(value, int):
return value
elif value.isdigit():
return int(value)
elif value.startswith("0x"):
return int(value, 16)
elif value[-1].upper() in ("K", "M"):
base = 1024 if value[-1].upper() == "K" else 1024 * 1024
return int(value[:-1]) * base
return value
def _parse_partitions(env):
partitions_csv = env.subst("$PARTITIONS_TABLE_CSV")
if not isfile(partitions_csv):
sys.stderr.write(
"Could not find the file %s with partitions " "table.\n" % partitions_csv
)
env.Exit(1)
return
result = []
# The first offset is 0x9000 because partition table is flashed to 0x8000 and
# occupies an entire flash sector, which size is 0x1000
next_offset = 0x9000
with open(partitions_csv) as fp:
for line in fp.readlines():
line = line.strip()
if not line or line.startswith("#"):
continue
tokens = [t.strip() for t in line.split(",")]
if len(tokens) < 5:
continue
bound = 0x10000 if tokens[1] in ("0", "app") else 4
calculated_offset = (next_offset + bound - 1) & ~(bound - 1)
partition = {
"name": tokens[0],
"type": tokens[1],
"subtype": tokens[2],
"offset": tokens[3] or calculated_offset,
"size": tokens[4],
"flags": tokens[5] if len(tokens) > 5 else None,
}
result.append(partition)
next_offset = _parse_size(partition["offset"]) + _parse_size(
partition["size"]
)
return result
def mtjson_esp32_part(target, source, env):
part = _parse_partitions(env)
pj = json.dumps(part)
# print(f"JSON_PARTITIONS: {pj}")
# Dump json string to 'custom_mtjson_part' variable to use later when writing the manifest
env.Replace(custom_mtjson_part=pj)
env.AddPreAction("mtjson", mtjson_esp32_part)

View File

@@ -1,9 +1,7 @@
#!/usr/bin/env python3
# trunk-ignore-all(ruff/F821) # trunk-ignore-all(ruff/F821)
# trunk-ignore-all(flake8/F821): For SConstruct imports # trunk-ignore-all(flake8/F821): For SConstruct imports
Import("env") Import("env")
# Custom HEX from ELF # Custom HEX from ELF
env.AddPostAction( env.AddPostAction(
"$BUILD_DIR/${PROGNAME}.elf", "$BUILD_DIR/${PROGNAME}.elf",

Some files were not shown because too many files have changed in this diff Show More