Fixes nightly build failures caused by: GoReleaser v2 requiring version 2 config syntax Zig cross-compilation failing for macOS CGO targets SQLite Driver Migration: Replace gorm.io/driver/sqlite with github.com/glebarez/sqlite (pure-Go) Execute PRAGMA statements via SQL instead of DSN parameters All platforms now build with CGO_ENABLED=0 GoReleaser v2 Migration: Update version: 1 → version: 2 snapshot.name_template → version_template archives.format → formats (array syntax) archives.builds → ids nfpms.builds → ids Remove Zig cross-compilation environment Also fixes Docker Compose E2E image reference: Use CHARON_E2E_IMAGE_TAG instead of bare digest Add fallback default for local development All database tests pass with the pure-Go SQLite driver.
16 KiB
GoReleaser v2 Migration & Nightly Build Failure Remediation
Status: Active
Created: 2026-01-30
Priority: CRITICAL (Blocking Nightly Builds)
Executive Summary
The nightly build workflow (nightly-build.yml) is failing with multiple issues:
- GoReleaser v2 Compatibility: Config uses deprecated v1 syntax
- Zig Cross-Compilation: Incorrect macOS target triple format
- 🆕 CGO/SQLite Dependency: Disabling CGO for darwin breaks SQLite (
mattn/go-sqlite3requires CGO)
Error Messages:
only version: 2 configuration files are supported, yours is version: 1, please update your configuration
Deprecation Warnings:
snapshot.name_templateis deprecatedarchives.formatis deprecatedarchives.buildsis deprecatednfpms.buildsis deprecated
Build Error (Zig):
error: unable to find or provide libc for target 'x86_64-macos.11.7.1...13.3-gnu'
info: zig can provide libc for related target x86_64-macos.11-none
🔴 Critical Dependency: SQLite CGO Issue
Problem Statement
The current SQLite driver (gorm.io/driver/sqlite) depends on mattn/go-sqlite3, which is a CGO-based library. This means:
- CGO_ENABLED=0 will cause build failures when SQLite is used
- Cross-compilation for darwin from Linux is blocked by CGO complexity
- The proposed fix of disabling CGO for darwin builds will break the application
Solution: Migrate to Pure-Go SQLite
Recommended Migration Path:
| Current | New | Notes |
|---|---|---|
gorm.io/driver/sqlite |
github.com/glebarez/sqlite |
GORM-compatible pure-Go driver |
mattn/go-sqlite3 (indirect) |
modernc.org/sqlite (indirect) |
Pure-Go SQLite implementation |
Benefits:
- ✅ No CGO required for any platform
- ✅ Simplified cross-compilation (no Zig needed for SQLite)
- ✅ Smaller binary size
- ✅ Faster build times
- ✅ Same GORM API - minimal code changes required
Files Requiring SQLite Driver Changes
| File | Line | Change Required |
|---|---|---|
| backend/internal/database/database.go | 10 | gorm.io/driver/sqlite → github.com/glebarez/sqlite |
| backend/internal/testutil/db_test.go | 6 | gorm.io/driver/sqlite → github.com/glebarez/sqlite |
| backend/cmd/seed/main.go | 13 | gorm.io/driver/sqlite → github.com/glebarez/sqlite |
| backend/go.mod | 19 | Replace gorm.io/driver/sqlite with github.com/glebarez/sqlite |
Issue 1: GoReleaser v1 → v2 Migration (CRITICAL)
Problem Statement
GoReleaser v2 (currently v2.13.3) no longer supports version: 1 configuration files. The nightly workflow uses GoReleaser ~> v2 which requires v2 config syntax.
Root Cause Analysis
Current .goreleaser.yaml uses deprecated v1 syntax:
version: 1 # ❌ v2 requires "version: 2"
Multiple deprecated fields need updating:
| Deprecated Field | v2 Replacement |
|---|---|
snapshot.name_template |
snapshot.version_template |
archives.format |
archives.formats (array) |
archives.builds |
archives.ids |
nfpms.builds |
nfpms.ids |
GoReleaser Deprecation Reference
From goreleaser.com/deprecations:
-
snapshot.name_template→snapshot.version_template- Changed in v2.0.0
- The template generates a version string, not a "name"
-
archives.format→archives.formats- Changed to array to support multiple formats per archive config
- Must be
formats: [tar.gz]notformat: tar.gz
-
archives.builds→archives.ids- Renamed for clarity: it filters by build
id, not "builds"
- Renamed for clarity: it filters by build
-
nfpms.builds→nfpms.ids- Same rationale as archives
Required Changes
--- a/.goreleaser.yaml
+++ b/.goreleaser.yaml
@@ -1,4 +1,4 @@
-version: 1
+version: 2
project_name: charon
@@ -62,10 +62,10 @@
- -X github.com/Wikid82/charon/backend/internal/version.BuildTime={{.Date}}
archives:
- - format: tar.gz
+ - formats: [tar.gz]
id: nix
- builds:
+ ids:
- linux
- darwin
name_template: >-
@@ -76,9 +76,9 @@
- LICENSE
- README.md
- - format: zip
+ - formats: [zip]
id: windows
- builds:
+ ids:
- windows
name_template: >-
{{ .ProjectName }}_
@@ -90,7 +90,7 @@
nfpms:
- id: packages
- builds:
+ ids:
- linux
package_name: charon
vendor: Charon
@@ -116,7 +116,7 @@
name_template: 'checksums.txt'
snapshot:
- name_template: "{{ .Tag }}-next"
+ version_template: "{{ .Tag }}-next"
changelog:
sort: asc
Issue 2: Zig Cross-Compilation for macOS
Problem Statement
The nightly build fails during GoReleaser release step when cross-compiling for macOS (darwin) using Zig:
error: unable to find or provide libc for target 'x86_64-macos.11.7.1...13.3-gnu'
info: zig can provide libc for related target x86_64-macos.11-none
Root Cause Analysis
The .goreleaser.yaml darwin build uses -macos-none which is correct, but examining the actual file shows -macos-none is already in place. The error message suggests something is injecting version numbers.
Wait - Re-reading the current config, I see it actually says -macos-none already. Let me check if there's a different issue.
Actually, looking at the error more carefully:
target 'x86_64-macos.11.7.1...13.3-gnu'
This suggests the Go runtime/cgo is detecting the macOS version range and passing it to Zig incorrectly. The -gnu suffix shouldn't be there for macOS.
Current Configuration:
CC=zig cc -target {{ if eq .Arch "amd64" }}x86_64{{ else }}aarch64{{ end }}-macos-none
The current config is correct (-macos-none), but CGO may be interfering.
Recommended Fix: Disable CGO for Darwin
⚠️ UPDATE: This section is superseded by the SQLite driver migration (see "Critical Dependency: SQLite CGO Issue" above). Simply disabling CGO for darwin breaks SQLite functionality.
✅ Actual Fix: Migrate to Pure-Go SQLite
By migrating from gorm.io/driver/sqlite (CGO) to github.com/glebarez/sqlite (pure-Go):
- Zig is no longer required for any platform
- CGO_ENABLED=0 can be used for ALL platforms (linux, darwin, windows)
- Cross-compilation is trivial - standard Go cross-compilation works
- Build times are faster - no C compiler invocation
This completely eliminates Issue 2 as a side effect of fixing the SQLite dependency issue.
Complete Updated .goreleaser.yaml
Note: After migrating to pure-Go SQLite (
github.com/glebarez/sqlite), Zig cross-compilation is no longer required. All platforms now useCGO_ENABLED=0for simpler, faster builds.
version: 2
project_name: charon
builds:
- id: linux
dir: backend
main: ./cmd/api
binary: charon
env:
- CGO_ENABLED=0
goos:
- linux
goarch:
- amd64
- arm64
ldflags:
- -s -w
- -X github.com/Wikid82/charon/backend/internal/version.Version={{.Version}}
- -X github.com/Wikid82/charon/backend/internal/version.GitCommit={{.Commit}}
- -X github.com/Wikid82/charon/backend/internal/version.BuildTime={{.Date}}
- id: windows
dir: backend
main: ./cmd/api
binary: charon
env:
- CGO_ENABLED=0
goos:
- windows
goarch:
- amd64
ldflags:
- -s -w
- -X github.com/Wikid82/charon/backend/internal/version.Version={{.Version}}
- -X github.com/Wikid82/charon/backend/internal/version.GitCommit={{.Commit}}
- -X github.com/Wikid82/charon/backend/internal/version.BuildTime={{.Date}}
- id: darwin
dir: backend
main: ./cmd/api
binary: charon
env:
- CGO_ENABLED=0
goos:
- darwin
goarch:
- amd64
- arm64
ldflags:
- -s -w
- -X github.com/Wikid82/charon/backend/internal/version.Version={{.Version}}
- -X github.com/Wikid82/charon/backend/internal/version.GitCommit={{.Commit}}
- -X github.com/Wikid82/charon/backend/internal/version.BuildTime={{.Date}}
archives:
- formats: [tar.gz]
id: nix
ids:
- linux
- darwin
name_template: >-
{{ .ProjectName }}_
{{- .Version }}_
{{- .Os }}_
{{- .Arch }}
files:
- LICENSE
- README.md
- formats: [zip]
id: windows
ids:
- windows
name_template: >-
{{ .ProjectName }}_
{{- .Version }}_
{{- .Os }}_
{{- .Arch }}
files:
- LICENSE
- README.md
nfpms:
- id: packages
ids:
- linux
package_name: charon
vendor: Charon
homepage: https://github.com/Wikid82/charon
maintainer: Wikid82
description: "Charon - A powerful reverse proxy manager"
license: MIT
formats:
- deb
- rpm
contents:
- src: ./backend/data/
dst: /var/lib/charon/data/
type: dir
- src: ./frontend/dist/
dst: /usr/share/charon/frontend/
type: dir
dependencies:
- libc6
- ca-certificates
checksum:
name_template: 'checksums.txt'
snapshot:
version_template: "{{ .Tag }}-next"
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'
Implementation Plan
Phase 0: SQLite Driver Migration (PREREQUISITE)
Objective: Migrate from CGO-dependent SQLite to pure-Go implementation.
Files to Modify:
| File | Change | Reason |
|---|---|---|
backend/go.mod |
Replace gorm.io/driver/sqlite with github.com/glebarez/sqlite |
Pure-Go SQLite driver |
backend/internal/database/database.go |
Update import statement | New driver package |
backend/internal/testutil/db_test.go |
Update import statement | New driver package |
backend/cmd/seed/main.go |
Update import statement | New driver package |
Steps:
# 1. Update go.mod - replace CGO driver with pure-Go driver
cd backend
go get github.com/glebarez/sqlite
go mod edit -droprequire gorm.io/driver/sqlite
# 2. Update import statements in Go files
# (Manual step - update imports in 3 files listed above)
# 3. Tidy dependencies
go mod tidy
# 4. Verify build works without CGO
CGO_ENABLED=0 go build ./cmd/api
CGO_ENABLED=0 go build ./cmd/seed
# 5. Run tests to verify SQLite functionality
CGO_ENABLED=0 go test ./internal/database/... -v
CGO_ENABLED=0 go test ./internal/testutil/... -v
Validation:
- ✅
CGO_ENABLED=0 go build ./backend/cmd/apisucceeds - ✅
CGO_ENABLED=0 go build ./backend/cmd/seedsucceeds - ✅ All database tests pass with CGO disabled
- ✅
go.modno longer referencesgorm.io/driver/sqliteormattn/go-sqlite3
Phase 1: Update GoReleaser Config
Files to Modify:
| File | Change | Reason |
|---|---|---|
.goreleaser.yaml |
Update to version 2 syntax | Required for GoReleaser ~> v2 |
.goreleaser.yaml |
Remove Zig cross-compilation | No longer needed with pure-Go SQLite |
.goreleaser.yaml |
Set CGO_ENABLED=0 for ALL platforms |
Consistent pure-Go builds |
Simplified Build Configuration (No Zig Required):
builds:
- id: linux
dir: backend
main: ./cmd/api
binary: charon
env:
- CGO_ENABLED=0
goos:
- linux
goarch:
- amd64
- arm64
ldflags:
- -s -w
- -X github.com/Wikid82/charon/backend/internal/version.Version={{.Version}}
- -X github.com/Wikid82/charon/backend/internal/version.GitCommit={{.Commit}}
- -X github.com/Wikid82/charon/backend/internal/version.BuildTime={{.Date}}
- id: windows
dir: backend
main: ./cmd/api
binary: charon
env:
- CGO_ENABLED=0
goos:
- windows
goarch:
- amd64
ldflags:
- -s -w
- -X github.com/Wikid82/charon/backend/internal/version.Version={{.Version}}
- -X github.com/Wikid82/charon/backend/internal/version.GitCommit={{.Commit}}
- -X github.com/Wikid82/charon/backend/internal/version.BuildTime={{.Date}}
- id: darwin
dir: backend
main: ./cmd/api
binary: charon
env:
- CGO_ENABLED=0
goos:
- darwin
goarch:
- amd64
- arm64
ldflags:
- -s -w
- -X github.com/Wikid82/charon/backend/internal/version.Version={{.Version}}
- -X github.com/Wikid82/charon/backend/internal/version.GitCommit={{.Commit}}
- -X github.com/Wikid82/charon/backend/internal/version.BuildTime={{.Date}}
Phase 2: Verification Steps
# 1. Verify SQLite migration (Phase 0 complete)
cd backend
CGO_ENABLED=0 go build ./cmd/api
CGO_ENABLED=0 go test ./... -count=1
# 2. Validate the GoReleaser config locally
goreleaser check
# 3. Test snapshot build locally (no Zig required!)
goreleaser release --snapshot --skip=publish --clean
# 4. Trigger nightly workflow manually
gh workflow run nightly-build.yml -f reason="Test GoReleaser v2 migration with pure-Go SQLite"
# 5. Monitor workflow execution
gh run watch
Phase 3: Rollback Plan
If the fix fails:
SQLite Rollback:
- Revert
go.modto usegorm.io/driver/sqlite - Revert import statement changes
- Re-enable CGO in GoReleaser config
GoReleaser Rollback:
- Revert
.goreleaser.yamlchanges - Pin GoReleaser to v1.x in workflows:
version: '1.26.2' # Last v1 release
Requirements (EARS Notation)
- WHEN building for any platform, THE SYSTEM SHALL use
CGO_ENABLED=0(pure-Go builds). - WHEN importing the SQLite driver, THE SYSTEM SHALL use
github.com/glebarez/sqlite(pure-Go driver). - WHEN GoReleaser executes, THE SYSTEM SHALL use version 2 configuration syntax.
- WHEN archiving builds, THE SYSTEM SHALL use
formats(array) instead of deprecatedformat. - WHEN referencing build IDs in archives/nfpms, THE SYSTEM SHALL use
idsinstead of deprecatedbuilds. - WHEN generating snapshot versions, THE SYSTEM SHALL use
version_templateinstead of deprecatedname_template.
Acceptance Criteria
Phase 0 (SQLite Migration):
backend/go.modusesgithub.com/glebarez/sqliteinstead ofgorm.io/driver/sqlite- No references to
mattn/go-sqlite3ingo.modorgo.sum CGO_ENABLED=0 go build ./backend/cmd/apisucceedsCGO_ENABLED=0 go build ./backend/cmd/seedsucceeds- All database tests pass with
CGO_ENABLED=0
Phase 1 (GoReleaser v2):
goreleaser checkpasses without errors or deprecation warnings- Nightly build workflow completes successfully
- Linux amd64/arm64 binaries are produced
- Windows amd64 binary is produced
- Darwin amd64/arm64 binaries are produced
- .deb and .rpm packages are produced for Linux
- No deprecation warnings in CI logs
- No Zig-related errors in build logs
Risk Assessment
| Risk | Likelihood | Impact | Mitigation |
|---|---|---|---|
| Pure-Go SQLite has different behavior | Low | Medium | Run full test suite; compare query results |
| Pure-Go SQLite performance differs | Low | Low | Run benchmarks; acceptable for typical workloads |
| Other undocumented v2 breaking changes | Low | Medium | Monitor GoReleaser changelog; test locally first |
| Import statement missed in some file | Low | High | Use grep to find all gorm.io/driver/sqlite imports |
References
- glebarez/sqlite - Pure Go SQLite driver for GORM
- modernc.org/sqlite - Pure Go SQLite implementation
- GoReleaser v2 Migration Guide
- GoReleaser Builds Documentation
ARCHIVED: Other CI Issues (Separate from GoReleaser)
The following issues are documented separately and may be addressed in future PRs:
- Playwright E2E - Emergency Server Connectivity - See docs/plans/e2e_remediation_spec.md
- Trivy Scan - Image Reference Validation - See docs/plans/docker_compose_ci_fix.md