Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 97 additions & 24 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,115 @@ name: CI

on:
push:
branches: [ "main" ]
branches: [ "main", "release/**" ]
pull_request:
branches: [ "main" ]
branches: [ "main", "release/**" ]

# Cancel any in-progress run for the same branch when a new push arrives.
# This avoids wasting runner minutes on stale commits.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
# Single source of truth for the linter version.
# Using v2.x to natively support Go 1.25/1.26 toolchains.
GOLANGCI_LINT_VERSION: v2.10.1

permissions:
contents: read

jobs:
lint:
name: Lint & Hygiene
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache: true

- name: Install golangci-lint ${{ env.GOLANGCI_LINT_VERSION }}
run: |
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh \
| sh -s -- -b $(go env GOPATH)/bin ${{ env.GOLANGCI_LINT_VERSION }}

- name: Verify module metadata is tidy
run: |
go mod tidy
git diff --exit-code go.mod go.sum || {
echo "::error::go.mod or go.sum is out of sync. Run 'go mod tidy' locally."
exit 1
}

- name: Format check
run: |
$(go env GOPATH)/bin/golangci-lint fmt --diff || {
echo "::error::Formatting issues found. Run 'golangci-lint fmt' locally."
exit 1
}

- name: Run golangci-lint
run: |
$(go env GOPATH)/bin/golangci-lint run --timeout=5m

test:
name: Test
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
go-version: [ "1.24", "1.25" ]

go-version: [ "1.25", "1.26" ]
steps:
- uses: actions/checkout@v4
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: ${{ matrix.go-version }}
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go-version }}
cache: true

- name: Install dependencies
run: go mod download
- name: Verify dependencies
run: go mod verify

- name: Verify dependencies
run: go mod verify
- name: Run Tests with Coverage
run: go test -v -race -coverprofile=coverage.txt -covermode=atomic ./...

- name: Run Tests
run: go test -v -race -cover ./...
- name: Upload coverage
uses: actions/upload-artifact@v4
with:
name: coverage-report-${{ matrix.go-version }}
path: coverage.txt
retention-days: 5

lint:
build:
name: Build (Cross-Compile)
runs-on: ubuntu-latest
needs: [lint, test]
strategy:
fail-fast: false
matrix:
goos: [linux, darwin, windows]
goarch: [amd64, arm64]

steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v4
with:
go-version: '1.25'
- name: golangci-lint
uses: golangci/golangci-lint-action@v6
with:
version: latest
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache: true

- name: Verify compilation for ${{ matrix.goos }}/${{ matrix.goarch }}
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
run: go build -v ./...
61 changes: 61 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
version: "2"

# ── Run Options ─────────────────────────────────────────────────────────────
run:
timeout: 5m
tests: true # Re-enabling tests since this is a library and we want tests linted

# Prevents golangci-lint from modifying go.mod when loading packages.
# Equivalent to running with -mod=readonly. Important in CI.
modules-download-mode: readonly

# Resolve relative paths relative to the go.mod root.
# Produces cleaner, consistent output in CI and locally.
relative-path-mode: gomod

# ── Linters ──────────────────────────────────────────────────────────────────
linters:
# Explicitly opt in to only the linters below.
# All others are disabled. Plug-and-play: uncomment a linter here
# and CI will enforce it on the next push — no changes to ci.yml needed.
default: none

enable:
- govet # compiler-level checks (printf mismatches, unreachable code, etc.)
- ineffassign # detects assignments that are immediately overwritten
- unused # flags unused exported identifiers
- nolintlint # enforces correct usage of //nolint directives (no stale suppressions)
- staticcheck # full staticcheck suite (SA, ST, QF rules)
- errcheck # unhandled errors
- gosec # security analysis

settings:
nolintlint:
# Require a reason to be provided with every //nolint directive.
require-explanation: true
# Disallow blanket //nolint with no specific linter named.
allow-no-explanation: []
require-specific: true

