Files
2026-04-17 03:32:18 -07:00

7.1 KiB
Raw Permalink Blame History

Firmware projects on MeshForge

This guide is for maintainers of GitHub-hosted PlatformIO firmware that users open in MeshForge.

Quick tips

  • Optional meshforge.yaml — full reference in the next section. Commit it on your default branch so MeshForge can narrow the tag and target pickers.
  • After you push tags or change how the project should be discovered, hit Refresh tags on the repo page so MeshForge pulls the latest from GitHub.
  • Set your repositorys default branch in GitHub to the branch you commit custom changes on (many maintainers name it after the mod). MeshForge periodically scans that branch.

meshforge.yaml

meshforge.yaml is an optional file at the repository root (same level as platformio.ini). It tells MeshForge how to filter Git tags and PlatformIO environments ([env:…] names) in the web UI so users only see combinations that make sense for your project.

Where MeshForge reads it

The tag and target dropdowns use the copy of meshforge.yaml from your repos GitHub default branch (via the GitHub contents API). That means:

  • Put the file on whatever branch you set as default in GitHub settings.
  • When you change the profile, merge or push to that default branch, then use Refresh tags so MeshForge refetches it.
  • The profile is not read separately per selected tag for the pickers—one file on the default branch drives the filters for the whole repo view.

File shape

MeshForge only understands a top-level meshforge: block with optional tags: and targets: sections. Other keys are ignored. The built-in parser is intentionally small: it expects 2-space indentation under meshforge: (tags: / targets: at two spaces, their fields at four), supports line comments (# …), quoted or unquoted string values, and inline lists like [wifi, ble] for require_capabilities. If the file is missing or unparsable, MeshForge shows all tags and all scanned environments (subject to the normal scan).

meshforge:
  tags:
    include: ^v2\.
  targets:
    include: HELTEC|TLORA|TBEAM
    require_capabilities: [wifi]

tags.include

  • Type: string interpreted as a JavaScript RegExp source (same as new RegExp(…) in the browser).
  • Effect: Only tag names that match this pattern stay in the tag dropdown. If the pattern is missing, every tag from GitHub is listed (still sorted as usual).
  • Invalid regex: MeshForge treats the filter as absent and keeps the full tag list.

Use this to hide CI-only tags, old experiments, or anything you do not want offered as a firmware ref—for example ^v\d for SemVer-looking tags only.

targets.include

  • Type: string → JavaScript RegExp over PlatformIO environment names (not display names).
  • Effect: When no include_template applies (see below), environments whose names do not match are hidden from the target picker.
  • Invalid regex: the regex filter is skipped (capabilities can still apply).

targets.include_template (tag-aware targets)

When you want which targets appear to depend on which tag is selected, use tags.include together with targets.include_template:

  1. tags.include must match the currently selected tag; the match is run with RegExp.exec, so you can use capturing groups (...) or named groups (?<name>…) (JavaScript regex syntax).
  2. targets.include_template is a string that becomes a new regex after placeholders are filled in. Each substituted piece is regex-escaped so literal tag text does not break the pattern.

Placeholders

Placeholder Meaning
${1}, ${2}, … Numbered capture groups from tags.include
${myName} Named group (?<myName>…) from tags.include
${myName_snake} Same capture, converted to snake_case
${myName_camel} lowerCamelCase
${myName_pascal} PascalCase

Precedence: If both include_template and tags.include are set and the current tag matches tags.include, the expanded template is the target regex. Otherwise MeshForge uses targets.include as a plain static regex. If neither yields a valid regex, there is no name-based filter (capabilities may still apply).

Example: Tags like acme-1.0.0 where environments are named acme_1_0_0 and acme_1_0_0_debug:

meshforge:
  tags:
    include: ^(?<mod>[a-z]+)-(?<ver>[0-9]+(?:\.[0-9]+)*)$
  targets:
    include_template: ^${mod_snake}_${ver_snake}

The template becomes a regex that still matches if you suffix env names (for example _debug). Adjust the tag regex and template to match how you name tags vs env: sections.

targets.require_capabilities

  • Type: inline list of strings, e.g. [wifi, ble].
  • Effect: An environment is shown only if every listed capability is present on that env. Capabilities are inferred by MeshForge from PlatformIOs platform / board for each env (not read from meshforge.yaml). Today that means roughly:
    • Espressif32 (including pioarduino URLs) → wifi, ble
    • nordicnrf52ble
    • Raspberry Pi / Picowifi and ble only when the board looks like a Pico W (e.g. name contains picow or ends with _w)
    • Other platforms → no inferred capabilities

You can use only require_capabilities (no include / include_template) to, for example, restrict the list to ESP32-class boards. If every env shows no capabilities (for example an old scan completed before capability detection), open the repo again on that ref so MeshForge can rescan; otherwise the capability filter may hide everything.

Practical tips

  • Start without a file, add meshforge.yaml once tag and env lists feel noisy or unsafe for end users.
  • Test regexes in a JavaScript console (new RegExp('…').test('tag-name')) before committing.
  • Refresh tags after editing the file on the default branch so the UI picks up changes quickly.

Release tag naming

Tag releases so users can read both your mod and the upstream base at a glance, for example:

<modName>-<modVersion>-<baseName>-<baseVersion>

That makes it clear which upstream firmware version a release is built on.

Maintaining a fork

  • Start from upstream — Pick a tagged upstream release (often the latest) or any commit, and branch from there for your project (Meshtastic, MeshCore, or any PlatformIO-based LoRa mesh firmware).
  • Default branch — Set that branch as the GitHub default. MeshForge uses it for periodic scans.
  • When upstream tags a new releaseMerge that tag into your branch and continue development. That keeps older release tags meaningful. Do not rebase published history you care about, or those tags will no longer sit on the older base revision users expect.
  • Branch-only workflow — You can maintain a branch without tags; MeshForge builds from the tip of that branch. That works well for experimental projects before you cut releases.