From 2f2c4aad6578de6036cf9b7ecd15aa0449a9c18c Mon Sep 17 00:00:00 2001 From: Jonathan Taylor Date: Mon, 2 Mar 2026 11:10:33 -0500 Subject: [PATCH] fix: embed IANA timezone database for Windows support - Import time/tzdata in cmd/gog/main.go to bundle the IANA tz database into the binary (~450KB), fixing time.LoadLocation on Windows - Add tzdata_test.go verifying LoadLocation works for representative zones - Add windows-latest CI job running the full gate (fmt, lint, test, build) --- .github/workflows/ci.yml | 28 ++++++++++++++++++++++++++ cmd/gog/main.go | 1 + cmd/gog/tzdata_test.go | 37 +++++++++++++++++++++++++++++++++++ internal/cmd/testmain_test.go | 2 ++ internal/tzembed/embed.go | 5 +++++ 5 files changed, 73 insertions(+) create mode 100644 cmd/gog/tzdata_test.go create mode 100644 internal/tzembed/embed.go diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 28b236a4..aebdba0e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,6 +42,34 @@ jobs: - name: Test run: pnpm -C internal/tracking/worker test + windows: + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version-file: go.mod + cache: true + - name: Install tools + run: make tools + shell: bash + - name: Format check + run: make fmt-check + shell: bash + - name: Test + # Skip tests that depend on macOS Keychain / Linux keyring or Unix path semantics. + # These are covered by ubuntu-latest and macos-latest jobs. + # See https://github.com/steipete/gogcli/issues/395 + run: >- + go test ./... + -skip 'TestAuth|TestListClientCredentials|TestReadClientCredentials|TestConfigExists|TestExpandPath|TestResolveKeyringBackendInfo|TestLoadSecrets_LegacyFallback' + shell: bash + - name: Lint + run: make lint + shell: bash + - name: Build + run: go build ./cmd/gog + darwin-cgo-build: runs-on: macos-latest steps: diff --git a/cmd/gog/main.go b/cmd/gog/main.go index 154cc3c7..1f4f84ac 100644 --- a/cmd/gog/main.go +++ b/cmd/gog/main.go @@ -4,6 +4,7 @@ import ( "os" "github.com/steipete/gogcli/internal/cmd" + _ "github.com/steipete/gogcli/internal/tzembed" // Embed IANA timezone database for Windows support ) func main() { diff --git a/cmd/gog/tzdata_test.go b/cmd/gog/tzdata_test.go new file mode 100644 index 00000000..1e6e2e39 --- /dev/null +++ b/cmd/gog/tzdata_test.go @@ -0,0 +1,37 @@ +package main + +import ( + "testing" + "time" + + _ "github.com/steipete/gogcli/internal/tzembed" // Ensure tz database is embedded +) + +// TestEmbeddedTZData verifies that the time/tzdata import in main.go +// successfully embeds the IANA timezone database. On macOS/Linux this +// passes regardless, but on Windows (where Go has no system tz database) +// it validates the actual fix. The test also guards against accidental +// removal of the time/tzdata import. +func TestEmbeddedTZData(t *testing.T) { + zones := []string{ + "America/New_York", + "America/Los_Angeles", + "Europe/Berlin", + "Europe/London", + "Asia/Tokyo", + "Australia/Sydney", + "Pacific/Auckland", + "UTC", + } + + for _, zone := range zones { + loc, err := time.LoadLocation(zone) + if err != nil { + t.Errorf("time.LoadLocation(%q) failed: %v (is time/tzdata imported?)", zone, err) + continue + } + if loc == nil { + t.Errorf("time.LoadLocation(%q) returned nil location", zone) + } + } +} diff --git a/internal/cmd/testmain_test.go b/internal/cmd/testmain_test.go index 53329922..4c4baa0f 100644 --- a/internal/cmd/testmain_test.go +++ b/internal/cmd/testmain_test.go @@ -4,6 +4,8 @@ import ( "os" "path/filepath" "testing" + + _ "github.com/steipete/gogcli/internal/tzembed" // Embed IANA timezone database for Windows test support ) func TestMain(m *testing.M) { diff --git a/internal/tzembed/embed.go b/internal/tzembed/embed.go new file mode 100644 index 00000000..75345423 --- /dev/null +++ b/internal/tzembed/embed.go @@ -0,0 +1,5 @@ +// Package tzembed forces embedding of the IANA timezone database +// so time.LoadLocation works on Windows in both binaries and tests. +package tzembed + +import _ "time/tzdata" // Embeds IANA timezone database so time.LoadLocation works on Windows