Skip to content

feat: add pure-go sqlite support via build tags when cgo is disabled - #1072

Open
LXSCA7 wants to merge 1 commit into
gotify:masterfrom
LXSCA7:feat/purego-sqlite-support
Open

LXSCA7 wants to merge 1 commit into
gotify:masterfrom
LXSCA7:feat/purego-sqlite-support

Conversation

@LXSCA7

@LXSCA7 LXSCA7 commented Oct 12, 2026

Copy link
Copy Markdown

Description

This PR enables pure-Go SQLite support via github.com/glebarez/sqlite (backed by modernc.org/sqlite) when compiling with CGO_ENABLED=0.

Motivation

Compiling Gotify with CGO_ENABLED=0 currently fails at runtime because mattn/go-sqlite3 falls back to stub functions that panic (Binary was compiled with 'CGO_ENABLED=0', go-sqlite3 requires cgo to work. This is a stub).

This limits running Gotify in environments where dynamic C libraries / glibc linking or cross-compilation toolchains are problematic (e.g. minimal FROM scratch containers, Alpine environments, Termux/Android, or embedded architectures).

Changes

  • Added conditional SQLite dialectors using Go build tags (//go:build cgo and //go:build !cgo).
  • Standard builds (CGO_ENABLED=1, official Docker images, release workflows) remain 100% unchanged using gorm.io/driver/sqlite.
  • Builds with CGO_ENABLED=0 automatically resolve to github.com/glebarez/sqlite without requiring CGO or external C compilers.
  • Updated database/migration_test.go to use the abstracted dialector.

Tests

  • Verified test suite passes under standard build (CGO_ENABLED=1).
  • Verified test suite passes without CGO (CGO_ENABLED=0).
  • Validated full binary cross-compilation and startup:
    CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags="-s -w" -o gotify_arm64 .
Test output (standard: go test -v ./database/... ./test/testdb/...)

go test -v ./database/... ./test/testdb/...

=== RUN   TestDatabaseSuite
=== RUN   TestDatabaseSuite/TestApplication
=== RUN   TestDatabaseSuite/TestCleanupExpiredClients
=== RUN   TestDatabaseSuite/TestClient
=== RUN   TestDatabaseSuite/TestClientExpiresAtMemoization
=== RUN   TestDatabaseSuite/TestClientSelectHidesExpired
=== RUN   TestDatabaseSuite/TestDeleteAppDeletesMessages
=== RUN   TestDatabaseSuite/TestDeleteUserDeletesApplicationsAndClientsAndPluginConfs
=== RUN   TestDatabaseSuite/TestGetMessagesSince
=== RUN   TestDatabaseSuite/TestMessage
=== RUN   TestDatabaseSuite/TestPing_onClosedDB
=== RUN   TestDatabaseSuite/TestPing_onValidDB
=== RUN   TestDatabaseSuite/TestPluginConf
=== RUN   TestDatabaseSuite/TestUser
=== RUN   TestDatabaseSuite/TestUserPlugins
--- PASS: TestDatabaseSuite (0.32s)
    --- PASS: TestDatabaseSuite/TestApplication (0.01s)
    --- PASS: TestDatabaseSuite/TestCleanupExpiredClients (0.01s)
    --- PASS: TestDatabaseSuite/TestClient (0.01s)
    --- PASS: TestDatabaseSuite/TestClientExpiresAtMemoization (0.01s)
    --- PASS: TestDatabaseSuite/TestClientSelectHidesExpired (0.01s)
    --- PASS: TestDatabaseSuite/TestDeleteAppDeletesMessages (0.01s)
    --- PASS: TestDatabaseSuite/TestDeleteUserDeletesApplicationsAndClientsAndPluginConfs (0.01s)
    --- PASS: TestDatabaseSuite/TestGetMessagesSince (0.22s)    --- PASS: TestDatabaseSuite/TestMessage (0.01s)
    --- PASS: TestDatabaseSuite/TestPing_onClosedDB (0.01s)             --- PASS: TestDatabaseSuite/TestPing_onValidDB (0.01s)
    --- PASS: TestDatabaseSuite/TestPluginConf (0.01s)                  --- PASS: TestDatabaseSuite/TestUser (0.01s)
    --- PASS: TestDatabaseSuite/TestUserPlugins (0.01s)
=== RUN   TestInvalidDialect                                        --- PASS: TestInvalidDialect (0.00s)
=== RUN   TestCreateSqliteFolder                                    --- PASS: TestCreateSqliteFolder (0.01s)
=== RUN   TestWithAlreadyExistingSqliteFolder
--- PASS: TestWithAlreadyExistingSqliteFolder (0.01s)
=== RUN   TestPanicsOnMkdirError
--- PASS: TestPanicsOnMkdirError (0.00s)
=== RUN   TestMigrateSortKey                                        {"level":"info","count":4,"time":"2026-10-12T15:31:40-03:00","message":"Migrating application sort keys"}                               --- PASS: TestMigrateSortKey (0.00s)=== RUN   TestMigration
=== RUN   TestMigration/TestMigration                               --- PASS: TestMigration (0.00s)
    --- PASS: TestMigration/TestMigration (0.00s)
PASS
ok      github.com/gotify/server/v3/database    0.742s
=== RUN   Test_WithDefault
--- PASS: Test_WithDefault (0.00s)                                  === RUN   TestDatabaseSuite
=== RUN   TestDatabaseSuite/Test_Apps
=== RUN   TestDatabaseSuite/Test_Clients
=== RUN   TestDatabaseSuite/Test_Messages
=== RUN   TestDatabaseSuite/Test_Users
--- PASS: TestDatabaseSuite (0.00s)
    --- PASS: TestDatabaseSuite/Test_Apps (0.00s)
    --- PASS: TestDatabaseSuite/Test_Clients (0.00s)
    --- PASS: TestDatabaseSuite/Test_Messages (0.00s)
    --- PASS: TestDatabaseSuite/Test_Users (0.00s)
PASS
ok      github.com/gotify/server/v3/test/testdb 0.812s

CGO_ENABLED=0 go test -v ./database/... ./test/testdb/...

=== RUN   TestDatabaseSuite
=== RUN   TestDatabaseSuite/TestApplication
=== RUN   TestDatabaseSuite/TestCleanupExpiredClients
=== RUN   TestDatabaseSuite/TestClient
=== RUN   TestDatabaseSuite/TestClientExpiresAtMemoization
=== RUN   TestDatabaseSuite/TestClientSelectHidesExpired
=== RUN   TestDatabaseSuite/TestDeleteAppDeletesMessages
=== RUN   TestDatabaseSuite/TestDeleteUserDeletesApplicationsAndClientsAndPluginConfs
=== RUN   TestDatabaseSuite/TestGetMessagesSince
=== RUN   TestDatabaseSuite/TestMessage
=== RUN   TestDatabaseSuite/TestPing_onClosedDB
=== RUN   TestDatabaseSuite/TestPing_onValidDB
=== RUN   TestDatabaseSuite/TestPluginConf
=== RUN   TestDatabaseSuite/TestUser
=== RUN   TestDatabaseSuite/TestUserPlugins
--- PASS: TestDatabaseSuite (0.36s)
    --- PASS: TestDatabaseSuite/TestApplication (0.01s)
    --- PASS: TestDatabaseSuite/TestCleanupExpiredClients (0.01s)
    --- PASS: TestDatabaseSuite/TestClient (0.01s)
    --- PASS: TestDatabaseSuite/TestClientExpiresAtMemoization (0.01s)
    --- PASS: TestDatabaseSuite/TestClientSelectHidesExpired (0.01s)
    --- PASS: TestDatabaseSuite/TestDeleteAppDeletesMessages (0.01s)
    --- PASS: TestDatabaseSuite/TestDeleteUserDeletesApplicationsAndClientsAndPluginConfs (0.01s)
    --- PASS: TestDatabaseSuite/TestGetMessagesSince (0.25s)
    --- PASS: TestDatabaseSuite/TestMessage (0.01s)
    --- PASS: TestDatabaseSuite/TestPing_onClosedDB (0.01s)
    --- PASS: TestDatabaseSuite/TestPing_onValidDB (0.01s)
    --- PASS: TestDatabaseSuite/TestPluginConf (0.01s)
    --- PASS: TestDatabaseSuite/TestUser (0.01s)
    --- PASS: TestDatabaseSuite/TestUserPlugins (0.01s)
=== RUN   TestInvalidDialect
--- PASS: TestInvalidDialect (0.00s)
=== RUN   TestCreateSqliteFolder
--- PASS: TestCreateSqliteFolder (0.01s)
=== RUN   TestWithAlreadyExistingSqliteFolder
--- PASS: TestWithAlreadyExistingSqliteFolder (0.01s)
=== RUN   TestPanicsOnMkdirError
--- PASS: TestPanicsOnMkdirError (0.00s)
=== RUN   TestMigrateSortKey
{"level":"info","count":4,"time":"2026-10-12T15:32:22-03:00","message":"Migrating application sort keys"}
--- PASS: TestMigrateSortKey (0.00s)
=== RUN   TestMigration
=== RUN   TestMigration/TestMigration
--- PASS: TestMigration (0.01s)
    --- PASS: TestMigration/TestMigration (0.01s)
PASS
ok  	github.com/gotify/server/v3/database	1.356s
=== RUN   Test_WithDefault
--- PASS: Test_WithDefault (0.01s)
=== RUN   TestDatabaseSuite
=== RUN   TestDatabaseSuite/Test_Apps
=== RUN   TestDatabaseSuite/Test_Clients
=== RUN   TestDatabaseSuite/Test_Messages
=== RUN   TestDatabaseSuite/Test_Users
--- PASS: TestDatabaseSuite (0.01s)
    --- PASS: TestDatabaseSuite/Test_Apps (0.00s)
    --- PASS: TestDatabaseSuite/Test_Clients (0.00s)
    --- PASS: TestDatabaseSuite/Test_Messages (0.00s)
    --- PASS: TestDatabaseSuite/Test_Users (0.00s)
PASS
ok  	github.com/gotify/server/v3/test/testdb	0.584s

@LXSCA7
LXSCA7 requested a review from a team as a code owner October 12, 2026 19:10
@codecov

codecov Bot commented Oct 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 76.56%. Comparing base (6a49e9c) to head (d3c02f5).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1072      +/-   ##
==========================================
+ Coverage   76.54%   76.56%   +0.01%     
==========================================
  Files          68       69       +1     
  Lines        3714     3716       +2     
==========================================
+ Hits         2843     2845       +2     
  Misses        658      658              
  Partials      213      213              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant