Skip to content

Router: null-check destination node before dereferencing public_key in PKI decode#10226

Open
nightjoker7 wants to merge 5 commits into
meshtastic:developfrom
nightjoker7:fix/router-pki-to-null-deref
Open

Router: null-check destination node before dereferencing public_key in PKI decode#10226
nightjoker7 wants to merge 5 commits into
meshtastic:developfrom
nightjoker7:fix/router-pki-to-null-deref

Conversation

@nightjoker7

Copy link
Copy Markdown
Contributor

Summary

Null-check nodeDB->getMeshNode(p->to) before dereferencing ->user.public_key.size during the PKI decryption gate in perhapsDecode().

Problem

In src/mesh/Router.cpp::perhapsDecode(), the PKI decryption path guards against a missing sender node, but not a missing destination node:

if (p->channel == 0 && isToUs(p) && p->to > 0 && !isBroadcast(p->to) && nodeDB->getMeshNode(p->from) != nullptr &&
    nodeDB->getMeshNode(p->from)->user.public_key.size > 0 && nodeDB->getMeshNode(p->to)->user.public_key.size > 0 &&
    rawSize > MESHTASTIC_PKC_OVERHEAD) {

isToUs(p) returns true when p->to == ourNodeNum, but a brand-new node that just booted may not yet have itself populated into its own NodeDB (e.g. before the first NodeDB::init() write-back completes, or on a freshly-factory-reset node that has not yet received its own NodeInfo broadcast back). In that window, getMeshNode(p->to) returns nullptr, and the immediately following ->user.public_key.size dereferences a null pointer → hard fault / watchdog reset.

Similar races can occur after NodeDB eviction of the local node entry under pressure, or on nodes that have disabled their local NodeInfo broadcast.

Fix

Add an explicit nodeDB->getMeshNode(p->to) != nullptr check to the short-circuit chain, mirroring the existing p->from guard on the previous line.

if (p->channel == 0 && isToUs(p) && p->to > 0 && !isBroadcast(p->to) && nodeDB->getMeshNode(p->from) != nullptr &&
    nodeDB->getMeshNode(p->from)->user.public_key.size > 0 && nodeDB->getMeshNode(p->to) != nullptr &&
    nodeDB->getMeshNode(p->to)->user.public_key.size > 0 && rawSize > MESHTASTIC_PKC_OVERHEAD) {

If the lookup returns null, the PKI path is skipped and the packet falls through to the existing channel-based decryption logic — the same behavior as when the local key is simply absent.

Testing

  • Patched firmware running on a small fleet (RAK4631 / Heltec Station G2 / Heltec T114 / Heltec V3) for several days with no crashes on receipt of PKI-encrypted DMs.
  • Builds cleanly against develop.

Risk

Minimal. Two-line change, adds a null-check in front of an existing dereference; no behavior change on the happy path.

…n PKI decode

In perhapsDecode(), the PKI decryption gate dereferences
nodeDB->getMeshNode(p->to)->user.public_key.size without first
confirming the destination node is present in NodeDB. The sender
(p->from) is null-checked on the previous line, but the destination
is not. On a freshly-booted or freshly-reset node whose own NodeInfo
has not yet been written back to NodeDB, isToUs(p) can be true while
getMeshNode(p->to) returns nullptr, causing a null-pointer dereference
and hard fault on receipt of any PKI-encrypted DM addressed to us.

Add a matching nullptr check for p->to so the PKI path is skipped and
the packet falls through to channel-based decryption, identical to the
behavior when the local key is absent.
@github-actions github-actions Bot added the bugfix Pull request that fixes bugs label Apr 21, 2026
@thebentern thebentern requested a review from Copilot April 21, 2026 20:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR prevents a null dereference in Router::perhapsDecode() by adding a destination-node null check before accessing ->user.public_key.size in the PKI decryption gate.

Changes:

  • Add nodeDB->getMeshNode(p->to) != nullptr to the PKI decryption precondition
  • Preserve existing behavior by falling back to channel-based decryption when the destination node entry is missing

Comment thread src/mesh/Router.cpp Outdated
Review feedback from @thebentern (via Copilot) on PR meshtastic#10226: the previous
code called getMeshNode(p->from) three times and getMeshNode(p->to) once
within the same condition + body. Two concerns:

1. NodeDB::getMeshNode is a linear scan over numMeshNodes — doubling or
   tripling the work per PKI decrypt on the hot RX path.
2. TOCTOU: another task could evict a node between calls, so the first
   null-check passes but a later deref returns nullptr.

Cache both lookups in local pointers once, then use the locals throughout
the PKI branch. Preserves every original null-check and uses the cached
fromNode->user.public_key / toNode->user.public_key for the actual decrypt
and public-key copy.
@nightjoker7

Copy link
Copy Markdown
Contributor Author

Addressed the TOCTOU in 8cb93f54f: cached getMeshNode(p->from) and getMeshNode(p->to) in local fromNode/toNode pointers once, use the locals throughout the PKI branch. Eliminates both the doubled linear scan and the race window.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

Comment thread src/mesh/Router.cpp Outdated
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

@thebentern thebentern requested a review from Copilot April 23, 2026 23:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

nightjoker7 added a commit to nightjoker7/python that referenced this pull request Apr 25, 2026
…re in __init__

If connect() or waitForConfig() raises during __init__ (handshake timeout,
bad stream, config error), the reader thread started by connect() keeps
running and the underlying stream/socket stays open — but the caller never
receives a reference to the half-initialized instance, so they cannot call
close() themselves. The leak compounds on every retry from a caller's
reconnect loop.

Fix: wrap connect() + waitForConfig() in try/except; call self.close() on
any exception before re-raising. Also guard close() against RuntimeError
from joining an unstarted reader thread (happens when close() runs from
a failed __init__ before connect() could spawn it).

Discovered while debugging a real-world Meshtastic firmware crash where
a passive logger's retrying TCPInterface() calls against a node with
250-entry NodeDB produced a reconnect storm — every retry triggered a
full config+NodeDB dump on the node, compounding heap pressure, which
then exposed null-deref bugs in Router::perhapsDecode / MeshService
(firmware side fixed in meshtastic/firmware#10226 and #10229). The
client-side leak is independent of those firmware bugs and worth fixing
on its own.
@fifieldt

Copy link
Copy Markdown
Member

@copilot resolve the merge conflicts in this pull request

jeremiah-k added a commit to jeremiah-k/mtjk that referenced this pull request Jun 1, 2026
* Added example script : meshtastic_serial_message_reader.py

* Updates and bug fixes meshtastic_serial_message_reader.py

* Adjusting old deprecation test and exception for non-abstract use of StreamInterface

* Removing superfluous setting of noProto in init()

* Updating test for change of deprecation exception

* Shifting serial interface connection parts from __init__() into connect() method

* Removing unnecessary initialization of self.stream in TCPInterface

* Reorganising connect method calls for when connectNow is false

* Linting adjustment for change to StreamInterface non-abstract use check

* Container: Add initial container for meshtastic-cli

Just a quick set of files to enable the build of (tagged) containers.
Both alpine and debian containers are available (~200MiB/~1.2GiB)
allowing us to use meshtastic cli with a quick docker run, instead of
having to build/install stuff locally.

Signed-off-by: Olliver Schinagl <oliver@schinagl.nl>

* Filter --reply based on specified channel index 

Ensures that automatic replies are sent back on the same channel index the message was received on. Previously, all replies defaulted to the primary channel (0), even if the incoming message arrived on a secondary channel. Additionally it ensures incoming messages match the specified channel index.

E.g:  meshtastic --ch-index 1 --reply .

Modified the `onReceive` handler to extract the `channel` index from received packets. This ensures `interface.sendText` targets the originating channel rather than always defaulting to the primary channel. Added a filter to ensure that only the specified channel index is being replied to.

* fix(ble): handle BLEError with user-friendly messages

Replace raw tracebacks with helpful error messages that explain:
- What went wrong
- Possible causes
- How to fix it

Covers all BLEError cases:
- Device not found (BLE disabled, sleep mode, out of range)
- Multiple devices found (need to specify which one)
- Write errors (pairing PIN, Linux bluetooth group)
- Read errors (device disconnected)

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>

* fix(cli): add timeout error handling for serial connections

Handle MeshInterface.MeshInterfaceError when device is rebooting
or connection times out, with user-friendly error message.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>

* Refactor the Meshtastic TCP pub/sub example to ensure proper resource cleanup and clearer exception handling.

* Give TCPInterface reconnect logic on write errors

 * Moving to socket.sendall() is safer, as sendall will send the entire
   buffer, while send() would return the number of bytes sent and
   require being called multiple times if the buffer was full.
 * On exceptions: reconnect to the server.
 * On reconnection: make sure using a lock that there isn't a race
   between the readers and the writers triggering a reconnect.

* Fix local node position overwrite by low-precision echoes

When other nodes relay our position via map reports, they send it at
reduced precision (e.g., 13 bits). _onPositionReceive() was blindly
overwriting our locally-stored high-precision GPS position (32 bits)
with these degraded echoes.

The fix only protects the local node's position — since we have the
GPS internally, any lower-precision update is always an echo from the
mesh, never fresh data. Remote node positions are still updated
normally, as any position they broadcast reflects their current state.

Fixes meshtastic#910

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Added textchat.py and replymessage.py example scripts from TODO

* protobufs: v2.7.21

* loosen packaging version requirement

* poetry lock

* Update factory reset to use integer for config reset

* StreamInterface: prevent socket/reader-thread leak on handshake failure in __init__

If connect() or waitForConfig() raises during __init__ (handshake timeout,
bad stream, config error), the reader thread started by connect() keeps
running and the underlying stream/socket stays open — but the caller never
receives a reference to the half-initialized instance, so they cannot call
close() themselves. The leak compounds on every retry from a caller's
reconnect loop.

Fix: wrap connect() + waitForConfig() in try/except; call self.close() on
any exception before re-raising. Also guard close() against RuntimeError
from joining an unstarted reader thread (happens when close() runs from
a failed __init__ before connect() could spawn it).

Discovered while debugging a real-world Meshtastic firmware crash where
a passive logger's retrying TCPInterface() calls against a node with
250-entry NodeDB produced a reconnect storm — every retry triggered a
full config+NodeDB dump on the node, compounding heap pressure, which
then exposed null-deref bugs in Router::perhapsDecode / MeshService
(firmware side fixed in meshtastic/firmware#10226 and #10229). The
client-side leak is independent of those firmware bugs and worth fixing
on its own.

* protobufs: v2.7.24

* Inject options in nanopb .options files into the protobuf files used for code generation

* Add tests of nanopb options injection

* pylint cleanups

* the fuzz

* fix import order

* Update the other factory reset to use integer too

* Document the use of --ch-index along with --reply a little

* pylint fix

* fix a missing paren in a comment

* Fix some leaks/hangs on close: unstarted StreamInterface streams & TCP reader unblock

* pylint strikes again

* pylint/test fixes

* some pre-merge cleanup

* Re-establish the OSError being raised to match former behavior, but still reconnect. TBD if this is quite the right approach.

* Avoid deadlocking on potentially re-entrant _startConfig call, and don't reconnect when _wantExit

* make test more deterministic for reconnect count testing

* Harden a bit, update some sections, add a README section

* A bunch of dependency updates in poetry.lock (to shut up Dependabot)

* tryfix container build issue

* Remove arm/v7 from the container build right now, can't be bothered

* Make examples more regularized and focused, and add contribution guidelines for the examples folder

* Add a BLEError 'kind' field and branch on it instead of string matching

* tests of new BLEError functionality

* More lockfile updates now that dependabot woke up

* One more dependency update

* Filter --reply based on specified channel index 

Ensures that automatic replies are sent back on the same channel index the message was received on. Previously, all replies defaulted to the primary channel (0), even if the incoming message arrived on a secondary channel. Additionally it ensures incoming messages match the specified channel index.

E.g:  meshtastic --ch-index 1 --reply .

Modified the `onReceive` handler to extract the `channel` index from received packets. This ensures `interface.sendText` targets the originating channel rather than always defaulting to the primary channel. Added a filter to ensure that only the specified channel index is being replied to.

* Container: Add initial container for meshtastic-cli

Just a quick set of files to enable the build of (tagged) containers.
Both alpine and debian containers are available (~200MiB/~1.2GiB)
allowing us to use meshtastic cli with a quick docker run, instead of
having to build/install stuff locally.

Signed-off-by: Olliver Schinagl <oliver@schinagl.nl>

* Document the use of --ch-index along with --reply a little

* Add new example scripts and contribution guidelines from upstream meshtastic#928

Ports the 6 new files from upstream master 81ae8b6 (PR meshtastic#928 by ianmcorvidae):
- examples/CONTRIBUTING.md
- examples/tcp_connection_info_once.py
- examples/tcp_pubsub_send_and_receive.py (replacement for pub_sub_example*.py)
- examples/meshtastic_serial_message_reader.py
- examples/textchat.py
- examples/replymessage.py

The rewrites of existing example files in 81ae8b6 (get_hw.py, hello_world_serial.py,
info_example.py, scan_for_devices.py, set_owner.py, show_ports.py, tcp_gps_example.py,
waypoint.py) are skipped because develop's versions are already more robust
(context managers, type hints, stricter error handling) than master's modernization.

Upstream commit: 81ae8b6 (Make examples more regularized and focused)
Original author: Ian McEwen <ian@ianmcorvidae.net>

* Add bin/inject_nanopb_options.py for nanopb options injection

Ports the inject_nanopb_options.py script from upstream master 89d81c9.
The script reads .options files from the protobufs submodule and injects
the nanopb constraints (max_size, max_length, etc.) as inline proto field
options so protoc --python_out embeds them in the generated descriptors.
Python code can then read them via:

    field.GetOptions().Extensions[nanopb_pb2.nanopb].max_size

Includes a7d13eb's parse_value bug fix: replaced s.lstrip("-").isdigit()
with re.fullmatch(r"-?[0-9]+", s) to correctly reject strings like "---5"
that lstrip would mangle.

The actual _pb2.py regeneration is intentionally NOT performed here — the
protobufs submodule is regenerated by CI workflows (see
.github/workflows/update_protobufs.yml), and the script is ready for the
next regen.

Upstream commits: 89d81c9 (script) + a7d13eb (parse_value fix)
Original author: Ian McEwen <ian@ianmcorvidae.net>

* Integrate nanopb options injection into bin/regen-protobufs.sh

Adds the upstream 89d81c9 injection step to develop's regen script:
1. Copies protobufs/meshtastic/*.options into the temp build dir
2. After the existing sed pipeline, iterates over .options files and
   calls bin/inject_nanopb_options.py on the matching .proto file
3. Then runs protoc as before, so the generated _pb2.py descriptors
   embed the nanopb constraints inline

The script change is intentionally additive: if no .options files are
present, the for loop is a no-op, so existing regeneration behavior is
preserved.

The actual _pb2.py files are NOT regenerated in this commit — the
protobufs submodule is auto-regenerated by CI workflows (per copilot
instructions: 'Never edit _pb2.py or _pb2.pyi files directly. Regenerate
with: make protobufs or ./bin/regen-protobufs.sh'). The next CI run will
pick up the new injection step.

Adapted to develop's variable style (${SEDCMD[@]} array, ${PROTOC}
variable) rather than master's hardcoded paths.

Upstream commit: 89d81c9
Original author: Ian McEwen <ian@ianmcorvidae.net>

* Add tests for bin/inject_nanopb_options.py (nanopb options injection)

Ports meshtastic/tests/test_inject_nanopb_options.py from upstream master
280323d. The test file has two parts:

Part 1 (test_parse_*, test_inject_*): unit-tests the script's logic directly
using small synthetic proto snippets and a tmp_path-based test harness.
Covers parse_value, parse_options_file, apply_options, and inject.

Part 2 (test_descriptor_*): smoke-tests the already-generated _pb2.py files
to confirm the regen pipeline embedded the expected nanopb options. These
will pass once the next CI protobuf regeneration runs (the protobufs
submodule is auto-regenerated by .github/workflows/update_protobufs.yml,
which now invokes the updated bin/regen-protobufs.sh).

Includes a7d13eb's three hypothesis property-based tests for parse_value:
- test_parse_value_any_integer_returns_int: any int string round-trips
- test_parse_value_never_crashes: no input crashes the parser
- test_parse_value_non_numeric_non_bool_returns_str: non-numeric non-bool
  strings pass through unchanged

The hypothesis dependency is already in pyproject.toml per the project's
copilot-instructions.md tech stack.

The test file loads bin/inject_nanopb_options.py at test time via
importlib.util.spec_from_file_location, so it does not require the script
to be on PYTHONPATH.

Upstream commits: 280323d (test file) + a7d13eb (hypothesis tests)
Original author: Ian McEwen <ian@ianmcorvidae.net>

* Fix CI: regenerate protobufs with nanopb injection, fix reply filter test, fix lint

- Regenerated all _pb2.py files via bin/regen-protobufs.sh to embed nanopb
  options (max_size, max_count, int_size) in protobuf descriptors. The inject
  script was already integrated in commit 1e65a62 but _pb2.py files hadn't
  been regenerated since then. Fixes 10 test_descriptor_* test failures.
- test_main_onReceive_with_text: set args.reply=True and args.ch_index=None
  explicitly. MagicMock's default __int__ returns 1, making
  targetChannel=1 != rxChannel=0, so the reply was being silently
  filtered by the --ch-index logic (cherry-picked from upstream c8b1b8e).
  Fixes the 'Ignored message on channel 0' → 'Sending reply' assertion.
- test_inject_nanopb_options.py: fix ruff lint (unused imports, docstring
  caps, ambiguous 'l' vars, unused 'lines'/'user_line' variables).
- __main__.py: fix trailing whitespace (pylint C0303).

Each update should complete the CI checks.

* Apply code review fixes (2 critical, 4 medium)

Critical:
- examples/replymessage.py: prevent infinite auto-reply loop by filtering
  self-sent messages (from == my_node_num) and auto-reply echoes
  (text starts with "got msg '")
- __main__.py --reply: same loop prevention — without this, a node
  running --reply would reply to its own replies, spamming the mesh

Medium:
- inject_nanopb_options.py: import detection now matches lines with
  trailing comments (uses ";" in line instead of endswith(";"))
- inject_nanopb_options.py: explicit encoding='utf-8' on file open
  for Windows compatibility
- examples/textchat.py: filter local echo messages so user doesn't
  see their own messages duplicated
- Containerfile.alpine: add --no-directory flag to match Debian
  variant and avoid unnecessary local copy into system site-packages

Also fixes ruff lint (D400/D401/D403 docstring style) in touched files.

* Apply 13 review findings: security, correctness, style

container-build.yaml:
- Remove continue-on-error: true (was masking build failures)
- Add persist-credentials: false to checkout step
- Pin all 6 action refs to immutable commit SHAs

Containerfile.alpine + Containerfile.debian:
- Add non-root user (meshtastic) before ENTRYPOINT

bin/inject_nanopb_options.py:
- Replace typing.Dict/List/Tuple with PEP 585 built-in generics
- Fix scope merge bug: remove break so all matching specific keys
  get merged (shortest path first, more-specific overrides)

meshtastic/tests/test_inject_nanopb_options.py:
- Add type annotations to _load_inject_module, _inject, _field_opts

examples/replymessage.py:
- Send reply on received channel (channelIndex=) not default
- Wrap executable code in main() with __name__ guard
- Use PEP 604 unions (X | None) instead of Optional/Union

examples/textchat.py:
- Wrap executable code in main() with __name__ guard
- Use PEP 604 unions instead of Optional/Union

examples/CONTRIBUTING.md:
- Add checklist item 8: type hints + PEP 604/built-in generics

meshtastic/__main__.py:
- Fix --reply channel filter: unset --ch-index now means any channel
  (was incorrectly defaulting to channel 0)
- Use .get() with fallback for rxSnr/hopLimit (crash on missing fields)

* Fix mypy + pylint failures on review changes

- test_inject_nanopb_options.py: add assert guards for None checks
  on spec_from_file_location return (mypy arg-type/union-attr)
- inject_nanopb_options.py main(): add docstring, encoding='utf-8'
  on read_text/write_text (pylint missing-docstring, unspecified-encoding)
- examples/replymessage.py main(): add docstring (pylint C0116)
- examples/textchat.py main(): add docstring (pylint C0116)

* style: reformat code and update CI workflow

Apply consistent code formatting across examples, main entry point, and tests to improve readability and adhere to style guidelines. Update GitHub Actions workflow to use double quotes for tag patterns.

* Address review feedback: container CI, examples polish, tests, determinism

Container workflow (.github/workflows/container-build.yaml):
- Add 'develop' to push and pull_request branch triggers
- Remove linux/arm/v7 and linux/arm/v6 platforms (upstream build issues)
- Update autotag logic to use 'auto' for any branch push

Examples (replymessage.py, textchat.py):
- Type packet parameter as dict[str, Any] instead of bare dict
- Add Interface type alias to replace verbose multi-line union types
- Use 'exc' naming for caught exceptions (pylint W0707)
- Move pylint disable comment to correct line for onConnection

inject_nanopb_options.py:
- Sort option keys in format_nanopb_opts() for deterministic output
  across Python versions and option file ordering

New tests — onReceive reply behavior (test_main.py, 4 tests):
- test_main_onReceive_reply_uses_rx_channel: verifies channelIndex=packet channel
- test_main_onReceive_ch_index_filter_mismatch: verifies --ch-index mismatch ignored
- test_main_onReceive_own_packet_no_reply: verifies own-node packets skipped
- test_main_onReceive_auto_reply_echo_no_reply: verifies 'got msg' prefix skipped

New tests — inject_nanopb_options edge cases (7 tests):
- Comments with braces don't corrupt nesting
- Map<> fields are skipped (not injected)
- Oneof fields receive options correctly
- Enum value lines are not modified
- format_nanopb_opts output is sorted/deterministic
- Duplicate specific/wildcard options merge deterministically
- Multiple close braces on one line handled correctly

Protobuf reproducibility verified: regen-protobufs.sh produces clean diff.

Pre-existing failures: test_main_init_parser_version and test_main_main_version
fail due to version detection in dev environment (not related to this change).

* Fix duplicate pull_request key, centralize project name constants

container-build.yaml:
- Fix critical YAML duplicate key bug: merge two pull_request blocks
  into one with both master and develop branches
- Remove invalid 'tags' subkey from pull_request event

version.py:
- Add PACKAGE_NAME, PROJECT_DISPLAY_NAME, INSTALL_UPGRADE_HINT constants
- Single source of truth for project identity; swap PACKAGE_NAME to
  'meshtastic' when upstreaming

util.py:
- Import DISTRIBUTION_NAME_CANDIDATES from version.py instead of
  duplicating the definition

__main__.py:
- Use PROJECT_DISPLAY_NAME and INSTALL_UPGRADE_HINT from version.py
- Upgrade hint now recommends 'pipx upgrade mtjk' instead of
  'pip install --upgrade meshtastic'

ble_interface.py, interfaces/ble/__init__.py:
- Update BLE bleak install error to recommend 'pipx install mtjk'

* Remove Containerfile.alpine from container build matrix

* Restore alpine matrix entry, skip build outside upstream repo

Only builds Containerfile.alpine when running in meshtastic/python.
Any fork (including mtjk) automatically skips it. One line to remove
when upstreaming.

* ci(container): update alpine build conditional comment

Update the comment in the container build workflow to clarify that the Alpine build is restricted to the upstream repository.

* refactor(ci): restrict all container builds to upstream repository

Update the job conditional to ensure that container builds are only
executed within the meshtastic/python repository. This simplifies the
logic previously used to selectively skip the Alpine build by applying
the restriction to the entire job.

---------

Signed-off-by: Olliver Schinagl <oliver@schinagl.nl>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
Co-authored-by: henri <github.shustak@neverbox.com>
Co-authored-by: Travis-L-R <>
Co-authored-by: Olliver Schinagl <oliver@schinagl.nl>
Co-authored-by: Rob <95710162+thatSFguy@users.noreply.github.com>
Co-authored-by: Aleksei Sviridkin <f@lex.la>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: dim5x <dim5x@yahoo.com>
Co-authored-by: Stephen Thorne <stephen@thorne.id.au>
Co-authored-by: Benjamin Babeshkin <skypanther@gmail.com>
Co-authored-by: Aron Tkachuk <arotkac@icloud.com>
Co-authored-by: Ian McEwen <ian@ianmcorvidae.net>
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: nightjoker7 <mattdeering7@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Pull request that fixes bugs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants