Fix download URL mismatch

This commit is contained in:
NeilClack
2026-06-24 14:17:06 -05:00
parent 732bd7c9a0
commit 0a9a33b87b
3 changed files with 125 additions and 96 deletions
-88
View File
@@ -1,88 +0,0 @@
# RhemaWave
A Go-based fullscreen SDL2/OpenGL application for Linux kiosk systems. Displays proclamations with audio playback and animated visual patterns.
## Development
Development uses Nix for a reproducible build environment.
```bash
nix develop # enter dev shell
go build -o bin/rhemawave rhemawave.go # build
./bin/rhemawave # run
./dev_scripts/reset.sh # reset database (if needed)
```
### Prerequisites
- Nix with flakes enabled
- A display server (X11/Wayland) and audio device for running the application
## Architecture
- **Page-based UI** — SDL2/OpenGL 3.3 fullscreen rendering with a page stack for navigation
- **Proclamation player** — scrolling text display with synchronized audio playback
- **Startup validation** — WiFi, TOS acceptance, email, license key checks
- **Singleton managers** — ShaderManager, FontManager, Logger (initialized once via `sync.Once`)
### Key Directories
```
bin/ # build output (gitignored)
share/rhemawave/ # assets (fonts, shaders, proclamations, TOS)
internal/ # Go source packages
packaging/ # deployment configs (kiosk, updater, polkit)
dev_scripts/ # developer utilities
```
### Runtime Data
Stored in `~/.local/share/rhemawave/`:
- `data.db` — SQLite database (config, proclamations, logs)
- `log.txt` — application log
- `license_key` — license key file
### Development Rules
These rules must be followed during the development of RhemaWave to retain a
maintainable application.
1. The Application package is soley responsible for managing the database handler, and the
configuration cache. Internal packages may update the configuration within the database, and
then signal the application to refresh the cache via a callback function `refreshCache()`.
## Deployment
Deployed to kiosk hardware via NixOS.
## Notes
### Deployment Pipeline
A manual walkthough of deploying Radiant Wave updates.
For reference later when writing automated actions.
1. Create a new branch for issue being worked on
2. Perform work
3. Merge to dev when done
4. Build dev with `nix build` to verify no errors
5. Checkout KioskConfig dev
6. Update rhemawave-dev with `nix flake update rhemawave-dev`
7. Build rhemawavekiosk-dev virtual machine
8. Test virtual machine for problems
9. Build dev-iso
10. Install dev-iso to a machine and check for problems
11. Checkout `main`
12. Merge `dev`
13. `nix flake update rhemawave`
14. Build virtual machine
15. Build iso image
16. Build commercial virtual machine
17. Build commercial iso image
18. Build Raspberry Pi img
19. Approve all virtual machines and iso images
20. Approve all machines update on their own
21. Rename all iso image to "radiantwavekiosk-iso-{system}-{MM-DD-YYYY}-{radiantwave-git-hash}.iso"
22. Upload iso images to file server
23. Move old iso images to `archives/` on the fileserver
+90
View File
@@ -0,0 +1,90 @@
#+TITLE: Radiantwave & KioskConfig Development & Release Pipeline
#+AUTHOR: Neil C.
#+DATE: 2026-06-23
#+OPTIONS: toc:nil num:nil
#+TAGS: development nixos radiantwave kiosk automation
* Radiant Wave
* Full Pipeline Workflow (Detailed)
** Development Phase
1. Create a new branch for the issue
2. Implement the changes for the issue
** Integration to =dev=
3. Open a pull request to =dev=
4. CI: Run =nix build= to verify no errors
5. CI: Run linting and unit tests
6. CI: Auto-update =rhemawave-dev= flake input
7. CI: Build all =dev= VMs in parallel (Kiosk, Commercial, RPi)
8. Merge the pull request to =dev= after CI passes
** Testing Phase
9. Run all VMs (Kiosk, Commercial, RPi) and test all functionality of the application on each VM
10. Install =dev-iso= to a test machine and verify installation and application functionality
** Release to =main=
11. Open a pull request from =dev= to =main=
12. CI: Build all =main= VMs in parallel (Kiosk, Commercial, RPi)
13. CI: Build all ISO images in parallel
14. CI: Auto-rename ISO images to format =radiantwave-{system}-{YYYY-MM-DD}-{git-hash}.iso=
15. CI: Upload ISO images to file server
16. CI: Move old ISO images to =archives/= on file server
17. Merge the pull request to =main= after CI passes
18. Tag the release (optional, for traceability)
* Automation Opportunities
This section describes which parts of the workflow can be automated via CI/CD, and how.
** Group 1: Development Validation (Steps 3-8)
- =What to automate=: PR triggering, =nix build=, linting, unit tests, flake updates, dev VM builds
- =How=: GitHub Actions workflow triggered on PR to =dev=
- =Why=: Catch integration errors before manual testing; ensure =dev= is always buildable
** Group 2: Testing (Steps 9-10)
- =What to automate=: VM functionality testing, ISO installation verification
- =How=: Scripted test suites, automated ISO installation in VMs
- =Why=: Reduce manual toil; increase test coverage and consistency
** Group 3: Release Pipeline (Steps 11-16)
- =What to automate=: Main VM/ISO builds, ISO renaming, file server uploads, archiving
- =How=: GitHub Actions workflow triggered on PR to =main=
- =Why=: Ensure consistent releases; eliminate human error in naming/uploading
* Preflight Checklist
- [ ] Create a new branch for the issue
- [ ] Implement the changes for the issue
- [ ] Open a pull request to =dev=
- [ ] Merge the pull request to =dev= after CI passes
- [ ] Run all VMs (Kiosk, Commercial, RPi) and test all functionality of the application on each VM
- [ ] Install =dev-iso= to a test machine and verify installation and application functionality
- [ ] Open a pull request from =dev= to =main=
- [ ] Merge the pull request to =main= after CI passes
- [ ] Tag the release (optional, for traceability)
* Automation Task List
** Group 1: Development Validation
- [ ] Set up GitHub Actions workflow for PRs to =dev=
- [ ] Configure =nix build= step
- [ ] Add linting and unit test steps
- [ ] Add flake auto-update step
- [ ] Configure parallel VM builds (Kiosk, Commercial, RPi)
- [ ] Verify workflow blocks PR merge on failure
** Group 2: Testing
- [ ] Create automated test scripts for VM functionality
- [ ] Set up automated ISO installation testing
- [ ] Integrate with CI for optional automated testing
** Group 3: Release Pipeline
- [ ] Set up GitHub Actions workflow for PRs to =main=
- [ ] Configure parallel VM builds
- [ ] Configure parallel ISO builds
- [ ] Add ISO auto-renaming step (using =git rev-parse HEAD= and =date +%Y-%m-%d=)
- [ ] Add file server upload step (=rsync= or similar)
- [ ] Add archive old ISOs step
- [ ] Verify workflow blocks PR merge on failure
+35 -8
View File
@@ -20,12 +20,44 @@ type DownloadStatus struct {
Err error // Error, if any
}
// ensureDir checks if a dire
func ensureDir(path string) error {
info, err := os.Stat(path)
if err == nil {
if !info.IsDir() {
return fmt.Errorf("path exists but is not a directory: %s", path)
}
fmt.Printf("Directory already exists: %s\n", path)
return nil
}
if !os.IsNotExist(err) {
return fmt.Errorf("error checking path: %w", err)
}
// 0760 = rwxrw---- (owner: rwx, group: rw-, others: ---)
if err := os.MkdirAll(path, 0760); err != nil {
return fmt.Errorf("failed to create directory: %w", err)
}
logger.Info("Directory created: %s\n", path)
return nil
}
// DownloadAudioFiles downloads multiple audio files and sends progress updates
// to the provided channel. The channel is closed when all downloads are complete.
func DownloadAudioFiles(progressChan chan<- DownloadStatus, filenames []string, destDir string) {
defer close(progressChan)
urlBase := "https://files.rhemawavetech.com/audio/"
if err := ensureDir(destDir); err != nil {
logger.Error("failed to ensureDir %s %v", destDir, err)
progressChan <- DownloadStatus{
Msg: fmt.Sprintf("Failed to ensure directory exists: %v", err),
Err: err,
}
}
urlBase := "https://files.radiantwavetech.com/audio/"
// First, calculate the total size of files that need to be downloaded
totalSize := int64(0)
@@ -87,6 +119,8 @@ func DownloadAudioFiles(progressChan chan<- DownloadStatus, filenames []string,
url := urlBase + filename
destPath := filepath.Join(destDir, filename)
// Ensure the destination directory exists
// Create the destination file
out, err := os.Create(destPath)
if err != nil {
@@ -158,13 +192,6 @@ func DownloadAudioFiles(progressChan chan<- DownloadStatus, filenames []string,
}
out.Close()
// Send completion for this file
progressChan <- DownloadStatus{
Max: totalSize,
Cur: totalDownloaded,
Msg: "Finished Downloading",
}
}
// Send final status