Skip to content

Packages#3

Merged
rustyeddy merged 8 commits into
mainfrom
packages
Dec 22, 2025
Merged

Packages#3
rustyeddy merged 8 commits into
mainfrom
packages

Conversation

@rustyeddy
Copy link
Copy Markdown
Owner

@rustyeddy rustyeddy commented Nov 25, 2025

Have actions pipeline generate binaries for different OS/Architecture combos.

@rustyeddy rustyeddy self-assigned this Nov 25, 2025
@rustyeddy rustyeddy added the enhancement New feature or request label Nov 25, 2025
@rustyeddy rustyeddy marked this pull request as ready for review December 22, 2025 23:24
Copilot AI review requested due to automatic review settings December 22, 2025 23:24
@rustyeddy rustyeddy merged commit 2def1e3 into main Dec 22, 2025
8 of 9 checks passed
@rustyeddy rustyeddy deleted the packages branch December 22, 2025 23:24
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR configures GitHub Actions to build cross-platform binaries for multiple operating systems and architectures, while also making several code changes including dependency updates, message topic reorganization, and device initialization refactoring.

  • Adds a comprehensive GitHub Actions workflow matrix to build binaries for Linux (amd64, ARM variants), macOS (Intel and Apple Silicon), and Windows
  • Updates dependencies (devices v0.0.1→v0.0.3, otto v0.0.9→v0.0.11) and removes local replace directives to use published versions
  • Refactors device initialization to store devices as struct fields and changes MQTT topic naming scheme with "d/" and "c/" prefixes

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
.github/workflows/go.yml Adds multi-architecture build matrix for Linux (ARM variants), macOS, and Windows with artifact uploads
go.mod Updates dependency versions and comments out local replace directives for remote packages
go.sum Adds checksums for updated dependency versions
main.go Renames log file and removes goroutine wrapper from gardener.Start() call
gardener.go Refactors device initialization to use struct fields, updates MQTT topics with prefixes, adds centralized message handler

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/go.yml
cache: true

- name: Prepare dist directory
run: mkdir -p dist
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

The mkdir command syntax is Unix-specific and will fail on Windows runners. While 'mkdir dist' might work on Windows PowerShell, the '-p' flag is bash-specific. For cross-platform compatibility with all matrix builds, specify 'shell: bash' or use a platform-independent approach. Since the workflow already needs bash for the build step, add 'shell: bash' here as well.

Suggested change
run: mkdir -p dist
run: mkdir -p dist
shell: bash

Copilot uses AI. Check for mistakes.
Comment thread gardener.go
Comment on lines +189 to +200
fmt.Println("Got soil: ")

case "env":
fmt.Println("Got env: ")

case "on", "off":
fmt.Println("Got a button")

default:
slog.Error("unknown msg type", "topic", msg.Topic, "msg", msg)
}
fmt.Printf("msg: %#v\n", msg)
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

The MsgHandler function uses fmt.Println for debugging output (lines 189, 192, 195, 200) instead of the structured logging (slog) used throughout the rest of the codebase. For consistency and proper log level control, these should use slog.Debug or slog.Info. Additionally, the messages are incomplete (e.g., "Got soil: " with no value), which suggests these are debugging statements that may have been left in accidentally.

Suggested change
fmt.Println("Got soil: ")
case "env":
fmt.Println("Got env: ")
case "on", "off":
fmt.Println("Got a button")
default:
slog.Error("unknown msg type", "topic", msg.Topic, "msg", msg)
}
fmt.Printf("msg: %#v\n", msg)
slog.Debug("received soil message", "topic", msg.Topic, "value", msg.Data)
case "env":
slog.Debug("received env message", "topic", msg.Topic, "value", msg.Data)
case "on", "off":
slog.Debug("received button message", "topic", msg.Topic, "value", msg.Data)
default:
slog.Error("unknown msg type", "topic", msg.Topic, "msg", msg)
}
slog.Debug("raw MQTT message", "msg", msg)

Copilot uses AI. Check for mistakes.
Comment thread main.go
gardener := &Gardener{}
gardener.Init()
go gardener.Start()
gardener.Start()
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

Removing the goroutine from gardener.Start() changes the application's behavior significantly. The Start() method now blocks the main thread, which means signal handling won't work until Start() returns. This breaks graceful shutdown because the signal handler goroutine at line 72-76 won't be able to process signals while Start() is blocking.

Looking at the Start() method in gardener.go (lines 165-182), it doesn't appear to have a blocking loop, so this might work differently than expected. However, if Start() is intended to be blocking (e.g., if it starts servers or waits for connections), the signal handler needs to be set up before calling Start(), which it already is. But if Start() returns immediately, the program will proceed to wait on gardener.Done at line 78 without anything blocking.

