Four documents asserted things the code contradicts. ARCHITECTURE's component diagram had the UI calling the autostart Manager directly. It does not, and must not: src/ui holds no reference to the package at all — Settings reads svc.AutostartStatus(), like everything else it reads. The edge is folded into the existing ui→Service one, so the diagram no longer draws the exception to the project's own rule. platform/desktop was described in both ARCHITECTURE and DEVELOPMENT as a "display-scale helper". It installs the .desktop entry and icon under XDG data home; there is no scale helper in it. The ~250-line file guideline was written as though the jobs_view and settings_view splits had settled it. Both files are over it again and history_view.go has never been split, so the guideline is now stated as the target it is, with the current state named rather than implied. STANDARDS pointed at a "CI coverage gate" item that ROADMAP does not have, while omitting the two it does. README's gosentry.json sample was three keys short of what the app writes on first run — default_timeout_seconds, theme and job_list_view — which made the one file the user is invited to hand-edit the least accurate thing in the document. The sample is now the real default (verified by marshalling DefaultConfig), with the keys explained, including why a zero timeout is written out and an unset one is not. The per-job overrides for overlap policy and timeout were undocumented despite being in the job dialog, and the feature list had not caught up with the timeout, the theme, or the compact job list. Version numbers in example output paths are now <version>, matching how the CI section already wrote them, so they cannot go stale again. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
7.1 KiB
GoSentry — Development
Build instructions, project layout, and dependency information for contributors.
Requirements
Common:
- Go 1.22 or newer.
Windows:
- MSYS2 with UCRT64 GCC in
C:\msys64\ucrt64\bin.
Install these dependencies on Windows:
# 1. Install Go 1.22 or newer from https://go.dev/dl/.
# The default installer path is C:\Program Files\Go.
go version
# 2. Install MSYS2 from https://www.msys2.org/.
# Use the default installation path so UCRT64 tools are placed under
# C:\msys64\ucrt64\bin.
# 3. Open "MSYS2 UCRT64" from the Start menu and install GCC plus windres.
pacman -Syu
pacman -S --needed mingw-w64-ucrt-x86_64-gcc mingw-w64-ucrt-x86_64-binutils
# 4. In PowerShell, check that the compiler is available where the build script
# expects it. build-windows.bat prepends this directory automatically.
Test-Path C:\msys64\ucrt64\bin\gcc.exe
Test-Path C:\msys64\ucrt64\bin\windres.exe
Linux:
- A C compiler.
- Fyne native build dependencies, including OpenGL/X11 development packages.
On Debian/Ubuntu, the Linux dependencies are typically:
# Go builds the application, gcc is required by CGO/Fyne, and the OpenGL/X11
# development packages provide the native desktop headers used by Fyne.
sudo apt install golang gcc libgl1-mesa-dev xorg-dev
Build
Windows
# Builds dist\windows\gosentry-<version>-windows-amd64.exe. The script changes
# to the repository root first, so double-clicking it from Explorer works. It
# also adds MSYS2 UCRT64 to PATH for this process only, embeds the Windows icon
# when windres is available, and uses the Windows GUI subsystem so no console
# window opens at startup.
.\scripts\build-windows.bat
The Windows build is created as a GUI application, so it does not open a terminal window.
The binary is written to:
dist\windows\gosentry-<version>-windows-amd64.exe
Linux
# Make the helper executable once, then build a linux/amd64 Fyne binary.
chmod +x ./scripts/build-linux.sh
./scripts/build-linux.sh
The binary is written to:
dist/linux/gosentry-<version>-linux-amd64
Linux using Docker
# Builds the Linux binary inside Docker using the versioned image tag
# gitea.mixdep.ru/mix/gosentry-builder:<version>. Useful from hosts or CI jobs
# where the native Linux/Fyne packages are not installed locally.
chmod +x ./scripts/build-linux-docker.sh
./scripts/build-linux-docker.sh
The binary is copied to:
dist/linux/gosentry-<version>-linux-amd64
Release build from Linux
# Interactively choose Linux amd64, Linux arm64, Windows amd64, or all artifacts
# from one Linux/Docker workflow. The Dockerfile contains the builder
# environment; the build commands live in this script. Docker runs the build
# with the current user's UID/GID so dist/ files are not owned by root.
chmod +x ./scripts/build-release-linux.sh
./scripts/build-release-linux.sh
Non-interactive release builds can pass target names:
# Build only Linux arm64 and Windows amd64 artifacts.
./scripts/build-release-linux.sh linux-arm64 windows-amd64
The binaries are copied to:
dist/linux/gosentry-<version>-linux-amd64
dist/linux/gosentry-<version>-linux-arm64
dist/windows/gosentry-<version>-windows-amd64.exe
Automated release builds (CI)
Tagged releases are built automatically on both GitHub and Codeberg:
.github/workflows/release.yml— GitHub Actions..forgejo/workflows/release.yml— Forgejo Actions (Codeberg).
Both run inside golang:1.22-bookworm (the same base image as the
Dockerfile), install the cross toolchain, and call
scripts/ci-build-release.sh, which builds and packages all three artifacts:
dist/linux/gosentry-<version>-linux-amd64.tar.gz
dist/linux/gosentry-<version>-linux-arm64.tar.gz
dist/windows/gosentry-<version>-windows-amd64.zip
The Windows binary is cross-compiled with MinGW-w64 from the Linux job, so no
Windows runner is required. Each archive contains the executable plus README.md
and CHANGELOG.md, matching the local package-* scripts.
To cut a release, bump src/app/version.go, then create and publish a release
with a matching v tag on the forge (GitHub Releases / Codeberg releases). You
can do that from the web UI or the CLI, e.g.:
git tag v0.11.5
git push origin v0.11.5 # and to the Codeberg remote
gh release create v0.11.5 --generate-notes # GitHub; publishes the release
Publishing the release triggers the workflow: it strips the leading v from
the tag and injects it as the version (so the tag must match version.go),
builds the archives, and attaches them to that release. workflow_dispatch
also allows a manual, upload-free build to smoke-test the pipeline.
Codeberg publishing needs a repository secret named RELEASE_TOKEN (a Codeberg
access token with the write:repository scope) under
Settings → Actions → Secrets. GitHub uses the built-in GITHUB_TOKEN.
Run From Source
Windows:
# Fyne requires CGO on Windows. MSYS2 UCRT64 provides the C compiler and native
# libraries used by the desktop backend.
$env:Path = 'C:\msys64\ucrt64\bin;' + $env:Path
$env:CGO_ENABLED = '1'
# go run starts the app from source. Use scripts\build-windows.bat when you need
# a standalone .exe without a console window.
& 'C:\Program Files\Go\bin\go.exe' run ./cmd/gosentry
Linux:
# CGO must stay enabled because the Fyne GUI links against native Linux desktop
# libraries.
CGO_ENABLED=1 go run ./cmd/gosentry
Project Layout
cmd/gosentry— entry point; starts the desktop app.src/domain— pure value types:Job,Config,RunRecord,Schedule,JobRuntime.src/app—Service: sole owner of job and runtime state; emits typed events to the UI.src/scheduler— pure timing loop; callsService.RunDueon every tick.src/runner— shell command execution, log file writing, and log cleanup.src/storage— JSON persistence (gosentry.json,jobs.json).src/platform/autostart—Managerinterface with Windows (shortcut) and Linux (XDG) implementations.src/platform/desktop— desktop entry and icon under XDG data home (Linux only).src/platform/winproc— hidden-window startup flags (Windows only).src/ui— Fyne windows, tabs, and dialogs; reads service state through events.assets— app icons embedded into the application binary.scripts— build helpers.docs— architecture notes, changelog, and roadmap.
Build outputs are written to dist/.
Dependencies
GoSentry keeps the direct dependency list intentionally small:
fyne.io/fyne/v2for the native GUI.github.com/robfig/cron/v3for cron schedule parsing.
The remaining entries in go.mod are indirect dependencies pulled by Fyne and the Go module resolver.
Source repositories for mirroring:
- Go toolchain: https://go.googlesource.com/go
- Fyne: https://github.com/fyne-io/fyne
- robfig/cron: https://github.com/robfig/cron
To list every direct and indirect Go module used by the current checkout:
go list -m all