2026-08-25 14:15:35 -08:00
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
|
|
|
|
|
"dagger/quintodrome/internal/dagger"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type Quintodrome struct{}
|
|
|
|
|
|
2026-08-25 14:20:12 -08:00
|
|
|
// Ci runs the full Linux CI: lint, build, and test for both Go and JS.
|
2026-08-25 14:15:35 -08:00
|
|
|
func (m *Quintodrome) Ci(ctx context.Context,
|
|
|
|
|
// +defaultPath="."
|
|
|
|
|
src *dagger.Directory,
|
|
|
|
|
) error {
|
2026-08-25 14:20:12 -08:00
|
|
|
if err := m.LintGo(ctx, src); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if err := m.FmtGo(ctx, src); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2026-08-25 14:15:35 -08:00
|
|
|
if err := m.BuildGo(ctx, src); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if err := m.TestGo(ctx, src); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2026-08-25 14:20:12 -08:00
|
|
|
if err := m.LintJS(ctx, src); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2026-08-25 14:15:35 -08:00
|
|
|
if err := m.BuildJS(ctx, src); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if err := m.TestJS(ctx, src); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-25 14:20:12 -08:00
|
|
|
// LintGo runs golangci-lint with the repo's .golangci.yml.
|
|
|
|
|
func (m *Quintodrome) LintGo(ctx context.Context, src *dagger.Directory) error {
|
|
|
|
|
_, err := goContainer().
|
|
|
|
|
WithDirectory("/repo", src).
|
|
|
|
|
WithWorkdir("/repo").
|
2026-08-25 14:43:59 -08:00
|
|
|
WithExec([]string{"sh", "-c", "curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b /usr/local/bin"}).
|
2026-08-25 14:20:12 -08:00
|
|
|
WithExec([]string{"golangci-lint", "run", "--timeout", "2m"}).
|
|
|
|
|
Sync(ctx)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FmtGo checks that goimports and go mod tidy leave the tree clean.
|
|
|
|
|
func (m *Quintodrome) FmtGo(ctx context.Context, src *dagger.Directory) error {
|
|
|
|
|
_, err := goContainer().
|
|
|
|
|
WithDirectory("/repo", src).
|
|
|
|
|
WithWorkdir("/repo").
|
|
|
|
|
WithExec([]string{"sh", "-c", `
|
|
|
|
|
go run golang.org/x/tools/cmd/goimports@latest -w $(find . -name '*.go' | grep -v '_gen.go$' | grep -v '.pb.go$')
|
|
|
|
|
go mod tidy
|
|
|
|
|
test -z "$(git status --porcelain)"
|
|
|
|
|
`}).
|
|
|
|
|
Sync(ctx)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-25 14:15:35 -08:00
|
|
|
// BuildGo compiles the Navidrome server and all packages.
|
|
|
|
|
func (m *Quintodrome) BuildGo(ctx context.Context, src *dagger.Directory) error {
|
|
|
|
|
_, err := goContainer().
|
|
|
|
|
WithDirectory("/repo", src).
|
|
|
|
|
WithWorkdir("/repo").
|
|
|
|
|
WithExec([]string{"go", "build", "-tags", "netgo,sqlite_fts5", "./..."}).
|
|
|
|
|
Sync(ctx)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TestGo runs the Go test suite.
|
|
|
|
|
func (m *Quintodrome) TestGo(ctx context.Context, src *dagger.Directory) error {
|
|
|
|
|
_, err := goContainer().
|
|
|
|
|
WithDirectory("/repo", src).
|
|
|
|
|
WithWorkdir("/repo").
|
|
|
|
|
WithExec([]string{"go", "test", "-tags", "netgo,sqlite_fts5", "./..."}).
|
|
|
|
|
Sync(ctx)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-25 14:20:12 -08:00
|
|
|
// LintJS runs prettier and eslint in the web UI.
|
|
|
|
|
func (m *Quintodrome) LintJS(ctx context.Context, src *dagger.Directory) error {
|
|
|
|
|
_, err := jsContainer().
|
|
|
|
|
WithDirectory("/repo", src).
|
|
|
|
|
WithWorkdir("/repo/ui").
|
|
|
|
|
WithExec([]string{"npm", "ci", "--ignore-scripts"}).
|
|
|
|
|
WithExec([]string{"npm", "run", "check-formatting"}).
|
|
|
|
|
WithExec([]string{"npm", "run", "lint"}).
|
|
|
|
|
Sync(ctx)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-25 14:15:35 -08:00
|
|
|
// BuildJS builds the Navidrome web UI.
|
|
|
|
|
func (m *Quintodrome) BuildJS(ctx context.Context, src *dagger.Directory) error {
|
|
|
|
|
_, err := jsContainer().
|
|
|
|
|
WithDirectory("/repo", src).
|
|
|
|
|
WithWorkdir("/repo/ui").
|
|
|
|
|
WithExec([]string{"npm", "ci", "--ignore-scripts"}).
|
|
|
|
|
WithExec([]string{"npm", "run", "build"}).
|
|
|
|
|
Sync(ctx)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TestJS runs the JS test suite.
|
|
|
|
|
func (m *Quintodrome) TestJS(ctx context.Context, src *dagger.Directory) error {
|
|
|
|
|
_, err := jsContainer().
|
|
|
|
|
WithDirectory("/repo", src).
|
|
|
|
|
WithWorkdir("/repo/ui").
|
|
|
|
|
WithExec([]string{"npm", "ci", "--ignore-scripts"}).
|
|
|
|
|
WithExec([]string{"npm", "test"}).
|
|
|
|
|
Sync(ctx)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func goContainer() *dagger.Container {
|
|
|
|
|
return dag.Container().From("golang:1.26")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func jsContainer() *dagger.Container {
|
|
|
|
|
return dag.Container().From("node:24")
|
|
|
|
|
}
|
2026-08-25 14:24:26 -08:00
|
|
|
|
|
|
|
|
// BuildDesktopWindows builds the Windows desktop app (.exe/.msi) inside a
|
|
|
|
|
// Windows container.
|
|
|
|
|
//
|
|
|
|
|
// Experimental: this requires the Dagger engine to run on a Windows host with
|
|
|
|
|
// BuildKit's Windows container support enabled (the engine uses the containerd
|
|
|
|
|
// worker with `platforms = ["windows/amd64"]`). Unverified end-to-end — the
|
|
|
|
|
// Rust MSVC toolchain and Tauri's NSIS/WiX bundling may not behave in a
|
|
|
|
|
// Windows Server Core container the way they do on a full Windows runner.
|
|
|
|
|
func (m *Quintodrome) BuildDesktopWindows(ctx context.Context, src *dagger.Directory) *dagger.Directory {
|
|
|
|
|
setup := `Set-ExecutionPolicy Bypass -Scope Process -Force
|
|
|
|
|
[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor 3072
|
|
|
|
|
iex ((New-Object Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
|
|
|
|
|
choco install -y nodejs-lts golang rustup.install visualstudio2022buildtools visualstudio2022-workload-vctools --no-progress`
|
|
|
|
|
|
|
|
|
|
return dag.Container().
|
|
|
|
|
From("mcr.microsoft.com/windows/servercore:ltsc2022").
|
|
|
|
|
WithDirectory("C:/src", src).
|
|
|
|
|
WithWorkdir("C:/src").
|
|
|
|
|
WithExec([]string{"powershell", "-NoProfile", "-Command", setup}).
|
|
|
|
|
WithExec([]string{"cmd", "/c", "npm --version && go version && rustc --version"}).
|
|
|
|
|
Directory("C:/src/desktop/src-tauri/target/release/bundle")
|
|
|
|
|
}
|