Copilot uses AI. Check for mistakes.
Comment thread gardener.go

func (g *Gardener) initDisplay() {
display, err := oled.New("lcd", 0x27, 1)
display, err := oled.New("c/lcd", 0x27, 1)
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

The display variable is assigned but never stored in the struct field g.display (line 32). This means the display device cannot be accessed later by other methods of the Gardener struct. The pump device is similarly created but assigned to g.pump, while display should be assigned to g.display for consistency with other device initialization methods.

Copilot uses AI. Check for mistakes.
Comment thread gardener.go
Comment on lines +172 to +175
topics := []string{"soil", "env", "on", "off", "pump", "display"}
for _, topic := range topics {
g.Subscribe(topic, g.MsgHandler)
}
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

The message topic subscriptions use base topic names ("soil", "env", "on", "off", "pump", "display"), but the publishing code uses prefixed topics like "d/soil", "d/env", "d/on", "d/off" (device topics) and "c/pump", "c/lcd" (control topics). This mismatch means published messages won't match the subscribed topics, breaking the message flow. The subscriptions should use the same topic prefixes as the publishers, or the publishers should use unprefixed topics.

Copilot uses AI. Check for mistakes.
Comment thread gardener.go
g.pump, err = relay.New("pump", pinmap["pump"])
if err != nil {
panic(err)
}
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

The pump device is initialized but never added to the DeviceManager, unlike all other devices (soil, env, on, off buttons, display). This inconsistency means the pump won't be tracked or managed like other devices. Add g.DeviceManager.Add(g.pump) after line 150, similar to how other devices are registered.

Suggested change
}
}
g.DeviceManager.Add(g.pump)

Copilot uses AI. Check for mistakes.
Comment thread .github/workflows/go.yml
if [ "$GOOS" = "windows" ]; then EXT=".exe"; fi
OUT="dist/${BIN_NAME}-${{ matrix.build.name }}${EXT}"
echo "Building $OUT (GOOS=$GOOS GOARCH=$GOARCH GOARM=$GOARM)"
go build -trimpath -ldflags "-s -w" -o "$OUT" ./...
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

The build command uses 'go build ... ./...' which builds all packages in the module and its subdirectories. However, the intent appears to be building a single binary from the main package. This should be 'go build -trimpath -ldflags "-s -w" -o "$OUT"' (without ./...) or 'go build -trimpath -ldflags "-s -w" -o "$OUT" .' to build only the main package. Building with ./... may produce unexpected results or fail if there are multiple main packages.

Suggested change
go build -trimpath -ldflags "-s -w" -o "$OUT" ./...
go build -trimpath -ldflags "-s -w" -o "$OUT" .

Copilot uses AI. Check for mistakes.
Comment thread .github/workflows/go.yml
Comment on lines +63 to +76
- name: Build binary
env:
GOOS: ${{ matrix.build.goos }}
GOARCH: ${{ matrix.build.goarch }}
GOARM: ${{ matrix.build.goarm }}
run: |
set -e
BIN_NAME=garden-station
EXT=""
if [ "$GOOS" = "windows" ]; then EXT=".exe"; fi
OUT="dist/${BIN_NAME}-${{ matrix.build.name }}${EXT}"
echo "Building $OUT (GOOS=$GOOS GOARCH=$GOARCH GOARM=$GOARM)"
go build -trimpath -ldflags "-s -w" -o "$OUT" ./...
ls -l "$OUT"
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

The shell script uses bash-specific syntax ('set -e', conditional with 'if [ ... ]; then'), but the default shell in GitHub Actions varies by runner OS. On Windows runners, this will fail. Either specify 'shell: bash' in the step configuration, or use cross-platform commands. For consistency across all matrix builds (including Windows), add 'shell: bash' to the step.

Copilot uses AI. Check for mistakes.
Comment thread .github/workflows/go.yml
Comment on lines +37 to +42
- name: darwin-amd64 # macOS Intel
os: macos-latest
goos: darwin
goarch: amd64
- name: darwin-arm64 # macOS Apple Silicon
os: macos-latest
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

Both darwin-amd64 and darwin-arm64 builds are configured to use 'macos-latest' as the runner. However, GitHub Actions currently provides separate runner types: macos-latest (Apple Silicon/ARM64) and macos-13 (Intel/AMD64). Building darwin-amd64 on an ARM64 runner works through cross-compilation, but for optimal build performance and to follow best practices, consider using 'macos-13' for darwin-amd64 builds and 'macos-latest' for darwin-arm64 builds. This is optional since cross-compilation works, but it would be more consistent with how the Windows builds are structured.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants