Skip to content

Add firmware publish flow to nh firmware upload - #6

Merged
joshk merged 1 commit into
mainfrom
feat/firmware-publish-deploy
Aug 21, 2026
Merged

joshk merged 1 commit into
mainfrom
feat/firmware-publish-deploy

Conversation

@joshk

@joshk joshk commented Aug 21, 2026 •

Copy link
Copy Markdown
Contributor

Why

The Elixir CLI has nh firmware publish, which signs, uploads, and updates deployment groups. The Go port only has nh firmware upload (sign + upload) — a gap in the migration.

Rather than add a second command that also signs and uploads, this puts the missing behaviour on upload and adds publish as an alias, so old muscle memory and scripts keep working.

What's new

--deploy <group> (repeatable) — points deployment groups at the new firmware once the upload succeeds. Falls back to NERVES_HUB_DEPLOYMENT_NAME (matching the old CLI). A failure here says the upload already succeeded, so the fix is to retry the deployment rather than republish.

nh firmware publish --deploy canary --deploy production

Optional path — inside a Nerves project, nh globs _build/<MIX_TARGET>_<MIX_ENV>/nerves/images/*.fw. No match, or several, is an error naming the pattern (and listing the candidates) rather than a prompt, so CI still works. Detection is a glob, not a mix eval — it can't trigger a compile and costs nothing.

Metadata validation and preview — reads fwup -m -i before uploading. A product mismatch is a hard error (uploading one product's build to another is never intended), and product/version/platform/architecture/uuid are shown. Unreadable metadata only warns, since fwup is optional under --skip-signing.

Behaviour compatibility

Confirmation is asked only when nh picked the file itself. An explicit path is already a statement of intent, and prompting there would break existing non-interactive callers of nh firmware upload. --yes skips it; --non-interactive without --yes on a detected path is a clear refusal.

Ports the parts of the Elixir CLI's `nh firmware publish` that were missing
from the Go port, onto the existing upload command rather than a second
near-duplicate command. `publish` is an alias, so the old name still works.

- --deploy <group> (repeatable) points deployment groups at the new firmware
  once the upload succeeds, falling back to NERVES_HUB_DEPLOYMENT_NAME. A
  failure here reports that the upload already succeeded, so the fix is to
  retry the deployment rather than republish.
- The path is now optional. Inside a Nerves project nh globs
  _build/<MIX_TARGET>_<MIX_ENV>/nerves/images/*.fw, erroring with the pattern
  it tried when there is no single match. Detection is a glob, not a `mix
  eval`, so it cannot trigger a compile.
- The image's own metadata (fwup -m -i) is read before uploading: a product
  mismatch is a hard error, and the product/version/platform/architecture/uuid
  are shown. Unreadable metadata only warns, since fwup is optional under
  --skip-signing.
- Confirmation is asked only when nh picked the file itself. An explicit path
  is already a statement of intent, and prompting for it would break existing
  non-interactive callers of `nh firmware upload`.

--ttl is deliberately not ported. NervesHub dropped firmware TTL in "Remove
OrgLimits" (2023); the upload endpoint discards every non-file param, so the
flag has been a no-op for years.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@joshk
joshk merged commit bfca813 into main Aug 21, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant