mirror of
https://github.com/jkingsman/Remote-Terminal-for-MeshCore.git
synced 2026-05-13 12:56:05 +02:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8843836bdf |
@@ -30,3 +30,4 @@ references/
|
||||
docker-compose.yml
|
||||
docker-compose.yaml
|
||||
.docker-certs/
|
||||
.docker-nginx/
|
||||
|
||||
+334
-353
@@ -1,191 +1,172 @@
|
||||
## [3.6.7] - 2026-03-31
|
||||
|
||||
* Misc: Remove armv7 (for now)
|
||||
|
||||
## [3.6.6] - 2026-03-31
|
||||
|
||||
* Misc: Please I'm begging for the build scripts to be working now
|
||||
|
||||
## [3.6.5] - 2026-03-31
|
||||
|
||||
* Bugfix: Maybe fix problem with publish script
|
||||
|
||||
## [3.6.4] - 2026-03-31
|
||||
|
||||
* Feature: Clarify New Channel/Contact button
|
||||
* Bugfix: Rename "Best RSSI" to "Strongest Neighbor"
|
||||
* Bugfix: Improve layout of Trace pane
|
||||
* Misc: Docker setup improvements
|
||||
|
||||
## [3.6.3] - 2026-03-30
|
||||
|
||||
* Feature: Add multi-byte trace
|
||||
* Feature: Show node name on discovered node if we know it
|
||||
* Feature: Add docker installation script
|
||||
* Feature: Add historical noise floor to stats
|
||||
* Feature: Add trace tool
|
||||
* Bugfix: 100x performance on statistics endpoint with indices and better queries
|
||||
* Misc: Performance and correctness improvements for backend-of-the-frontend
|
||||
* Misc: Reorganize scripts
|
||||
Feature: Add multi-byte trace
|
||||
Feature: Show node name on discovered node if we know it
|
||||
Feature: Add docker installation script
|
||||
Feature: Add historical noise floor to stats
|
||||
Feature: Add trace tool
|
||||
Bugfix: 100x performance on statistics endpoint with indices and better queries
|
||||
Misc: Performance and correctness improvements for backend-of-the-frontend
|
||||
Misc: Reorganize scripts
|
||||
|
||||
## [3.6.2] - 2026-03-29
|
||||
|
||||
* Feature: Be more flexible about timing and volume of full contact offload
|
||||
* Feature: Improve room server and repeater ops to be much more clearer about auth status
|
||||
* Feature: Show last error status on integrations
|
||||
* Feature: Push multi-platform docker builds
|
||||
* Bugfix: Fix advert interval time unit display
|
||||
* Bugfix: Don't cast RSSI/SNR to string for community MQTT
|
||||
* Bugfix: Map uploader follows redirect
|
||||
* Misc: Thin out unnecessary cruft in unreads endpoint
|
||||
* Misc: Fall back gracefully if linked to an unknown contact
|
||||
Feature: Be more flexible about timing and volume of full contact offload
|
||||
Feature: Improve room server and repeater ops to be much more clearer about auth status
|
||||
Feature: Show last error status on integrations
|
||||
Feature: Push multi-platform docker builds
|
||||
Bugfix: Fix advert interval time unit display
|
||||
Bugfix: Don't cast RSSI/SNR to string for community MQTT
|
||||
Bugfix: Map uploader follows redirect
|
||||
Misc: Thin out unnecessary cruft in unreads endpoint
|
||||
Misc: Fall back gracefully if linked to an unknown contact
|
||||
|
||||
## [3.6.1] - 2026-03-26
|
||||
|
||||
* Feature: MeshCore Map integration
|
||||
* Feature: Add warning screen about bots
|
||||
* Feature: Favicon reflects unread message state
|
||||
* Feature: Show hop map in larger modal
|
||||
* Feature: Add prebuilt frontend install script
|
||||
* Feature: Add clean service installer script
|
||||
* Feature: Swipe in to show menu
|
||||
* Bugfix: Invalid backend API path serves error, not fallback index
|
||||
* Bugfix: Fix some spacing/page height issues
|
||||
* Misc: Misc. bugfixes and performance and test improvements
|
||||
Feature: MeshCore Map integration
|
||||
Feature: Add warning screen about bots
|
||||
Feature: Favicon reflects unread message state
|
||||
Feature: Show hop map in larger modal
|
||||
Feature: Add prebuilt frontend install script
|
||||
Feature: Add clean service installer script
|
||||
Feature: Swipe in to show menu
|
||||
Bugfix: Invalid backend API path serves error, not fallback index
|
||||
Bugfix: Fix some spacing/page height issues
|
||||
Misc: Misc. bugfixes and performance and test improvements
|
||||
|
||||
## [3.6.0] - 2026-03-22
|
||||
|
||||
* Feature: Add incoming-packet analytics
|
||||
* Feature: BYOPacket for analysis
|
||||
* Feature: Add room activity to stats view
|
||||
* Bugfix: Handle Heltec v3 serial noise
|
||||
* Misc: Swap repeaters and room servers for better ordering
|
||||
Feature: Add incoming-packet analytics
|
||||
Feature: BYOPacket for analysis
|
||||
Feature: Add room activity to stats view
|
||||
Bugfix: Handle Heltec v3 serial noise
|
||||
Misc: Swap repeaters and room servers for better ordering
|
||||
|
||||
## [3.5.0] - 2026-03-19
|
||||
|
||||
* Feature: Add room server alpha support
|
||||
* Feature: Add option to force-reset node clock when it's too far ahead
|
||||
* Feature: DMs auto-retry before resorting to flood
|
||||
* Feature: Add impulse zero-hop advert
|
||||
* Feature: Utilize PATH packets to correctly source a contact's route
|
||||
* Feature: Metrics view on raw packet pane
|
||||
* Feature: Metric, Imperial, and Smoots are now selectable for distance display
|
||||
* Feature: Allow favorites to be sorted
|
||||
* Feature: Add multi-ack support
|
||||
* Feature: Password-remember checkbox on repeaters + room servers
|
||||
* Bugfix: Serialize radio disconnect in a lock
|
||||
* Bugfix: Fix contact bar layout issues
|
||||
* Bugfix: Fix sidebar ordering for contacts by advert recency
|
||||
* Bugfix: Fix version reporting in community MQTT
|
||||
* Bugfix: Fix Apprise duplicate names
|
||||
* Bugfix: Be better about identity resolution in the stats pane
|
||||
* Misc: Docs, test, and performance enhancements
|
||||
* Misc: Don't prompt "Are you sure" when leaving an unedited interation
|
||||
* Misc: Log node time on startup
|
||||
* Misc: Improve community MQTT error bubble-up
|
||||
* Misc: Unread DMs always have a red unread counter
|
||||
* Misc: Improve information in the debug view to show DB status
|
||||
Feature: Add room server alpha support
|
||||
Feature: Add option to force-reset node clock when it's too far ahead
|
||||
Feature: DMs auto-retry before resorting to flood
|
||||
Feature: Add impulse zero-hop advert
|
||||
Feature: Utilize PATH packets to correctly source a contact's route
|
||||
Feature: Metrics view on raw packet pane
|
||||
Feature: Metric, Imperial, and Smoots are now selectable for distance display
|
||||
Feature: Allow favorites to be sorted
|
||||
Feature: Add multi-ack support
|
||||
Feature: Password-remember checkbox on repeaters + room servers
|
||||
Bugfix: Serialize radio disconnect in a lock
|
||||
Bugfix: Fix contact bar layout issues
|
||||
Bugfix: Fix sidebar ordering for contacts by advert recency
|
||||
Bugfix: Fix version reporting in community MQTT
|
||||
Bugfix: Fix Apprise duplicate names
|
||||
Bugfix: Be better about identity resolution in the stats pane
|
||||
Misc: Docs, test, and performance enhancements
|
||||
Misc: Don't prompt "Are you sure" when leaving an unedited interation
|
||||
Misc: Log node time on startup
|
||||
Misc: Improve community MQTT error bubble-up
|
||||
Misc: Unread DMs always have a red unread counter
|
||||
Misc: Improve information in the debug view to show DB status
|
||||
|
||||
## [3.4.1] - 2026-03-16
|
||||
|
||||
* Bugfix: Improve handling of version information on prebuilt bundles
|
||||
* Bugfix: Improve frontend usability on disconnected radio
|
||||
* Misc: Docs and readme updates
|
||||
* Misc: Overhaul DM ingest and frontend state handling
|
||||
Bugfix: Improve handling of version information on prebuilt bundles
|
||||
Bugfix: Improve frontend usability on disconnected radio
|
||||
Misc: Docs and readme updates
|
||||
Misc: Overhaul DM ingest and frontend state handling
|
||||
|
||||
## [3.4.0] - 2026-03-16
|
||||
|
||||
* Feature: Add radio model and stats display
|
||||
* Feature: Add prebuilt frontends, then deleted that and moved to prebuilt release artifacts
|
||||
* Bugfix: Misc. frontend performance and correctness fixes
|
||||
* Bugfix: Fix same-second same-content DM send collition
|
||||
* Bugfix: Discard clearly-wrong GPS data
|
||||
* Bugfix: Prevent repeater clock skew drift on page nav
|
||||
* Misc: Use repeater's advertised location if we haven't loaded one from repeater admin
|
||||
* Misc: Don't permit invalid fanout configs to be saved ever`
|
||||
Feature: Add radio model and stats display
|
||||
Feature: Add prebuilt frontends, then deleted that and moved to prebuilt release artifacts
|
||||
Bugfix: Misc. frontend performance and correctness fixes
|
||||
Bugfix: Fix same-second same-content DM send collition
|
||||
Bugfix: Discard clearly-wrong GPS data
|
||||
Bugfix: Prevent repeater clock skew drift on page nav
|
||||
Misc: Use repeater's advertised location if we haven't loaded one from repeater admin
|
||||
Misc: Don't permit invalid fanout configs to be saved ever`
|
||||
|
||||
## [3.3.0] - 2026-03-13
|
||||
|
||||
* Feature: Use dashed lines to show collapsed ambiguous router results
|
||||
* Feature: Jump to unred
|
||||
* Feature: Local channel management to prevent need to reload channel every time
|
||||
* Feature: Debug endpoint
|
||||
* Feature: Force-singleton channel management
|
||||
* Feature: Local node discovery
|
||||
* Feature: Node routing discovery
|
||||
* Bugfix: Don't tell users to us npm ci
|
||||
* Bugfix: Fallback polling dm message persistence
|
||||
* Bugfix: All native-JS inputs are now modals
|
||||
* Bugfix: Same-second send collision resolution
|
||||
* Bugfix: Proper browser updates on resend
|
||||
* Bugfix: Don't use last-heard when we actually want last-advert for path discovery for nodes
|
||||
* Bugfix: Don't treat prefix-matching DM echoes as acks like we do for channel messages
|
||||
* Misc: Visualizer data layer overhaul for future map work
|
||||
* Misc: Parallelize docker tests
|
||||
Feature: Use dashed lines to show collapsed ambiguous router results
|
||||
Feature: Jump to unred
|
||||
Feature: Local channel management to prevent need to reload channel every time
|
||||
Feature: Debug endpoint
|
||||
Feature: Force-singleton channel management
|
||||
Feature: Local node discovery
|
||||
Feature: Node routing discovery
|
||||
Bugfix: Don't tell users to us npm ci
|
||||
Bugfix: Fallback polling dm message persistence
|
||||
Bugfix: All native-JS inputs are now modals
|
||||
Bugfix: Same-second send collision resolution
|
||||
Bugfix: Proper browser updates on resend
|
||||
Bugfix: Don't use last-heard when we actually want last-advert for path discovery for nodes
|
||||
Bugfix: Don't treat prefix-matching DM echoes as acks like we do for channel messages
|
||||
Misc: Visualizer data layer overhaul for future map work
|
||||
Misc: Parallelize docker tests
|
||||
|
||||
## [3.2.0] - 2026-03-12
|
||||
|
||||
* Feature: Improve ambiguous-sender DM handling and visibility
|
||||
* Feature: Allow for toggling of node GPS broadcast
|
||||
* Feature: Add path width to bot and move example to full kwargs
|
||||
* Feature: Improve node map color contrast
|
||||
* Bugfix: More accurate tracking of contact data
|
||||
* Bugfix: Misc. frontend performance and bugfixes
|
||||
* Misc: Clearer warnings on user-key linkage
|
||||
* Misc: Documentation improvements
|
||||
Feature: Improve ambiguous-sender DM handling and visibility
|
||||
Feature: Allow for toggling of node GPS broadcast
|
||||
Feature: Add path width to bot and move example to full kwargs
|
||||
Feature: Improve node map color contrast
|
||||
Bugfix: More accurate tracking of contact data
|
||||
Bugfix: Misc. frontend performance and bugfixes
|
||||
Misc: Clearer warnings on user-key linkage
|
||||
Misc: Documentation improvements
|
||||
|
||||
## [3.1.1] - 2026-03-11
|
||||
|
||||
* Feature: Add basic auth
|
||||
* Feature: SQS fanout
|
||||
* Feature: Enrich contact info pane
|
||||
* Feature: Search operators for node and channel
|
||||
* Feature: Pause radio connection attempts from Radio settings
|
||||
* Feature: New themes! What a great use of time!
|
||||
* Feature: Github workflows runs for validation
|
||||
* Bugfix: More consistent log format with times
|
||||
* Bugfix: Patch meshcore_py bluetooth eager reconnection out during pauses
|
||||
Feature: Add basic auth
|
||||
Feature: SQS fanout
|
||||
Feature: Enrich contact info pane
|
||||
Feature: Search operators for node and channel
|
||||
Feature: Pause radio connection attempts from Radio settings
|
||||
Feature: New themes! What a great use of time!
|
||||
Feature: Github workflows runs for validation
|
||||
Bugfix: More consistent log format with times
|
||||
Bugfix: Patch meshcore_py bluetooth eager reconnection out during pauses
|
||||
|
||||
## [3.1.0] - 2026-03-11
|
||||
|
||||
* Feature: Add basic auth
|
||||
* Feature: SQS fanout
|
||||
* Feature: Enrich contact info pane
|
||||
* Feature: Search operators for node and channel
|
||||
* Feature: Pause radio connection attempts from Radio settings
|
||||
* Feature: New themes! What a great use of time!
|
||||
* Feature: Github workflows runs for validation
|
||||
* Bugfix: More consistent log format with times
|
||||
* Bugfix: Patch meshcore_py bluetooth eager reconnection out during pauses
|
||||
Feature: Add basic auth
|
||||
Feature: SQS fanout
|
||||
Feature: Enrich contact info pane
|
||||
Feature: Search operators for node and channel
|
||||
Feature: Pause radio connection attempts from Radio settings
|
||||
Feature: New themes! What a great use of time!
|
||||
Feature: Github workflows runs for validation
|
||||
Bugfix: More consistent log format with times
|
||||
Bugfix: Patch meshcore_py bluetooth eager reconnection out during pauses
|
||||
|
||||
## [3.0.0] - 2026-03-10
|
||||
|
||||
* Feature: Custom regions per-channel
|
||||
* Feature: Add custom contact pathing
|
||||
* Feature: Corrupt packets are more clear that they're corrupt
|
||||
* Feature: Better, faster patterns around background fetching with explicit opt-in for recurring sync if the app detects you need it
|
||||
* Feature: More consistent icons
|
||||
* Feature: Add per-channel local notifications
|
||||
* Feature: New themes
|
||||
* Feature: Massive codebase refactor and overhaul
|
||||
* Bugfix: Fix packet parsing for trace packets
|
||||
* Bugfix: Refetch channels on reconnect
|
||||
* Bugfix: Load All on repeater pane on mobile doesn't etend into lower text
|
||||
* Bugfix: Timestamps in logs
|
||||
* Bugfix: Correct wrong clock sync command
|
||||
* Misc: Improve bot error bubble up
|
||||
* Misc: Update to non-lib-included meshcore-decoder version
|
||||
* Misc: Revise refactors to be more LLM friendly
|
||||
* Misc: Fix script executability
|
||||
* Misc: Better logging format with timestamp
|
||||
* Misc: Repeater advert buttons separate flood and one-hop
|
||||
* Misc: Preserve repeater pane on navigation away
|
||||
* Misc: Clearer iconography and coloring for status bar buttons
|
||||
* Misc: Search bar to top bar
|
||||
Feature: Custom regions per-channel
|
||||
Feature: Add custom contact pathing
|
||||
Feature: Corrupt packets are more clear that they're corrupt
|
||||
Feature: Better, faster patterns around background fetching with explicit opt-in for recurring sync if the app detects you need it
|
||||
Feature: More consistent icons
|
||||
Feature: Add per-channel local notifications
|
||||
Feature: New themes
|
||||
Feature: Massive codebase refactor and overhaul
|
||||
Bugfix: Fix packet parsing for trace packets
|
||||
Bugfix: Refetch channels on reconnect
|
||||
Bugfix: Load All on repeater pane on mobile doesn't etend into lower text
|
||||
Bugfix: Timestamps in logs
|
||||
Bugfix: Correct wrong clock sync command
|
||||
Misc: Improve bot error bubble up
|
||||
Misc: Update to non-lib-included meshcore-decoder version
|
||||
Misc: Revise refactors to be more LLM friendly
|
||||
Misc: Fix script executability
|
||||
Misc: Better logging format with timestamp
|
||||
Misc: Repeater advert buttons separate flood and one-hop
|
||||
Misc: Preserve repeater pane on navigation away
|
||||
Misc: Clearer iconography and coloring for status bar buttons
|
||||
Misc: Search bar to top bar
|
||||
|
||||
## [2.7.9] - 2026-03-08
|
||||
|
||||
* Bugfix: Don't obscure new integration dropdown on session boundary
|
||||
Bugfix: Don't obscure new integration dropdown on session boundary
|
||||
|
||||
## [2.7.8] - 2026-03-08
|
||||
|
||||
@@ -193,287 +174,287 @@
|
||||
|
||||
## [2.7.8] - 2026-03-08
|
||||
|
||||
* Bugfix: Improve frontend asset resolution and fixup the build/push script
|
||||
Bugfix: Improve frontend asset resolution and fixup the build/push script
|
||||
|
||||
## [2.7.1] - 2026-03-08
|
||||
|
||||
* Bugfix: Fix historical DM packet length passing
|
||||
* Misc: Follow better inclusion patterns for the patched meshcore-decoder and just publish the dang package
|
||||
* Misc: Patch a bewildering browser quirk that cause large raw packet lists to extend past the bottom of the page
|
||||
Bugfix: Fix historical DM packet length passing
|
||||
Misc: Follow better inclusion patterns for the patched meshcore-decoder and just publish the dang package
|
||||
Misc: Patch a bewildering browser quirk that cause large raw packet lists to extend past the bottom of the page
|
||||
|
||||
## [2.7.0] - 2026-03-08
|
||||
|
||||
* Feature: Multibyte path support
|
||||
* Feature: Add multibyte statistics to statistics pane
|
||||
* Feature: Add path bittage to contact info pane
|
||||
* Feature: Put tools in a collapsible
|
||||
Feature: Multibyte path support
|
||||
Feature: Add multibyte statistics to statistics pane
|
||||
Feature: Add path bittage to contact info pane
|
||||
Feature: Put tools in a collapsible
|
||||
|
||||
## [2.6.1] - 2026-03-08
|
||||
|
||||
* Misc: Fix busted docker builds; we don't have a 2.6.0 build sorry
|
||||
Misc: Fix busted docker builds; we don't have a 2.6.0 build sorry
|
||||
|
||||
## [2.6.0] - 2026-03-08
|
||||
|
||||
* Feature: A11y improvements
|
||||
* Feature: New themes
|
||||
* Feature: Backfill channel sender identity when available
|
||||
* Feature: Modular fanout bus, including Webhooks, more customizable community MQTT, and Apprise
|
||||
* Bugfix: Unreads now respect blocklist
|
||||
* Bugfix: Unreads can't accumulate on an open thread
|
||||
* Bugfix: Channel name in broadcasts
|
||||
* Bugfix: Add missing httpx dependency
|
||||
* Bugfix: Improvements to radio startup frontend-blocking time and radio status reporting
|
||||
* Misc: Improved button signage for app movement
|
||||
* Misc: Test, performance, and documentation improvements
|
||||
Feature: A11y improvements
|
||||
Feature: New themes
|
||||
Feature: Backfill channel sender identity when available
|
||||
Feature: Modular fanout bus, including Webhooks, more customizable community MQTT, and Apprise
|
||||
Bugfix: Unreads now respect blocklist
|
||||
Bugfix: Unreads can't accumulate on an open thread
|
||||
Bugfix: Channel name in broadcasts
|
||||
Bugfix: Add missing httpx dependency
|
||||
Bugfix: Improvements to radio startup frontend-blocking time and radio status reporting
|
||||
Misc: Improved button signage for app movement
|
||||
Misc: Test, performance, and documentation improvements
|
||||
|
||||
## [2.5.0] - 2026-03-05
|
||||
|
||||
* Feature: Far better accessibility across the app (with far to go)
|
||||
* Feature: Add community MQTT stats reporting, and improve over a few commits
|
||||
* Feature: Color schemes and misc. settings reorg
|
||||
* Feature: Add why-active to filtered nodes
|
||||
* Feature: Add channel and contact info box
|
||||
* Feature: Add contact blocking
|
||||
* Feature: Add potential repeater path map display
|
||||
* Feature: Add flood scoping/regions
|
||||
* Feature: Global message search
|
||||
* Feature: Fully safe bot disable
|
||||
* Feature: Add default #remoteterm channel (lol sorry I had to)
|
||||
* Feature: Custom recency pruning in visualizer
|
||||
* Bugfix: Be more cautious around null byte stripping
|
||||
* Bugfix: Clear channel-add interface on not-add-another
|
||||
* Bugfix: Add status/name/MQTT LWT
|
||||
* Bugfix: Channel deletion propagates over WS
|
||||
* Bugfix: Show map location for all nodes on link, not 7-day-limited
|
||||
* Bugfix: Hide private key channel keys by default
|
||||
* Misc: Logline to show if cleanup loop on non-sync'd meshcore radio links fixes anything
|
||||
* Misc: Doc, changelog, and test improvements
|
||||
* Misc: Add, and remove, package lock (sorry Windows users)
|
||||
* Misc: Don't show mark all as read if not necessary
|
||||
* Misc: Fix stale closures and misc. frontend perf/correctness improvements
|
||||
* Misc: Add Windows startup notes
|
||||
* Misc: E2E expansion + improvement
|
||||
* Misc: Move around visualizer settings
|
||||
Feature: Far better accessibility across the app (with far to go)
|
||||
Feature: Add community MQTT stats reporting, and improve over a few commits
|
||||
Feature: Color schemes and misc. settings reorg
|
||||
Feature: Add why-active to filtered nodes
|
||||
Feature: Add channel and contact info box
|
||||
Feature: Add contact blocking
|
||||
Feature: Add potential repeater path map display
|
||||
Feature: Add flood scoping/regions
|
||||
Feature: Global message search
|
||||
Feature: Fully safe bot disable
|
||||
Feature: Add default #remoteterm channel (lol sorry I had to)
|
||||
Feature: Custom recency pruning in visualizer
|
||||
Bugfix: Be more cautious around null byte stripping
|
||||
Bugfix: Clear channel-add interface on not-add-another
|
||||
Bugfix: Add status/name/MQTT LWT
|
||||
Bugfix: Channel deletion propagates over WS
|
||||
Bugfix: Show map location for all nodes on link, not 7-day-limited
|
||||
Bugfix: Hide private key channel keys by default
|
||||
Misc: Logline to show if cleanup loop on non-sync'd meshcore radio links fixes anything
|
||||
Misc: Doc, changelog, and test improvements
|
||||
Misc: Add, and remove, package lock (sorry Windows users)
|
||||
Misc: Don't show mark all as read if not necessary
|
||||
Misc: Fix stale closures and misc. frontend perf/correctness improvements
|
||||
Misc: Add Windows startup notes
|
||||
Misc: E2E expansion + improvement
|
||||
Misc: Move around visualizer settings
|
||||
|
||||
## [2.4.0] - 2026-03-02
|
||||
|
||||
* Feature: Add community MQTT reporting (e.g. LetsMesh.net)
|
||||
* Misc: Build scripts and library attribution
|
||||
* Misc: Add sign of life to E2E tests
|
||||
Feature: Add community MQTT reporting (e.g. LetsMesh.net)
|
||||
Misc: Build scripts and library attribution
|
||||
Misc: Add sign of life to E2E tests
|
||||
|
||||
## [2.3.0] - 2026-03-01
|
||||
|
||||
* Feature: Click path description to reset to flood
|
||||
* Feature: Add MQTT publishing
|
||||
* Feature: Visualizer remembers settings
|
||||
* Bugfix: Fix prefetch usage
|
||||
* Bugfix: Fixed an issue where busy channels can result in double-display of incoming messages
|
||||
* Misc: Drop py3.12 requirement
|
||||
* Misc: Performance, documentation, test, and file structure optimizations
|
||||
* Misc: Add arrows between route nodes on contact info
|
||||
* Misc: Show repeater path/type in title bar
|
||||
Feature: Click path description to reset to flood
|
||||
Feature: Add MQTT publishing
|
||||
Feature: Visualizer remembers settings
|
||||
Bugfix: Fix prefetch usage
|
||||
Bugfix: Fixed an issue where busy channels can result in double-display of incoming messages
|
||||
Misc: Drop py3.12 requirement
|
||||
Misc: Performance, documentation, test, and file structure optimizations
|
||||
Misc: Add arrows between route nodes on contact info
|
||||
Misc: Show repeater path/type in title bar
|
||||
|
||||
## [2.2.0] - 2026-02-28
|
||||
|
||||
* Feature: Track advert paths and use to disambiguate repeater identity in visualizer
|
||||
* Feature: Contact info pane
|
||||
* Feature: Overhaul repeater interface
|
||||
* Bugfix: Misc. frontend rendering + perf improvements
|
||||
* Bugfix: Better behavior around radio locking and autofetch/polling
|
||||
* Bugfix: Clear channel name field on new-channel modal tab change
|
||||
* Bugfix: Repeater inforbox can scroll
|
||||
* Bugfix: Better handling of historical DM encrypts
|
||||
* Bugfix: Handle errors if returned in prefetch phase
|
||||
* Misc: Radio event response failure is logged/surfaced better
|
||||
* Misc: Improve test coverage and remove dead code
|
||||
* Misc: Documentation and errata improvements
|
||||
* Misc: Database storage optimization
|
||||
Feature: Track advert paths and use to disambiguate repeater identity in visualizer
|
||||
Feature: Contact info pane
|
||||
Feature: Overhaul repeater interface
|
||||
Bugfix: Misc. frontend rendering + perf improvements
|
||||
Bugfix: Better behavior around radio locking and autofetch/polling
|
||||
Bugfix: Clear channel name field on new-channel modal tab change
|
||||
Bugfix: Repeater inforbox can scroll
|
||||
Bugfix: Better handling of historical DM encrypts
|
||||
Bugfix: Handle errors if returned in prefetch phase
|
||||
Misc: Radio event response failure is logged/surfaced better
|
||||
Misc: Improve test coverage and remove dead code
|
||||
Misc: Documentation and errata improvements
|
||||
Misc: Database storage optimization
|
||||
|
||||
## [2.1.0] - 2026-02-23
|
||||
|
||||
* Feature: Add ability to remember last-used channel on load
|
||||
* Feature: Add `docker compose` support (thanks @suymur !)
|
||||
* Feature: Better-aligned favicon (lol)
|
||||
* Bugfix: Disable autocomplete on message field
|
||||
* Bugfix: Legacy hash restoration on page load
|
||||
* Bugfix: Align resend buttons in pathing modal
|
||||
* Bugfix: Update README.md (briefly), then docker-compose.yaml, to reflect correct docker image host
|
||||
* Bugfix: Correct settings pane scroll lock on zoom (thanks @yellowcooln !)
|
||||
* Bugfix: Improved repeater comms on busy meshes
|
||||
* Bugfix: Drain before autofetch from radio
|
||||
* Bugfix: Fix, or document exceptions to, sub-second resolution message failure
|
||||
* Bugfix: Improved handling of radio connection, disconnection, and connection-aliveness-status
|
||||
* Bugfix: Force server-side keystore update when radio key changes
|
||||
* Bugfix: Reduce WS churn for incoming message handling
|
||||
* Bugfix: Fix content type signalling for irrelevant endpoints
|
||||
* Bugfix: Handle stuck post-connect failure state
|
||||
* Misc: Documentation & version parsing improvements
|
||||
* Misc: Hide char counter on mobile for short messages
|
||||
* Misc: Typo fixes in docs and settings
|
||||
* Misc: Add dynamic webmanifest for hosts that can support it
|
||||
* Misc: Improve DB size via dropping unnecessary uniqs, indices, vacuum, and offering ability to drop historical matches packets
|
||||
* Misc: Drop weird rounded bounding box for settings
|
||||
* Misc: Move resend buttons to pathing modal
|
||||
* Misc: Improved comments around database ownership on *nix systems
|
||||
* Misc: Move to SSoT for message dedupe on frontend
|
||||
* Misc: Move DM ack clearing to standard poll, and increase hold time between polling
|
||||
* Misc: Holistic testing overhaul
|
||||
Feature: Add ability to remember last-used channel on load
|
||||
Feature: Add `docker compose` support (thanks @suymur !)
|
||||
Feature: Better-aligned favicon (lol)
|
||||
Bugfix: Disable autocomplete on message field
|
||||
Bugfix: Legacy hash restoration on page load
|
||||
Bugfix: Align resend buttons in pathing modal
|
||||
Bugfix: Update README.md (briefly), then docker-compose.yaml, to reflect correct docker image host
|
||||
Bugfix: Correct settings pane scroll lock on zoom (thanks @yellowcooln !)
|
||||
Bugfix: Improved repeater comms on busy meshes
|
||||
Bugfix: Drain before autofetch from radio
|
||||
Bugfix: Fix, or document exceptions to, sub-second resolution message failure
|
||||
Bugfix: Improved handling of radio connection, disconnection, and connection-aliveness-status
|
||||
Bugfix: Force server-side keystore update when radio key changes
|
||||
Bugfix: Reduce WS churn for incoming message handling
|
||||
Bugfix: Fix content type signalling for irrelevant endpoints
|
||||
Bugfix: Handle stuck post-connect failure state
|
||||
Misc: Documentation & version parsing improvements
|
||||
Misc: Hide char counter on mobile for short messages
|
||||
Misc: Typo fixes in docs and settings
|
||||
Misc: Add dynamic webmanifest for hosts that can support it
|
||||
Misc: Improve DB size via dropping unnecessary uniqs, indices, vacuum, and offering ability to drop historical matches packets
|
||||
Misc: Drop weird rounded bounding box for settings
|
||||
Misc: Move resend buttons to pathing modal
|
||||
Misc: Improved comments around database ownership on *nix systems
|
||||
Misc: Move to SSoT for message dedupe on frontend
|
||||
Misc: Move DM ack clearing to standard poll, and increase hold time between polling
|
||||
Misc: Holistic testing overhaul
|
||||
|
||||
## [2.0.1] - 2026-02-16
|
||||
|
||||
* Bugfix: Fix missing trigger condition on statistics pane expansion on mobile
|
||||
Bugfix: Fix missing trigger condition on statistics pane expansion on mobile
|
||||
|
||||
## [2.0.0] - 2026-02-16
|
||||
|
||||
* Feature: Frontend UX + log overhaul
|
||||
* Bugfix: Use contact object from DB for broadcast rather than handrolling
|
||||
* Bugfix: Fix out of order path WS messages overwriting each other
|
||||
* Bugfix: Make broadcast timestamp match fallback logic used in storage code
|
||||
* Bugfix: Fix repeater command timestamp selection logic
|
||||
* Bugfix: Use actual pubkey matching for path update, and don't action serial path update events (use RX packet)
|
||||
* Bugfix: Add missing radio operation locks in a few spots
|
||||
* Bugfix: Fix dedupe for frontend raw packet delivery (mesh visualizer much more active now!)
|
||||
* Bugfix: Less aggressive dedupe for advert packets (we don't care about the payload, we care about the path, duh)
|
||||
* Misc: Visualizer layout refinement & option labels
|
||||
Feature: Frontend UX + log overhaul
|
||||
Bugfix: Use contact object from DB for broadcast rather than handrolling
|
||||
Bugfix: Fix out of order path WS messages overwriting each other
|
||||
Bugfix: Make broadcast timestamp match fallback logic used in storage code
|
||||
Bugfix: Fix repeater command timestamp selection logic
|
||||
Bugfix: Use actual pubkey matching for path update, and don't action serial path update events (use RX packet)
|
||||
Bugfix: Add missing radio operation locks in a few spots
|
||||
Bugfix: Fix dedupe for frontend raw packet delivery (mesh visualizer much more active now!)
|
||||
Bugfix: Less aggressive dedupe for advert packets (we don't care about the payload, we care about the path, duh)
|
||||
Misc: Visualizer layout refinement & option labels
|
||||
|
||||
## [1.10.0] - 2026-02-16
|
||||
|
||||
* Feature: Collapsible sidebar sections with per-section unread badge (thanks @rgregg !)
|
||||
* Feature: 3D mesh visualizer
|
||||
* Feature: Statistics pane
|
||||
* Feature: Support incoming/outgoing indication for bot invocations
|
||||
* Feature: Quick byte-perfect message resend if you got unlucky with repeats (thanks @rgregg -- we had a parallel implementation but I appreciate your work!)
|
||||
* Bugfix: Fix top padding out outgoing message
|
||||
* Bugfix: Frontend performance, appearance, and Lighthouse improvements (prefetches, form labelling, contrast, channel/roomlist changes)
|
||||
* Bugfix: Multiple-sent messages had path appearing delays until rerender
|
||||
* Bugfix: Fix ack/message race condition that caused dropped ack displays until rerender
|
||||
* Misc: Dedupe contacts/rooms by key and not name to prevent name collisions creating unreachable conversations
|
||||
* Misc: s/stopped/idle/ for room finder
|
||||
Feature: Collapsible sidebar sections with per-section unread badge (thanks @rgregg !)
|
||||
Feature: 3D mesh visualizer
|
||||
Feature: Statistics pane
|
||||
Feature: Support incoming/outgoing indication for bot invocations
|
||||
Feature: Quick byte-perfect message resend if you got unlucky with repeats (thanks @rgregg -- we had a parallel implementation but I appreciate your work!)
|
||||
Bugfix: Fix top padding out outgoing message
|
||||
Bugfix: Frontend performance, appearance, and Lighthouse improvements (prefetches, form labelling, contrast, channel/roomlist changes)
|
||||
Bugfix: Multiple-sent messages had path appearing delays until rerender
|
||||
Bugfix: Fix ack/message race condition that caused dropped ack displays until rerender
|
||||
Misc: Dedupe contacts/rooms by key and not name to prevent name collisions creating unreachable conversations
|
||||
Misc: s/stopped/idle/ for room finder
|
||||
|
||||
## [1.9.3] - 2026-02-12
|
||||
|
||||
* Feature: Upgrade the room finder to support two-word rooms
|
||||
Feature: Upgrade the room finder to support two-word rooms
|
||||
|
||||
## [1.9.2] - 2026-02-12
|
||||
|
||||
* Feature: Options dialog sucks less
|
||||
* Bugfix: Move tests to isolated memory DB
|
||||
* Bugfix: Mention case sensitivity
|
||||
* Bugfix: Stale header retention on settings page view
|
||||
* Bugfix: Non-isolated path writing
|
||||
* Bugfix: Nullable contact fields are now passed as real nulls
|
||||
* Bugfix: Look at all fields on message reconcile, not just text
|
||||
* Bugfix: Make mark-all-as-read atomic
|
||||
* Misc: Purge unused WS handlers from back when we did chans and contacts over WS, not API
|
||||
* Misc: Massive test and AGENTS.md overhauls and additions
|
||||
Feature: Options dialog sucks less
|
||||
Bugfix: Move tests to isolated memory DB
|
||||
Bugfix: Mention case sensitivity
|
||||
Bugfix: Stale header retention on settings page view
|
||||
Bugfix: Non-isolated path writing
|
||||
Bugfix: Nullable contact fields are now passed as real nulls
|
||||
Bugfix: Look at all fields on message reconcile, not just text
|
||||
Bugfix: Make mark-all-as-read atomic
|
||||
Misc: Purge unused WS handlers from back when we did chans and contacts over WS, not API
|
||||
Misc: Massive test and AGENTS.md overhauls and additions
|
||||
|
||||
## [1.9.1] - 2026-02-10
|
||||
|
||||
* Feature: Contacts and channels use keys, not names
|
||||
* Bugfix: Fix falsy casting of 0 in lat lon and timing data
|
||||
* Bugfix: Show message length in bytes, not chars
|
||||
* Bugfix: Fix phantom unread badges on focused convos
|
||||
* Misc: Bot invocation to async
|
||||
* Misc: Use full key, not prefix, where we can
|
||||
Feature: Contacts and channels use keys, not names
|
||||
Bugfix: Fix falsy casting of 0 in lat lon and timing data
|
||||
Bugfix: Show message length in bytes, not chars
|
||||
Bugfix: Fix phantom unread badges on focused convos
|
||||
Misc: Bot invocation to async
|
||||
Misc: Use full key, not prefix, where we can
|
||||
|
||||
## [1.9.0] - 2026-02-10
|
||||
|
||||
* Feature: Favorited contacts are preferentially loaded onto the radio
|
||||
* Feature: Add recent-message caching for fast switching
|
||||
* Feature: Add echo paths modal when echo-heard checkbox is clicked
|
||||
* Feature: Add experimental byte-perfect double-send for bad RF environments to try to punch the message out
|
||||
Feature: Favorited contacts are preferentially loaded onto the radio
|
||||
Feature: Add recent-message caching for fast switching
|
||||
Feature: Add echo paths modal when echo-heard checkbox is clicked
|
||||
Feature: Add experimental byte-perfect double-send for bad RF environments to try to punch the message out
|
||||
Frontend: Better styling on echo + message path display
|
||||
* Bugfix: Prevent frontend static file serving path traversal vuln
|
||||
* Bugfix: Safer prefix-claiming for DMs we don't have the key for
|
||||
* Bugfix: Prevent injection from mentions with special characters
|
||||
* Bugfix: Fix repeaters comms showing in wrong channel when repeater operations are in flight and the channel is changed quickly
|
||||
* Bugfix: App can boot and test without a frontend dir
|
||||
* Misc: Improve and consistent-ify (?) backend radio operation lock management
|
||||
* Misc: Frontend performance and safety enhancements
|
||||
* Misc: Move builds to non-bundled; usage requires building the Frontend
|
||||
* Misc: Update tests and agent docs
|
||||
Bugfix: Prevent frontend static file serving path traversal vuln
|
||||
Bugfix: Safer prefix-claiming for DMs we don't have the key for
|
||||
Bugfix: Prevent injection from mentions with special characters
|
||||
Bugfix: Fix repeaters comms showing in wrong channel when repeater operations are in flight and the channel is changed quickly
|
||||
Bugfix: App can boot and test without a frontend dir
|
||||
Misc: Improve and consistent-ify (?) backend radio operation lock management
|
||||
Misc: Frontend performance and safety enhancements
|
||||
Misc: Move builds to non-bundled; usage requires building the Frontend
|
||||
Misc: Update tests and agent docs
|
||||
|
||||
## [1.8.0] - 2026-02-07
|
||||
|
||||
* Feature: Single hop ping
|
||||
* Feature: PWA viewport fixes(thanks @rgregg)
|
||||
Feature: Single hop ping
|
||||
Feature: PWA viewport fixes(thanks @rgregg)
|
||||
Feature (?): No frontend distribution; build it yourself ;P
|
||||
* Bugfix: Fix channel message send race condition (concurrent sends could corrupt shared radio slot)
|
||||
* Bugfix: Fix TOCTOU race in radio reconnect (duplicate connections under contention)
|
||||
* Bugfix: Better guarding around reconnection
|
||||
* Bugfix: Duplicate websocket connection fixes
|
||||
* Bugfix: Settings tab error cleanliness on tab swap
|
||||
* Bugfix: Fix path traversal vuln
|
||||
Bugfix: Fix channel message send race condition (concurrent sends could corrupt shared radio slot)
|
||||
Bugfix: Fix TOCTOU race in radio reconnect (duplicate connections under contention)
|
||||
Bugfix: Better guarding around reconnection
|
||||
Bugfix: Duplicate websocket connection fixes
|
||||
Bugfix: Settings tab error cleanliness on tab swap
|
||||
Bugfix: Fix path traversal vuln
|
||||
UI: Swap visualizer legend ordering (yay prettier)
|
||||
* Misc: Perf and locking improvements
|
||||
* Misc: Always flood advertisements
|
||||
* Misc: Better packet dupe handling
|
||||
* Misc: Dead code cleanup, test improvements
|
||||
Misc: Perf and locking improvements
|
||||
Misc: Always flood advertisements
|
||||
Misc: Better packet dupe handling
|
||||
Misc: Dead code cleanup, test improvements
|
||||
|
||||
## [1.7.1] - 2026-02-03
|
||||
|
||||
* Feature: Clickable hyperlinks
|
||||
* Bugfix: More consistent public key normalization
|
||||
* Bugfix: Use more reliable cursor paging
|
||||
* Bugfix: Fix null timestamp dedupe failure
|
||||
* Bugfix: More consistent prefix-based message claiming on key receipt
|
||||
* Misc: Bot can respond to its own messages
|
||||
* Misc: Additional tests
|
||||
* Misc: Remove unneeded message dedupe logic
|
||||
* Misc: Resync settings after radio settings mutation
|
||||
Feature: Clickable hyperlinks
|
||||
Bugfix: More consistent public key normalization
|
||||
Bugfix: Use more reliable cursor paging
|
||||
Bugfix: Fix null timestamp dedupe failure
|
||||
Bugfix: More consistent prefix-based message claiming on key receipt
|
||||
Misc: Bot can respond to its own messages
|
||||
Misc: Additional tests
|
||||
Misc: Remove unneeded message dedupe logic
|
||||
Misc: Resync settings after radio settings mutation
|
||||
|
||||
## [1.7.0] - 2026-01-27
|
||||
|
||||
* Feature: Multi-bot functionality
|
||||
* Bugfix: Adjust bot code editor display and add line numbers
|
||||
* Bugfix: Fix clock filtering and contact lookup behavior bugs
|
||||
* Bugfix: Fix repeater message duplication issue
|
||||
* Bugfix: Correct outbound message timestamp assignment (affecting outgoing messages seen as incoming)
|
||||
Feature: Multi-bot functionality
|
||||
Bugfix: Adjust bot code editor display and add line numbers
|
||||
Bugfix: Fix clock filtering and contact lookup behavior bugs
|
||||
Bugfix: Fix repeater message duplication issue
|
||||
Bugfix: Correct outbound message timestamp assignment (affecting outgoing messages seen as incoming)
|
||||
UI: Move advertise button to identity tab
|
||||
* Misc: Clarify fallback functionality for missing private key export in logs
|
||||
Misc: Clarify fallback functionality for missing private key export in logs
|
||||
|
||||
## [1.6.0] - 2026-01-26
|
||||
|
||||
* Feature: Visualizer: extract public key from AnonReq, add heuristic repeater disambiguation, add reset button, draggable nodes
|
||||
* Feature: Customizable advertising interval
|
||||
* Feature: In-app bot setup
|
||||
* Bugfix: Force contact onto radio before DM send
|
||||
* Misc: Remove unused code
|
||||
Feature: Visualizer: extract public key from AnonReq, add heuristic repeater disambiguation, add reset button, draggable nodes
|
||||
Feature: Customizable advertising interval
|
||||
Feature: In-app bot setup
|
||||
Bugfix: Force contact onto radio before DM send
|
||||
Misc: Remove unused code
|
||||
|
||||
## [1.5.0] - 2026-01-19
|
||||
|
||||
* Feature: Network visualizer
|
||||
Feature: Network visualizer
|
||||
|
||||
## [1.4.1] - 2026-01-19
|
||||
|
||||
* Feature: Add option to attempt historical DM decrypt on new-contact advertisement (disabled by default)
|
||||
* Feature: Server-side preference management for favorites, read status, etc.
|
||||
Feature: Add option to attempt historical DM decrypt on new-contact advertisement (disabled by default)
|
||||
Feature: Server-side preference management for favorites, read status, etc.
|
||||
UI: More compact hop labelling
|
||||
* Bugfix: Misc. race conditions and websocket handling
|
||||
* Bugfix: Reduce fetching cadence by loading all contact data at start to prevent fetches on advertise-driven update
|
||||
Bugfix: Misc. race conditions and websocket handling
|
||||
Bugfix: Reduce fetching cadence by loading all contact data at start to prevent fetches on advertise-driven update
|
||||
|
||||
## [1.4.0] - 2026-01-18
|
||||
|
||||
UI: Improve button layout for room searcher
|
||||
UI: Improve favicon coloring
|
||||
UI: Improve status bar button layout on small screen
|
||||
* Feature: Show multi-path hop display with distance estimates
|
||||
* Feature: Search rooms and contacts by key, not just name
|
||||
* Bugfix: Historical DM decryption now works as expected
|
||||
* Bugfix: Don't double-set active conversation after addition; wait for backend room name normalization
|
||||
Feature: Show multi-path hop display with distance estimates
|
||||
Feature: Search rooms and contacts by key, not just name
|
||||
Bugfix: Historical DM decryption now works as expected
|
||||
Bugfix: Don't double-set active conversation after addition; wait for backend room name normalization
|
||||
|
||||
## [1.3.1] - 2026-01-17
|
||||
|
||||
UI: Rework restart handling
|
||||
* Feature: Add `dutycyle_start` command to logged-in repeater session to start five min duty cycle tracking
|
||||
Feature: Add `dutycyle_start` command to logged-in repeater session to start five min duty cycle tracking
|
||||
Bug: Improve error message rendering from server-side errors
|
||||
UI: Remove octothorpe from channel listing
|
||||
|
||||
## [1.3.0] - 2026-01-17
|
||||
|
||||
* Feature: Rework database schema to drop unnecessary columns and dedupe payloads at the DB level
|
||||
* Feature: Massive frontend settings overhaul. It ain't gorgeous but it's easier to navigate.
|
||||
* Feature: Drop repeater login wait time; vestigial from debugging a different issue
|
||||
Feature: Rework database schema to drop unnecessary columns and dedupe payloads at the DB level
|
||||
Feature: Massive frontend settings overhaul. It ain't gorgeous but it's easier to navigate.
|
||||
Feature: Drop repeater login wait time; vestigial from debugging a different issue
|
||||
|
||||
## [1.2.1] - 2026-01-17
|
||||
|
||||
@@ -481,27 +462,27 @@ Update: Update meshcore-hashtag-cracker to include sender-identification correct
|
||||
|
||||
## [1.2.0] - 2026-01-16
|
||||
|
||||
* Feature: Add favorites
|
||||
Feature: Add favorites
|
||||
|
||||
## [1.1.0] - 2026-01-14
|
||||
|
||||
* Bugfix: Use actual pathing data from advertisements, not just always flood (oops)
|
||||
* Bugfix: Autosync radio clock periodically to prevent drift (would show up most commonly as issues with repeater comms)
|
||||
Bugfix: Use actual pathing data from advertisements, not just always flood (oops)
|
||||
Bugfix: Autosync radio clock periodically to prevent drift (would show up most commonly as issues with repeater comms)
|
||||
|
||||
## [1.0.3] - 2026-01-13
|
||||
|
||||
* Bugfix: Add missing test management packages
|
||||
* Improvement: Drop unnecessary repeater timeouts, and retain timeout for login only -- repeater ops are faster AND more reliable!
|
||||
Bugfix: Add missing test management packages
|
||||
Improvement: Drop unnecessary repeater timeouts, and retain timeout for login only -- repeater ops are faster AND more reliable!
|
||||
|
||||
## [1.0.2] - 2026-01-13
|
||||
|
||||
* Improvement: Add delays between router ops to prevent traffic collisions
|
||||
Improvement: Add delays between router ops to prevent traffic collisions
|
||||
|
||||
## [1.0.1] - 2026-01-13
|
||||
|
||||
* Bugixes: Cleaner DB shutdown, radio reconnect contention, packet dedupe garbage removal
|
||||
Bugixes: Cleaner DB shutdown, radio reconnect contention, packet dedupe garbage removal
|
||||
|
||||
## [1.0.0] - 2026-01-13
|
||||
|
||||
* Initial full release!
|
||||
Initial full release!
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "remoteterm-meshcore-frontend",
|
||||
"private": true,
|
||||
"version": "3.6.7",
|
||||
"version": "3.6.3",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -860,7 +860,7 @@ export function Sidebar({
|
||||
onClick={onNewMessage}
|
||||
title="Add channel or contact"
|
||||
aria-label="Add channel or contact"
|
||||
className="h-8 w-full justify-start gap-2 border-primary/20 bg-primary/5 px-3 text-[13px] text-primary hover:bg-primary/10 hover:text-primary"
|
||||
className="h-8 w-full justify-start gap-2 px-3 text-[13px]"
|
||||
>
|
||||
<SquarePen className="h-4 w-4" />
|
||||
<span>Add Channel/Contact</span>
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "remoteterm-meshcore"
|
||||
version = "3.6.7"
|
||||
version = "3.6.3"
|
||||
description = "RemoteTerm - Web interface for MeshCore radio mesh networks"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
# shellcheck source=scripts/build/release_common.sh
|
||||
source "$SCRIPT_DIR/release_common.sh"
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: scripts/build/create_github_release.sh --version X.Y.Z --asset PATH [options]
|
||||
|
||||
Options:
|
||||
--version VERSION Release version / tag (required)
|
||||
--asset PATH Asset to attach; may be specified multiple times
|
||||
--notes-file PATH Markdown release notes file; defaults to CHANGELOG section
|
||||
--full-git-hash HASH Commit to tag if the tag does not already exist locally
|
||||
--title TITLE Release title (default: version)
|
||||
--help Show this message
|
||||
EOF
|
||||
}
|
||||
|
||||
VERSION=""
|
||||
TITLE=""
|
||||
NOTES_FILE=""
|
||||
FULL_GIT_HASH=""
|
||||
ASSETS=()
|
||||
TEMP_NOTES_FILE=""
|
||||
|
||||
cleanup() {
|
||||
if [ -n "$TEMP_NOTES_FILE" ] && [ -f "$TEMP_NOTES_FILE" ]; then
|
||||
rm -f "$TEMP_NOTES_FILE"
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--version)
|
||||
VERSION="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--asset)
|
||||
ASSETS+=("${2:-}")
|
||||
shift 2
|
||||
;;
|
||||
--notes-file)
|
||||
NOTES_FILE="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--full-git-hash)
|
||||
FULL_GIT_HASH="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--title)
|
||||
TITLE="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
usage >&2
|
||||
release_die "Unknown argument: $1"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
[ -n "$VERSION" ] || release_die "--version is required"
|
||||
[ "${#ASSETS[@]}" -gt 0 ] || release_die "At least one --asset is required"
|
||||
release_validate_version "$VERSION"
|
||||
|
||||
REPO_ROOT="$(release_repo_root)"
|
||||
TITLE="${TITLE:-$VERSION}"
|
||||
FULL_GIT_HASH="${FULL_GIT_HASH:-$(release_resolve_full_hash "$REPO_ROOT")}"
|
||||
|
||||
for asset in "${ASSETS[@]}"; do
|
||||
[ -f "$asset" ] || release_die "Asset not found: $asset"
|
||||
done
|
||||
|
||||
if [ -z "$NOTES_FILE" ]; then
|
||||
TEMP_NOTES_FILE="$(mktemp)"
|
||||
release_extract_changelog_section "$REPO_ROOT" "$VERSION" "$TEMP_NOTES_FILE"
|
||||
NOTES_FILE="$TEMP_NOTES_FILE"
|
||||
fi
|
||||
|
||||
[ -f "$NOTES_FILE" ] || release_die "Notes file not found: $NOTES_FILE"
|
||||
|
||||
if ! git -C "$REPO_ROOT" rev-parse -q --verify "refs/tags/$VERSION" >/dev/null; then
|
||||
echo "[create_github_release] Creating local tag $VERSION at $FULL_GIT_HASH..." >&2
|
||||
git -C "$REPO_ROOT" tag -a "$VERSION" "$FULL_GIT_HASH" -F "$NOTES_FILE"
|
||||
fi
|
||||
|
||||
if ! git -C "$REPO_ROOT" ls-remote --exit-code --tags origin "refs/tags/$VERSION" >/dev/null 2>&1; then
|
||||
echo "[create_github_release] Pushing tag $VERSION to origin..." >&2
|
||||
git -C "$REPO_ROOT" push origin "$VERSION"
|
||||
fi
|
||||
|
||||
if gh release view "$VERSION" >/dev/null 2>&1; then
|
||||
echo "[create_github_release] Updating existing GitHub release $VERSION..." >&2
|
||||
gh release upload "$VERSION" "${ASSETS[@]}" --clobber
|
||||
gh release edit "$VERSION" --title "$TITLE" --notes-file "$NOTES_FILE"
|
||||
else
|
||||
echo "[create_github_release] Creating GitHub release $VERSION..." >&2
|
||||
gh release create "$VERSION" "${ASSETS[@]}" --title "$TITLE" --notes-file "$NOTES_FILE" --verify-tag
|
||||
fi
|
||||
@@ -1,54 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
# shellcheck source=scripts/build/release_common.sh
|
||||
source "$SCRIPT_DIR/release_common.sh"
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: scripts/build/extract_release_notes.sh --version X.Y.Z --output PATH
|
||||
|
||||
Options:
|
||||
--version VERSION Release version to extract from CHANGELOG.md
|
||||
--output PATH Output markdown file path
|
||||
--changelog PATH Override changelog path
|
||||
--help Show this message
|
||||
EOF
|
||||
}
|
||||
|
||||
VERSION=""
|
||||
OUTPUT_FILE=""
|
||||
CHANGELOG_PATH=""
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--version)
|
||||
VERSION="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--output)
|
||||
OUTPUT_FILE="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--changelog)
|
||||
CHANGELOG_PATH="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
usage >&2
|
||||
release_die "Unknown argument: $1"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
[ -n "$VERSION" ] || release_die "--version is required"
|
||||
[ -n "$OUTPUT_FILE" ] || release_die "--output is required"
|
||||
release_validate_version "$VERSION"
|
||||
|
||||
REPO_ROOT="$(release_repo_root)"
|
||||
release_extract_changelog_section "$REPO_ROOT" "$VERSION" "$OUTPUT_FILE" "${CHANGELOG_PATH:-$REPO_ROOT/CHANGELOG.md}"
|
||||
@@ -1,111 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
# shellcheck source=scripts/build/release_common.sh
|
||||
source "$SCRIPT_DIR/release_common.sh"
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: scripts/build/package_release_artifact.sh --version X.Y.Z [options]
|
||||
|
||||
Options:
|
||||
--version VERSION Release version (required)
|
||||
--git-hash HASH Short git hash to embed in artifact naming
|
||||
--full-git-hash HASH Full git hash to archive
|
||||
--output PATH Output zip path
|
||||
--bundle-name NAME Bundle folder name inside the zip
|
||||
--skip-prebuilt-build Reuse existing frontend/prebuilt instead of rebuilding it
|
||||
--help Show this message
|
||||
EOF
|
||||
}
|
||||
|
||||
VERSION=""
|
||||
GIT_HASH=""
|
||||
FULL_GIT_HASH=""
|
||||
OUTPUT_PATH=""
|
||||
BUNDLE_NAME="Remote-Terminal-for-MeshCore"
|
||||
SKIP_PREBUILT_BUILD=0
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--version)
|
||||
VERSION="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--git-hash)
|
||||
GIT_HASH="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--full-git-hash)
|
||||
FULL_GIT_HASH="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--output)
|
||||
OUTPUT_PATH="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--bundle-name)
|
||||
BUNDLE_NAME="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--skip-prebuilt-build)
|
||||
SKIP_PREBUILT_BUILD=1
|
||||
shift
|
||||
;;
|
||||
--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
usage >&2
|
||||
release_die "Unknown argument: $1"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
[ -n "$VERSION" ] || release_die "--version is required"
|
||||
release_validate_version "$VERSION"
|
||||
|
||||
REPO_ROOT="$(release_repo_root)"
|
||||
FULL_GIT_HASH="${FULL_GIT_HASH:-$(release_resolve_full_hash "$REPO_ROOT")}"
|
||||
GIT_HASH="${GIT_HASH:-$(release_resolve_short_hash "$REPO_ROOT" "$FULL_GIT_HASH")}"
|
||||
OUTPUT_PATH="${OUTPUT_PATH:-$REPO_ROOT/remoteterm-prebuilt-frontend-v${VERSION}-${GIT_HASH}.zip}"
|
||||
|
||||
WORK_DIR="$(mktemp -d)"
|
||||
BUNDLE_DIR="$WORK_DIR/$BUNDLE_NAME"
|
||||
|
||||
cleanup() {
|
||||
rm -rf "$WORK_DIR"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
if [ "$SKIP_PREBUILT_BUILD" -eq 0 ]; then
|
||||
echo "[package_release_artifact] Building frontend prebuilt bundle..." >&2
|
||||
(
|
||||
cd "$REPO_ROOT/frontend"
|
||||
npm run packaged-build
|
||||
)
|
||||
fi
|
||||
|
||||
[ -d "$REPO_ROOT/frontend/prebuilt" ] || release_die "frontend/prebuilt is missing; run with frontend built or omit --skip-prebuilt-build"
|
||||
|
||||
mkdir -p "$BUNDLE_DIR/frontend"
|
||||
git -C "$REPO_ROOT" archive "$FULL_GIT_HASH" | tar -x -C "$BUNDLE_DIR"
|
||||
cp -R "$REPO_ROOT/frontend/prebuilt" "$BUNDLE_DIR/frontend/prebuilt"
|
||||
|
||||
cat > "$BUNDLE_DIR/build_info.json" <<EOF
|
||||
{
|
||||
"version": "$VERSION",
|
||||
"commit_hash": "$GIT_HASH",
|
||||
"build_source": "prebuilt-release"
|
||||
}
|
||||
EOF
|
||||
|
||||
rm -f "$OUTPUT_PATH"
|
||||
(
|
||||
cd "$WORK_DIR"
|
||||
zip -qr "$OUTPUT_PATH" "$BUNDLE_NAME"
|
||||
)
|
||||
|
||||
echo "$OUTPUT_PATH"
|
||||
+155
-93
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
@@ -10,63 +10,95 @@ NC='\033[0m' # No Color
|
||||
REPO_ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||
cd "$REPO_ROOT"
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
# shellcheck source=scripts/build/release_common.sh
|
||||
source "$SCRIPT_DIR/release_common.sh"
|
||||
|
||||
DOCKER_IMAGE="docker.io/jkingsman/remoteterm-meshcore"
|
||||
RELEASE_WORK_DIR=""
|
||||
RELEASE_BUNDLE_DIR_NAME="Remote-Terminal-for-MeshCore"
|
||||
RELEASE_ASSET=""
|
||||
DOCKER_IMAGE="jkingsman/remoteterm-meshcore"
|
||||
DOCKER_PLATFORMS="linux/amd64,linux/arm64"
|
||||
VERSION=""
|
||||
NOTES_FILE=""
|
||||
SKIP_QUALITY=0
|
||||
RELEASE_ASSET_PATH=""
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: scripts/build/publish.sh [options]
|
||||
|
||||
Options:
|
||||
--version VERSION Release version; prompts if omitted
|
||||
--notes-file PATH File containing changelog entry lines; prompts if omitted
|
||||
--skip-quality Skip ./scripts/quality/all_quality.sh
|
||||
--help Show this message
|
||||
EOF
|
||||
cleanup_release_build_artifacts() {
|
||||
if [ -d "$REPO_ROOT/frontend/prebuilt" ]; then
|
||||
rm -rf "$REPO_ROOT/frontend/prebuilt"
|
||||
fi
|
||||
if [ -n "$RELEASE_WORK_DIR" ] && [ -d "$RELEASE_WORK_DIR" ]; then
|
||||
rm -rf "$RELEASE_WORK_DIR"
|
||||
fi
|
||||
if [ -n "$RELEASE_ASSET" ] && [ -f "$REPO_ROOT/$RELEASE_ASSET" ]; then
|
||||
rm -f "$REPO_ROOT/$RELEASE_ASSET"
|
||||
fi
|
||||
}
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--version)
|
||||
VERSION="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--notes-file)
|
||||
NOTES_FILE="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--skip-quality)
|
||||
SKIP_QUALITY=1
|
||||
shift
|
||||
;;
|
||||
--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
usage >&2
|
||||
release_die "Unknown argument: $1"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
trap cleanup_release_build_artifacts EXIT
|
||||
|
||||
ensure_buildx_builder() {
|
||||
if ! docker buildx version >/dev/null 2>&1; then
|
||||
echo -e "${RED}Error: docker buildx is required for multi-arch Docker builds.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local current_builder
|
||||
current_builder="$(docker buildx inspect --format '{{ .Name }}' 2>/dev/null || true)"
|
||||
|
||||
if [ -n "$current_builder" ]; then
|
||||
docker buildx inspect --bootstrap >/dev/null
|
||||
return
|
||||
fi
|
||||
|
||||
if docker buildx inspect remoteterm-multiarch >/dev/null 2>&1; then
|
||||
docker buildx use remoteterm-multiarch >/dev/null
|
||||
else
|
||||
docker buildx create --name remoteterm-multiarch --use >/dev/null
|
||||
fi
|
||||
docker buildx inspect --bootstrap >/dev/null
|
||||
}
|
||||
|
||||
echo -e "${YELLOW}=== RemoteTerm for MeshCore Publish Script ===${NC}"
|
||||
echo
|
||||
|
||||
if [ "$SKIP_QUALITY" -eq 0 ]; then
|
||||
echo -e "${YELLOW}Running repo quality gate...${NC}"
|
||||
./scripts/quality/all_quality.sh
|
||||
echo -e "${GREEN}Quality gate passed!${NC}"
|
||||
echo
|
||||
fi
|
||||
# Run backend linting and type checking
|
||||
echo -e "${YELLOW}Running backend lint (Ruff)...${NC}"
|
||||
uv run ruff check app/ tests/ --fix
|
||||
uv run ruff format app/ tests/
|
||||
# validate
|
||||
uv run ruff check app/ tests/
|
||||
uv run ruff format --check app/ tests/
|
||||
echo -e "${GREEN}Backend lint passed!${NC}"
|
||||
echo
|
||||
|
||||
echo -e "${YELLOW}Running backend type check (Pyright)...${NC}"
|
||||
uv run pyright app/
|
||||
echo -e "${GREEN}Backend type check passed!${NC}"
|
||||
echo
|
||||
|
||||
# Run backend tests
|
||||
echo -e "${YELLOW}Running backend tests...${NC}"
|
||||
PYTHONPATH=. uv run pytest tests/ -v
|
||||
echo -e "${GREEN}Backend tests passed!${NC}"
|
||||
echo
|
||||
|
||||
# Run frontend linting and formatting check
|
||||
echo -e "${YELLOW}Running frontend lint (ESLint)...${NC}"
|
||||
cd "$REPO_ROOT/frontend"
|
||||
npm run lint
|
||||
echo -e "${GREEN}Frontend lint passed!${NC}"
|
||||
echo
|
||||
|
||||
echo -e "${YELLOW}Checking frontend formatting (Prettier)...${NC}"
|
||||
npm run format:check
|
||||
echo -e "${GREEN}Frontend formatting OK!${NC}"
|
||||
echo
|
||||
|
||||
# Run frontend tests and build
|
||||
echo -e "${YELLOW}Running frontend tests...${NC}"
|
||||
npm run test:run
|
||||
echo -e "${GREEN}Frontend tests passed!${NC}"
|
||||
echo
|
||||
|
||||
echo -e "${YELLOW}Building frontend...${NC}"
|
||||
npm run build
|
||||
echo -e "${GREEN}Frontend build complete!${NC}"
|
||||
cd "$REPO_ROOT"
|
||||
echo
|
||||
|
||||
echo -e "${YELLOW}Regenerating LICENSES.md...${NC}"
|
||||
bash scripts/build/collect_licenses.sh LICENSES.md
|
||||
@@ -81,11 +113,13 @@ echo -n " package.json: "
|
||||
grep '"version"' frontend/package.json | head -1 | sed 's/.*"version": "\(.*\)".*/\1/'
|
||||
echo
|
||||
|
||||
if [ -z "$VERSION" ]; then
|
||||
read -r -p "Enter new version (e.g., 1.2.3): " VERSION
|
||||
read -r -p "Enter new version (e.g., 1.2.3): " VERSION
|
||||
VERSION="$(printf '%s' "$VERSION" | tr -d '\r' | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')"
|
||||
|
||||
if [[ ! $VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
echo -e "${RED}Error: Version must be in format X.Y.Z${NC}"
|
||||
exit 1
|
||||
fi
|
||||
VERSION="$(release_trim "$VERSION")"
|
||||
release_validate_version "$VERSION"
|
||||
|
||||
# Update pyproject.toml
|
||||
echo -e "${YELLOW}Updating pyproject.toml...${NC}"
|
||||
@@ -103,28 +137,11 @@ echo -e "${GREEN}Version updated to $VERSION${NC}"
|
||||
echo
|
||||
|
||||
# Prompt for changelog entry
|
||||
RAW_CHANGELOG_INPUT_FILE="$(mktemp)"
|
||||
FORMATTED_CHANGELOG_INPUT_FILE="$(mktemp)"
|
||||
cleanup() {
|
||||
rm -f "$RAW_CHANGELOG_INPUT_FILE" "$FORMATTED_CHANGELOG_INPUT_FILE"
|
||||
rm -rf "${REPO_ROOT:?}/frontend/prebuilt"
|
||||
if [ -n "$RELEASE_ASSET_PATH" ] && [ -f "$RELEASE_ASSET_PATH" ]; then
|
||||
rm -f "$RELEASE_ASSET_PATH"
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
echo -e "${YELLOW}Enter changelog entry for version $VERSION${NC}"
|
||||
echo -e "${YELLOW}(Enter your changes, then press Ctrl+D when done):${NC}"
|
||||
echo
|
||||
|
||||
if [ -n "$NOTES_FILE" ]; then
|
||||
cp "$NOTES_FILE" "$RAW_CHANGELOG_INPUT_FILE"
|
||||
else
|
||||
echo -e "${YELLOW}Enter changelog entry for version $VERSION${NC}"
|
||||
echo -e "${YELLOW}(Enter your changes, then press Ctrl+D when done):${NC}"
|
||||
echo
|
||||
cat > "$RAW_CHANGELOG_INPUT_FILE"
|
||||
fi
|
||||
|
||||
release_format_markdown_list "$RAW_CHANGELOG_INPUT_FILE" "$FORMATTED_CHANGELOG_INPUT_FILE"
|
||||
[ -s "$FORMATTED_CHANGELOG_INPUT_FILE" ] || release_die "Changelog entry cannot be empty"
|
||||
CHANGELOG_ENTRY=$(cat)
|
||||
|
||||
# Create changelog entry with date
|
||||
DATE=$(date +%Y-%m-%d)
|
||||
@@ -140,7 +157,7 @@ if [ -f CHANGELOG.md ]; then
|
||||
echo
|
||||
echo "$CHANGELOG_HEADER"
|
||||
echo
|
||||
cat "$FORMATTED_CHANGELOG_INPUT_FILE"
|
||||
echo "$CHANGELOG_ENTRY"
|
||||
echo
|
||||
tail -n +2 CHANGELOG.md
|
||||
} > CHANGELOG.md.tmp
|
||||
@@ -150,7 +167,7 @@ if [ -f CHANGELOG.md ]; then
|
||||
{
|
||||
echo "$CHANGELOG_HEADER"
|
||||
echo
|
||||
cat "$FORMATTED_CHANGELOG_INPUT_FILE"
|
||||
echo "$CHANGELOG_ENTRY"
|
||||
echo
|
||||
cat CHANGELOG.md
|
||||
} > CHANGELOG.md.tmp
|
||||
@@ -163,7 +180,7 @@ else
|
||||
echo
|
||||
echo "$CHANGELOG_HEADER"
|
||||
echo
|
||||
cat "$FORMATTED_CHANGELOG_INPUT_FILE"
|
||||
echo "$CHANGELOG_ENTRY"
|
||||
} > CHANGELOG.md
|
||||
fi
|
||||
|
||||
@@ -183,33 +200,78 @@ echo
|
||||
GIT_HASH=$(git rev-parse --short HEAD)
|
||||
FULL_GIT_HASH=$(git rev-parse HEAD)
|
||||
RELEASE_ASSET="remoteterm-prebuilt-frontend-v${VERSION}-${GIT_HASH}.zip"
|
||||
RELEASE_ASSET_PATH="$REPO_ROOT/$RELEASE_ASSET"
|
||||
|
||||
echo -e "${YELLOW}Building packaged frontend artifact...${NC}"
|
||||
scripts/build/package_release_artifact.sh \
|
||||
--version "$VERSION" \
|
||||
--git-hash "$GIT_HASH" \
|
||||
--full-git-hash "$FULL_GIT_HASH" \
|
||||
--output "$RELEASE_ASSET_PATH"
|
||||
cd "$REPO_ROOT/frontend"
|
||||
npm run packaged-build
|
||||
cd "$REPO_ROOT"
|
||||
|
||||
RELEASE_WORK_DIR=$(mktemp -d)
|
||||
RELEASE_BUNDLE_DIR="$RELEASE_WORK_DIR/$RELEASE_BUNDLE_DIR_NAME"
|
||||
mkdir -p "$RELEASE_BUNDLE_DIR"
|
||||
git archive "$FULL_GIT_HASH" | tar -x -C "$RELEASE_BUNDLE_DIR"
|
||||
mkdir -p "$RELEASE_BUNDLE_DIR/frontend"
|
||||
cp -R "$REPO_ROOT/frontend/prebuilt" "$RELEASE_BUNDLE_DIR/frontend/prebuilt"
|
||||
cat > "$RELEASE_BUNDLE_DIR/build_info.json" <<EOF
|
||||
{
|
||||
"version": "$VERSION",
|
||||
"commit_hash": "$GIT_HASH",
|
||||
"build_source": "prebuilt-release"
|
||||
}
|
||||
EOF
|
||||
rm -f "$REPO_ROOT/$RELEASE_ASSET"
|
||||
(
|
||||
cd "$RELEASE_WORK_DIR"
|
||||
zip -qr "$REPO_ROOT/$RELEASE_ASSET" "$(basename "$RELEASE_BUNDLE_DIR")"
|
||||
)
|
||||
echo -e "${GREEN}Packaged release artifact created: $RELEASE_ASSET${NC}"
|
||||
echo
|
||||
|
||||
# Build and push multi-arch docker image
|
||||
echo -e "${YELLOW}Building and pushing multi-arch Docker image...${NC}"
|
||||
scripts/build/push_docker_multiarch.sh \
|
||||
--version "$VERSION" \
|
||||
--git-hash "$GIT_HASH" \
|
||||
--image "$DOCKER_IMAGE" \
|
||||
--platforms "$DOCKER_PLATFORMS"
|
||||
ensure_buildx_builder
|
||||
docker buildx build \
|
||||
--platform "$DOCKER_PLATFORMS" \
|
||||
--build-arg COMMIT_HASH="$GIT_HASH" \
|
||||
-t "$DOCKER_IMAGE:latest" \
|
||||
-t "$DOCKER_IMAGE:$VERSION" \
|
||||
-t "$DOCKER_IMAGE:$GIT_HASH" \
|
||||
--push \
|
||||
.
|
||||
echo -e "${GREEN}Multi-arch Docker build + push complete!${NC}"
|
||||
echo
|
||||
|
||||
# Create GitHub release using the changelog notes for this version.
|
||||
echo -e "${YELLOW}Creating GitHub release...${NC}"
|
||||
scripts/build/create_github_release.sh \
|
||||
--version "$VERSION" \
|
||||
--full-git-hash "$FULL_GIT_HASH" \
|
||||
--asset "$RELEASE_ASSET_PATH"
|
||||
RELEASE_NOTES_FILE=$(mktemp)
|
||||
{
|
||||
echo "$CHANGELOG_HEADER"
|
||||
echo
|
||||
echo "$CHANGELOG_ENTRY"
|
||||
} > "$RELEASE_NOTES_FILE"
|
||||
|
||||
# Create and push the release tag first so GitHub release creation does not
|
||||
# depend on resolving a symbolic ref like HEAD on the remote side. Use the same
|
||||
# changelog-derived notes for the annotated tag message.
|
||||
if git rev-parse -q --verify "refs/tags/$VERSION" >/dev/null; then
|
||||
echo -e "${YELLOW}Tag $VERSION already exists locally; reusing it.${NC}"
|
||||
else
|
||||
git tag -a "$VERSION" "$FULL_GIT_HASH" -F "$RELEASE_NOTES_FILE"
|
||||
fi
|
||||
|
||||
if git ls-remote --exit-code --tags origin "refs/tags/$VERSION" >/dev/null 2>&1; then
|
||||
echo -e "${YELLOW}Tag $VERSION already exists on origin; not pushing it again.${NC}"
|
||||
else
|
||||
git push origin "$VERSION"
|
||||
fi
|
||||
|
||||
gh release create "$VERSION" \
|
||||
"$RELEASE_ASSET" \
|
||||
--title "$VERSION" \
|
||||
--notes-file "$RELEASE_NOTES_FILE" \
|
||||
--verify-tag
|
||||
|
||||
rm -f "$RELEASE_NOTES_FILE"
|
||||
echo -e "${GREEN}GitHub release created!${NC}"
|
||||
echo
|
||||
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
# shellcheck source=scripts/build/release_common.sh
|
||||
source "$SCRIPT_DIR/release_common.sh"
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: scripts/build/push_docker_multiarch.sh --version X.Y.Z [options]
|
||||
|
||||
Options:
|
||||
--version VERSION Release version (required)
|
||||
--git-hash HASH Short git hash to tag alongside the version
|
||||
--image IMAGE Docker image name (default: docker.io/jkingsman/remoteterm-meshcore)
|
||||
--platforms CSV Buildx platforms CSV (default: linux/amd64,linux/arm64)
|
||||
--help Show this message
|
||||
EOF
|
||||
}
|
||||
|
||||
VERSION=""
|
||||
GIT_HASH=""
|
||||
IMAGE="docker.io/jkingsman/remoteterm-meshcore"
|
||||
PLATFORMS="linux/amd64,linux/arm64"
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--version)
|
||||
VERSION="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--git-hash)
|
||||
GIT_HASH="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--image)
|
||||
IMAGE="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--platforms)
|
||||
PLATFORMS="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
usage >&2
|
||||
release_die "Unknown argument: $1"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
[ -n "$VERSION" ] || release_die "--version is required"
|
||||
release_validate_version "$VERSION"
|
||||
|
||||
REPO_ROOT="$(release_repo_root)"
|
||||
GIT_HASH="${GIT_HASH:-$(release_resolve_short_hash "$REPO_ROOT")}"
|
||||
|
||||
echo "[push_docker_multiarch] Ensuring docker buildx builder..." >&2
|
||||
release_ensure_buildx_builder
|
||||
|
||||
docker_buildx_args=(
|
||||
build
|
||||
--platform "$PLATFORMS"
|
||||
--build-arg "COMMIT_HASH=$GIT_HASH"
|
||||
-t "$IMAGE:latest"
|
||||
-t "$IMAGE:$VERSION"
|
||||
-t "$IMAGE:$GIT_HASH"
|
||||
--push
|
||||
.
|
||||
)
|
||||
|
||||
echo "[push_docker_multiarch] Building and pushing $IMAGE for $PLATFORMS..." >&2
|
||||
(
|
||||
cd "$REPO_ROOT"
|
||||
docker buildx "${docker_buildx_args[@]}"
|
||||
)
|
||||
@@ -1,93 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
release_repo_root() {
|
||||
(
|
||||
cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd
|
||||
)
|
||||
}
|
||||
|
||||
release_die() {
|
||||
echo "Error: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
release_trim() {
|
||||
printf '%s' "$1" | tr -d '\r' | sed 's/^[[:space:]]*//; s/[[:space:]]*$//'
|
||||
}
|
||||
|
||||
release_validate_version() {
|
||||
local version="$1"
|
||||
[[ $version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || release_die "Version must be in format X.Y.Z"
|
||||
}
|
||||
|
||||
release_resolve_full_hash() {
|
||||
local repo_root="$1"
|
||||
local ref="${2:-HEAD}"
|
||||
git -C "$repo_root" rev-parse "$ref"
|
||||
}
|
||||
|
||||
release_resolve_short_hash() {
|
||||
local repo_root="$1"
|
||||
local ref="${2:-HEAD}"
|
||||
git -C "$repo_root" rev-parse --short "$ref"
|
||||
}
|
||||
|
||||
release_format_markdown_list() {
|
||||
local input_file="$1"
|
||||
local output_file="$2"
|
||||
awk '
|
||||
/^[[:space:]]*$/ { next }
|
||||
{
|
||||
sub(/^[[:space:]]+/, "", $0)
|
||||
if ($0 ~ /^\* /) {
|
||||
print
|
||||
} else if ($0 ~ /^- /) {
|
||||
sub(/^- /, "* ", $0)
|
||||
print
|
||||
} else {
|
||||
print "* " $0
|
||||
}
|
||||
}
|
||||
' "$input_file" > "$output_file"
|
||||
}
|
||||
|
||||
release_extract_changelog_section() {
|
||||
local repo_root="$1"
|
||||
local version="$2"
|
||||
local output_file="$3"
|
||||
local changelog_path="${4:-$repo_root/CHANGELOG.md}"
|
||||
|
||||
# Use index() for literal matching so dots in version strings are not
|
||||
# treated as regex wildcards (e.g. 3.6.5 won't match 31615).
|
||||
awk -v ver="$version" '
|
||||
BEGIN { header = "## [" ver "]" }
|
||||
index($0, header) == 1 { capture = 1; print; next }
|
||||
capture && /^## \[/ { exit }
|
||||
capture { print }
|
||||
' "$changelog_path" > "$output_file"
|
||||
|
||||
[ -s "$output_file" ] || release_die "Could not find CHANGELOG entry for version $version"
|
||||
}
|
||||
|
||||
release_ensure_buildx_builder() {
|
||||
if ! docker buildx version >/dev/null 2>&1; then
|
||||
release_die "docker buildx is required for multi-arch Docker builds"
|
||||
fi
|
||||
|
||||
# Multi-platform builds require the docker-container driver. The default
|
||||
# builder uses the "docker" driver which only supports the host platform.
|
||||
# Check the current builder's driver first; only create a new one if needed.
|
||||
local current_driver
|
||||
current_driver="$(docker buildx inspect --format '{{ .Driver }}' 2>/dev/null || true)"
|
||||
if [ "$current_driver" = "docker-container" ]; then
|
||||
docker buildx inspect --bootstrap >/dev/null
|
||||
return
|
||||
fi
|
||||
|
||||
if docker buildx inspect remoteterm-multiarch >/dev/null 2>&1; then
|
||||
docker buildx use remoteterm-multiarch >/dev/null
|
||||
else
|
||||
docker buildx create --name remoteterm-multiarch --use >/dev/null
|
||||
fi
|
||||
docker buildx inspect --bootstrap >/dev/null
|
||||
}
|
||||
@@ -22,12 +22,15 @@ REPO_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||
COMPOSE_FILE="$REPO_DIR/docker-compose.yml"
|
||||
EXAMPLE_FILE="$REPO_DIR/docker-compose.example.yml"
|
||||
SNAKEOIL_CERT_DIR="$REPO_DIR/.docker-certs"
|
||||
NGINX_CONFIG_DIR="$REPO_DIR/.docker-nginx"
|
||||
NGINX_CONFIG_BASENAME="remoteterm.conf"
|
||||
NGINX_CONFIG_HOST_PATH="$NGINX_CONFIG_DIR/$NGINX_CONFIG_BASENAME"
|
||||
SNAKEOIL_CERT_BASENAME="remoteterm-snakeoil.crt"
|
||||
SNAKEOIL_KEY_BASENAME="remoteterm-snakeoil.key"
|
||||
SNAKEOIL_CERT_HOST_PATH="$SNAKEOIL_CERT_DIR/$SNAKEOIL_CERT_BASENAME"
|
||||
SNAKEOIL_KEY_HOST_PATH="$SNAKEOIL_CERT_DIR/$SNAKEOIL_KEY_BASENAME"
|
||||
SNAKEOIL_CERT_CONTAINER_PATH="/app/certs/$SNAKEOIL_CERT_BASENAME"
|
||||
SNAKEOIL_KEY_CONTAINER_PATH="/app/certs/$SNAKEOIL_KEY_BASENAME"
|
||||
SNAKEOIL_CERT_CONTAINER_PATH="/etc/nginx/certs/$SNAKEOIL_CERT_BASENAME"
|
||||
SNAKEOIL_KEY_CONTAINER_PATH="/etc/nginx/certs/$SNAKEOIL_KEY_BASENAME"
|
||||
|
||||
IMAGE_MODE="image"
|
||||
TRANSPORT_MODE="serial"
|
||||
@@ -211,6 +214,49 @@ EOF
|
||||
chmod 644 "$SNAKEOIL_CERT_HOST_PATH"
|
||||
}
|
||||
|
||||
generate_nginx_tls_config() {
|
||||
mkdir -p "$NGINX_CONFIG_DIR"
|
||||
|
||||
cat >"$NGINX_CONFIG_HOST_PATH" <<EOF
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
return 308 https://\$host:8000\$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name _;
|
||||
|
||||
ssl_certificate $SNAKEOIL_CERT_CONTAINER_PATH;
|
||||
ssl_certificate_key $SNAKEOIL_KEY_CONTAINER_PATH;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_timeout 10m;
|
||||
|
||||
location /api/ws {
|
||||
proxy_pass http://remoteterm:8000/api/ws;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade \$http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Forwarded-Host \$host;
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
proxy_set_header X-Forwarded-Port 8000;
|
||||
}
|
||||
|
||||
location / {
|
||||
proxy_pass http://remoteterm:8000;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Forwarded-Host \$host;
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
proxy_set_header X-Forwarded-Port 8000;
|
||||
proxy_read_timeout 300s;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
echo -e "${BOLD}=== RemoteTerm for MeshCore — Docker Setup ===${NC}"
|
||||
echo
|
||||
echo -e " Repo directory : ${CYAN}${REPO_DIR}${NC}"
|
||||
@@ -400,7 +446,9 @@ LOCAL_ACCESS_IP="$(detect_primary_local_ip)"
|
||||
if [[ "$ENABLE_SNAKEOIL_TLS" =~ ^[Yy]$ ]]; then
|
||||
ensure_snakeoil_requirements
|
||||
generate_snakeoil_certificate "$LOCAL_ACCESS_IP"
|
||||
generate_nginx_tls_config
|
||||
echo -e "${GREEN}Generated snakeoil TLS certificate in ${SNAKEOIL_CERT_DIR}.${NC}"
|
||||
echo -e "${GREEN}Generated nginx TLS proxy config in ${NGINX_CONFIG_DIR}.${NC}"
|
||||
echo -e "${YELLOW}Browsers will show an untrusted/self-signed certificate warning.${NC}"
|
||||
else
|
||||
echo -e "${GREEN}Skipping snakeoil TLS generation. The container will serve plain HTTP.${NC}"
|
||||
@@ -441,32 +489,19 @@ mkdir -p "$REPO_DIR/data"
|
||||
if [[ "$RUN_AS_HOST_USER" =~ ^[Yy]$ ]]; then
|
||||
echo " user: \"$(id -u):$(id -g)\""
|
||||
fi
|
||||
echo " ports:"
|
||||
echo " - \"8000:8000\""
|
||||
if [[ "$ENABLE_SNAKEOIL_TLS" =~ ^[Yy]$ ]]; then
|
||||
echo " expose:"
|
||||
echo " - \"8000\""
|
||||
else
|
||||
echo " ports:"
|
||||
echo " - \"8000:8000\""
|
||||
fi
|
||||
echo " volumes:"
|
||||
echo " - ./data:/app/data"
|
||||
if [[ "$ENABLE_SNAKEOIL_TLS" =~ ^[Yy]$ ]]; then
|
||||
echo " - ./.docker-certs:/app/certs:ro"
|
||||
fi
|
||||
if [ "$TRANSPORT_MODE" = "serial" ]; then
|
||||
echo " devices:"
|
||||
echo " - ${SERIAL_COMPOSE_HOST_PATH}:${SERIAL_CONTAINER_PATH}"
|
||||
fi
|
||||
if [[ "$ENABLE_SNAKEOIL_TLS" =~ ^[Yy]$ ]]; then
|
||||
echo " command:"
|
||||
echo " - uv"
|
||||
echo " - run"
|
||||
echo " - uvicorn"
|
||||
echo " - app.main:app"
|
||||
echo " - --host"
|
||||
echo " - 0.0.0.0"
|
||||
echo " - --port"
|
||||
echo " - \"8000\""
|
||||
echo " - --ssl-keyfile"
|
||||
echo " - $SNAKEOIL_KEY_CONTAINER_PATH"
|
||||
echo " - --ssl-certfile"
|
||||
echo " - $SNAKEOIL_CERT_CONTAINER_PATH"
|
||||
fi
|
||||
echo " environment:"
|
||||
echo " MESHCORE_DATABASE_PATH: $(yaml_quote "data/meshcore.db")"
|
||||
if [ "$TRANSPORT_MODE" = "serial" ]; then
|
||||
@@ -486,6 +521,19 @@ mkdir -p "$REPO_DIR/data"
|
||||
echo " MESHCORE_BASIC_AUTH_PASSWORD: $(yaml_quote "$AUTH_PASSWORD")"
|
||||
fi
|
||||
echo " restart: unless-stopped"
|
||||
if [[ "$ENABLE_SNAKEOIL_TLS" =~ ^[Yy]$ ]]; then
|
||||
echo " nginx:"
|
||||
echo " image: nginx:alpine"
|
||||
echo " depends_on:"
|
||||
echo " - remoteterm"
|
||||
echo " ports:"
|
||||
echo " - \"80:80\""
|
||||
echo " - \"8000:443\""
|
||||
echo " volumes:"
|
||||
echo " - ./.docker-certs:/etc/nginx/certs:ro"
|
||||
echo " - ./.docker-nginx/$NGINX_CONFIG_BASENAME:/etc/nginx/conf.d/default.conf:ro"
|
||||
echo " restart: unless-stopped"
|
||||
fi
|
||||
} >"$COMPOSE_FILE"
|
||||
|
||||
echo -e "${GREEN}Generated ${COMPOSE_FILE}.${NC}"
|
||||
@@ -504,6 +552,11 @@ echo " sudo docker compose pull && sudo docker compose up -d # upgrade to the
|
||||
echo
|
||||
echo -e "${YELLOW}Note:${NC} serial passthrough generally needs ${BOLD}rootful Docker${NC}."
|
||||
echo "If Docker is running rootless on this host, serial-device mappings may fail even with a valid compose file."
|
||||
if [[ "$ENABLE_SNAKEOIL_TLS" =~ ^[Yy]$ ]]; then
|
||||
echo
|
||||
echo -e "${GREEN}HTTPS will be handled by an nginx sidecar.${NC}"
|
||||
echo "Host port 80 will redirect to HTTPS on port 8000."
|
||||
fi
|
||||
if [ "$TRANSPORT_MODE" = "ble" ] || [ "$BLE_MANUAL_WARNING" = true ]; then
|
||||
echo
|
||||
echo -e "${RED}BLE requires more than the generated env vars.${NC}"
|
||||
@@ -519,6 +572,7 @@ echo -e "${PURPLE}└───────────────────
|
||||
if [[ "$ENABLE_SNAKEOIL_TLS" =~ ^[Yy]$ ]]; then
|
||||
echo
|
||||
echo -e "After the container starts, open ${CYAN}https://${LOCAL_ACCESS_IP}:8000${NC}. Note that this address may change if you use DHCP/have not configured a static IP for your host via your router."
|
||||
echo -e "Plain HTTP on ${CYAN}http://${LOCAL_ACCESS_IP}${NC} will redirect there automatically."
|
||||
echo -e "${YELLOW}Expect an untrusted/self-signed certificate warning the first time you connect.${NC}"
|
||||
else
|
||||
echo
|
||||
|
||||
@@ -19,7 +19,7 @@ test.describe('Create contact flow', () => {
|
||||
await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible();
|
||||
|
||||
// Open new message modal
|
||||
await page.getByRole('button', { name: /add channel or contact/i }).click();
|
||||
await page.getByTitle('New Message').click();
|
||||
const dialog = page.getByRole('dialog');
|
||||
await expect(dialog).toBeVisible();
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ test.describe('Create hashtag channel flow', () => {
|
||||
await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible();
|
||||
|
||||
// Open new message modal
|
||||
await page.getByRole('button', { name: /add channel or contact/i }).click();
|
||||
await page.getByTitle('New Message').click();
|
||||
const dialog = page.getByRole('dialog');
|
||||
await expect(dialog).toBeVisible();
|
||||
|
||||
@@ -49,7 +49,7 @@ test.describe('Create hashtag channel flow', () => {
|
||||
await page.goto('/');
|
||||
await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible();
|
||||
|
||||
await page.getByRole('button', { name: /add channel or contact/i }).click();
|
||||
await page.getByTitle('New Message').click();
|
||||
const dialog = page.getByRole('dialog');
|
||||
await expect(dialog).toBeVisible();
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ test.describe('Historical packet decryption', () => {
|
||||
await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible();
|
||||
|
||||
// Open new message modal → Hashtag tab
|
||||
await page.getByRole('button', { name: /add channel or contact/i }).click();
|
||||
await page.getByTitle('New Message').click();
|
||||
const dialog = page.getByRole('dialog');
|
||||
await expect(dialog).toBeVisible();
|
||||
await dialog.getByRole('tab', { name: /Hashtag/i }).click();
|
||||
|
||||
Reference in New Issue
Block a user