Fix download URL mismatch
This commit is contained in:
@@ -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
@@ -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
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user