The web player is intrinsically LAN-resident: it reaches speakers directly
and only delegates cloud-only features (e.g. TTS) to a possibly-remote
AfterTouch service via --service-url. That is exactly what a cloud-hosted
soundtouch-service cannot do, so the standalone player binary stays useful
and is not being deprecated. Rename it to state its purpose, with a
transition window so existing downloads keep working.
- cmd/soundtouch-web -> cmd/soundtouch-player; CLI name is now
soundtouch-player. When the binary is invoked under its old name it prints
a one-line rename notice (filepath.Base(os.Args[0])).
- Build/release both names from the same source: Makefile (build-player +
build-web alias, dev-player* targets), Dockerfile (soundtouch-player image
+ transitional soundtouch-web image), release.yml and ci.yml (player +
web artifacts, checksums, Docker images; release notes announce the
rename). The soundtouch-web binary, image, and install script remain a
transitional alias to be dropped in a future release (which will break
stale fetch scripts and nudge users to the release notes).
- scripts/raspberry-pi/install-player.sh is canonical; install-web.sh keeps
working but warns.
- Sweep docs, code comments, user-facing strings, and assets
(soundtouch-web-ui.png, soundtouch-web-tunein.png, soundtouch-web-roadmap.md)
to soundtouch-player; README documents the rename and why the player
remains separate from the embedded /app.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Docker build excluded .git via .dockerignore, so Go's debug.ReadBuildInfo()
found no vcs.revision / vcs.time settings and the binaries reported
version=dev, commit=unknown, date=unknown in the web UI.
Two fixes:
1. Dockerfile — declare ARG VERSION/COMMIT/DATE (default to dev/unknown/unknown
so local docker build still works) and pass them to both go build commands
via -X main.version/commit/date ldflags. Also add the -trimpath and -s -w
flags that the Makefile's BUILDFLAGS already uses but the Dockerfile was
missing.
2. release.yml — add a 'Set build date' step, then pass build-args with
VERSION, COMMIT (full SHA), and DATE to both docker/build-push-action
steps. The .git exclusion in .dockerignore stays correct; version info
is now supplied explicitly instead of being read from VCS at build time.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Completes the docs-tier RFC-5737 rollout by sweeping the remaining
192.168.1.x references that lived outside .md / .txt / test files:
- .env.example — active PREFERRED_DEVICES default + examples
- .github/ISSUE_TEMPLATE/*.yml + workflows — issue template + CI examples
- cmd/websocket-demo/main.go, doc.go — top-level docs
- examples/*/main.go (7 files) — example program comments
- pkg/client/client.go — godoc examples
- pkg/models/doc.go — package godoc
- pkg/service/{amazon,spotify,zeroconf}/zeroconf.go — godoc comments
- pkg/service/handlers/web/index.html — placeholder text in the UI
- scripts/prepare-release.sh — example invocations
- scripts/spotify/spotify-prime-speaker.sh — usage comment
- tests/integration/http-client/http-client.env.json — fixture IPs
Same mapping as the docs commit (136d24a): 192.168.1.X → 192.0.2.X
preserving the last octet.
One semantic carve-out: the three zeroconf `zcBaseURL` godoc comments
in pkg/service/{amazon,spotify,zeroconf}/zeroconf.go switched to
192.168.10.10 instead of the doc range, because validateZcBaseURL
only accepts RFC-1918 / loopback / link-local. The comment must show
a value the validator actually accepts — see the matching test fix
in 92f66a2 for the same reason.
go build ./... clean. go test ./... clean except the pre-existing
TestDocsConsistency (untracked DEVICE-LOCAL-INSTALL.md, unrelated).
golangci-lint run ./... — 0 issues after a gofmt fix on
examples/zone-slave-operations/main.go.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace floating major-tag references (uses: foo/bar@vN) with the
specific commit SHAs they currently resolve to, annotated with the
fully-versioned tag (# vX.Y.Z) for human readability. Pinning to a SHA
makes the action behaviour reproducible across runs and removes the
supply-chain risk of a maintainer (or attacker) moving a tag to a new
commit.
One documented exception: semgrep/semgrep-action does not publish
v1.x.y semver tags — v1 is their only canonical release name on that
line — so it keeps a "# v1" annotation with an inline explanation.
actions/dependency-review-action's previous "@v5" reference would have
failed at run time: that repo only ships fully-versioned tags
(v5.0.0), no moving v5 alias. Pinned to v5.0.0 explicitly.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Introduces a standalone `soundtouch-backup` CLI with three subcommands:
- `all`: authenticates with the Bose cloud, backs up account data, then
reads device IPs from devices.xml and backs up each reachable speaker
- `cloud`: fetches account profile, devices, sources, presets, and full
endpoint from streaming.bose.com
- `local`: backs up each speaker via HTTP API (12 endpoints) and
optionally via SSH (individual files + /opt/Bose/etc/ and
/mnt/nv/BoseApp-Persistence/1/ directories)
Also centralises pkg/service/ssh → pkg/ssh so both the service and the
backup tool share the same SSH client; adds ReadFile and ReadDir
methods, and handles the firmware quirk where cat exits 1 on empty
files.
Output is a single dated .tar.gz or .zip archive.
Example flow:
```shell
gesellix@Mac Bose-SoundTouch % go run ./cmd/soundtouch-backup all --output _/cloud-backup --email user@example.com
Password:
Authenticating as user@example.com...
✓ Authenticated (account ID: 1234567)
✓ email address (107 bytes)
✓ devices (1492 bytes)
✓ sources (1111 bytes)
✓ presets (2585 bytes)
✓ full account (55037 bytes)
Found 2 device(s) in cloud account, attempting local backup...
✓ ST20: 12 files via HTTP
⚠ ST20: SSH skipped /etc/remote_services (Process exited with status 1)
⚠ ST20: SSH empty file /mnt/nv/remote_services
✓ ST20: 64 files via SSH
✓ ST10: 12 files via HTTP
⚠ ST10: SSH empty file /etc/remote_services
⚠ ST10: SSH skipped /mnt/nv/remote_services (Process exited with status 1)
✓ ST10: 48 files via SSH
Archive written: _/cloud-backup/soundtouch-backup-2026-05-02.tar.gz (141 files)
```
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
The checksums job was downloading all artifacts including Docker build
artifacts, but it was only designed to process binary artifacts. This
caused failures when the Docker job created artifacts that didn't match
the expected soundtouch-* binary file patterns.
Changed the artifact download to use pattern: binaries-* to only
download the binary artifacts that the checksums generation logic
expects.
- Use debug.ReadBuildInfo() for version information (Go 1.18+ best practice)
- Extract version from module info and VCS settings (vcs.revision, vcs.time)
- Remove complex ldflags setup from Makefile and GitHub workflows
- Simplify build process while maintaining all version information
- Cleaner approach recommended by Go community
Thanks to Gopher Slack feedback for this improvement!
- Use dedicated collection directory to avoid naming conflicts
- Simplify file movement logic by using release-files directory
- Update artifact upload paths to match new structure
- Resolves mv errors when files have same names as directories
Add ls -la output for:
- Working directory before/after build
- Go build cache location and contents
- Go module cache contents
- Post-build state verification
Simple directory listings often reveal file permission issues,
cached artifacts, or leftover files that cause 'File exists' errors
better than complex debugging output.
- Clean build environment before building (remove existing files, clean cache)
- Add atomic checksum generation using temp directory
- Improve error handling with explicit build failure detection
- Add debugging output to diagnose 'File exists' errors
- Use basename in temp operations to avoid path issues
This should resolve the 'Cannot open: File exists' errors occurring
during the darwin/arm64 build process.
Use find -mindepth 2 to only move files from subdirectories, avoiding
the 'mv: cannot overwrite directory' error when flattening the artifact
directory structure. This ensures only the actual binary and checksum
files are moved, not the directories themselves.
Fixes the sha256sum failure in the Generate Checksums workflow step.
- Generate individual SHA256/SHA512 checksums for each binary in matrix jobs
- Maintain combined checksums.sha256/checksums.sha512 files for all binaries
- Upload both types to release assets for maximum user flexibility
- Update release notes with examples for both verification methods
- Filter binary lists to exclude checksum files from combined checksums
Users can now choose between:
- Combined checksums (checksums.sha256) with --ignore-missing flag
- Individual checksums (per-binary .sha256 files) for simpler verification
This provides the best of both approaches for different user preferences.
- Each build job uploads artifact with unique name (binary filename)
- Checksums job downloads all artifacts and flattens structure
- Use 'find . -type f' to only move files, avoiding directory conflicts
- Add debugging output to troubleshoot artifact structure
Fixes 'artifact with this name already exists' error that was
preventing multiple build jobs from uploading simultaneously.
- Upload all binaries to single 'binaries' artifact instead of separate artifacts
- Remove complex directory flattening logic that was causing mv errors
- Add better error handling and debugging output for checksum generation
- Simplify artifact download process
Fixes the 'mv: cannot overwrite directory' errors that were causing
the Generate Checksums step to fail during release builds.
- Remove push:tags trigger that duplicated release:published trigger
- Keep workflow_dispatch for manual releases
- Simplify conditional logic for release creation
- Fix tag name resolution for different event types
- Ensure single workflow run per release creation
Resolves double-triggering issue where GitHub web UI release
creation would trigger both push:tags and release:published events.
- Reference original API documentation source from Bose Corporation
- Link to official Bose SoundTouch End-of-Life page
- Clarify this is an independent implementation
- Add disclaimer about non-affiliation with Bose Corporation
- Provide both online and local documentation references
- Remove Go version matrix from CI workflow
- Use go-version-file option to read from go.mod
- Update cache keys to use go.mod hash
- Ensure single source of truth for Go version
- Simplify maintenance by centralizing version management
- Add CI workflow with multi-version Go testing, linting, security scans
- Add automated release workflow triggered on tag push
- Include Dependabot for dependency management
- Add professional issue templates for bugs and features
- Configure golangci-lint with production-ready settings
- Update local release script to complement automation
- Support cross-platform builds for 7 platforms
- Automated release notes and checksum generation