# ── Formatters ───────────────────────────────────────────────────────────────
formatters:
# Driven by `golangci-lint fmt --diff` in CI.
# Adding a formatter here is the only change needed to enforce it everywhere.
disable-all: true
enable:
- gofmt
- goimports

settings:
gofmt:
simplify: true
goimports:
local-prefixes:
- github.com/JupiterMetaLabs/ion

# ── Issues ────────────────────────────────────────────────────────────────────
issues:
# Show every violation — never hide duplicates or cap per-linter counts.
# Developers should see the full picture in one run, not whack-a-mole.
max-issues-per-linter: 0
max-same-issues: 0
6 changes: 3 additions & 3 deletions examples/basic/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func example1_SimpleUsage() {
for _, w := range warnings {
log.Printf("ion warning: %v", w)
}
defer app.Sync()
defer func() { _ = app.Sync() }()

// Use Ion directly for logging
app.Info(ctx, "application started")
Expand All @@ -51,7 +51,7 @@ func example2_DependencyInjection() {
if err != nil {
log.Fatalf("Failed to create ion: %v", err)
}
defer app.Sync()
defer func() { _ = app.Sync() }()

// Pass a scoped child to components — preserves logging, tracing, and metrics
server := NewServer(app.Child("server"))
Expand Down Expand Up @@ -119,7 +119,7 @@ func example4_Metrics() {
if err != nil {
log.Fatalf("Failed to create ion: %v", err)
}
defer app.Shutdown(ctx)
defer func() { _ = app.Shutdown(ctx) }()

// Get a named meter
meter := app.Meter("example.metrics")
Expand Down
5 changes: 3 additions & 2 deletions examples/benchmark/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ import (
"testing"
"time"

"github.com/JupiterMetaLabs/ion"
"github.com/JupiterMetaLabs/ion/fields"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/trace/noop"

"github.com/JupiterMetaLabs/ion"
"github.com/JupiterMetaLabs/ion/fields"
)

func main() {
Expand Down
54 changes: 27 additions & 27 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
module github.com/JupiterMetaLabs/ion

go 1.24.0
go 1.25.0

require (
go.opentelemetry.io/contrib/bridges/otelzap v0.14.0
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0
go.opentelemetry.io/otel v1.39.0
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.15.0
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.15.0
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.39.0
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.39.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0
go.opentelemetry.io/otel/log v0.15.0
go.opentelemetry.io/otel/metric v1.39.0
go.opentelemetry.io/otel/sdk v1.39.0
go.opentelemetry.io/otel/sdk/log v0.15.0
go.opentelemetry.io/otel/sdk/metric v1.39.0
go.opentelemetry.io/otel/trace v1.39.0
go.opentelemetry.io/contrib/bridges/otelzap v0.17.0
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.67.0
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0
go.opentelemetry.io/otel v1.42.0
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.18.0
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.42.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0
go.opentelemetry.io/otel/log v0.18.0
go.opentelemetry.io/otel/metric v1.42.0
go.opentelemetry.io/otel/sdk v1.42.0
go.opentelemetry.io/otel/sdk/log v0.18.0
go.opentelemetry.io/otel/sdk/metric v1.42.0
go.opentelemetry.io/otel/trace v1.42.0
go.uber.org/zap v1.27.1
google.golang.org/grpc v1.77.0
google.golang.org/grpc v1.79.3
gopkg.in/natefinch/lumberjack.v2 v2.2.1
)

Expand All @@ -31,15 +31,15 @@ require (
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 // indirect
go.opentelemetry.io/proto/otlp v1.9.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 // indirect
go.opentelemetry.io/proto/otlp v1.10.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/net v0.47.0 // indirect
golang.org/x/sys v0.39.0 // indirect
golang.org/x/text v0.31.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect
google.golang.org/protobuf v1.36.10 // indirect
golang.org/x/net v0.52.0 // indirect
golang.org/x/sys v0.42.0 // indirect
golang.org/x/text v0.35.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7 // indirect
google.golang.org/protobuf v1.36.11 // indirect
)
Loading
Loading