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
133 changes: 120 additions & 13 deletions .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
# Reusable: invoked by .github/workflows/ci.yml. Builds and tests
# across a Go-version matrix; SQLCipher's cgo build needs gcc and
# OpenSSL development headers, both already on ubuntu-latest runners.
# across OSes and Go versions. SQLCipher's cgo build needs only a C
# compiler and standard libs (no external OpenSSL — we use the
# vendored libtomcrypt crypto backend).
#
# Layout: one explicit job per OS rather than one matrix-on-OS job.
# GitHub Actions' run-page sidebar truncates per-matrix-instance names
# when the OS lives only in a matrix axis or include block; explicit
# top-level jobs each get their own sidebar entry with the full
# human-readable name. Pattern lifted from mattn/go-sqlite3's CI.
name: build-test

on:
Expand All @@ -11,40 +18,140 @@ permissions:
contents: read

jobs:
go:
name: go ${{ matrix.go }}
linux-x86_64:
name: Linux x86_64 (go ${{ matrix.go }})
runs-on: ubuntu-latest
timeout-minutes: 15
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
# `oldstable` and `stable` are setup-go aliases that always
# resolve to Go's two officially supported releases. As Go
# ships a new minor, the matrix tracks it without manual
# maintenance. The go directive in go.mod sets the actual
# minimum (currently 1.24).
go: ['oldstable', 'stable']
go: [oldstable, stable]
steps:
- name: Harden Runner
uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2
with:
egress-policy: audit

- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false

- name: Set up Go
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6
with:
go-version: ${{ matrix.go }}
- name: Build
env:
CGO_ENABLED: "1"
run: go build -trimpath ./...
- name: Vet
run: go vet ./...
- name: Test
env:
CGO_ENABLED: "1"
run: go test -race -count=1 ./...

linux-arm64:
name: Linux ARM64 (go ${{ matrix.go }})
runs-on: ubuntu-24.04-arm
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
go: [oldstable, stable]
steps:
- name: Harden Runner
uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2
with:
egress-policy: audit
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false
- name: Set up Go
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6
with:
go-version: ${{ matrix.go }}
- name: Build
env:
CGO_ENABLED: "1"
run: go build -trimpath ./...
- name: Vet
run: go vet ./...
- name: Test
env:
CGO_ENABLED: "1"
run: go test -race -count=1 ./...

macos-apple-silicon:
name: macOS Apple Silicon (go ${{ matrix.go }})
runs-on: macos-latest
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
go: [oldstable, stable]
steps:
- name: Harden Runner
uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2
with:
egress-policy: audit
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false
- name: Set up Go
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6
with:
go-version: ${{ matrix.go }}
- name: Build
env:
CGO_ENABLED: "1"
run: go build -trimpath ./...
- name: Vet
run: go vet ./...
- name: Test
env:
CGO_ENABLED: "1"
run: go test -race -count=1 ./...

windows-x86_64:
name: Windows x86_64 (go ${{ matrix.go }})
runs-on: windows-latest
timeout-minutes: 30
defaults:
run:
shell: 'msys2 {0}'
strategy:
fail-fast: false
matrix:
go: [oldstable, stable]
steps:
- name: Harden Runner
uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2
with:
egress-policy: audit
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false
- name: Set up MSYS2 + MinGW-w64
uses: msys2/setup-msys2@e9898307ac31d1a803454791be09ab9973336e1c # v2.31.1
with:
msystem: MINGW64
update: true
install: mingw-w64-x86_64-toolchain
path-type: inherit
- name: Set up Go
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6
with:
go-version: ${{ matrix.go }}
- name: Build
env:
CGO_ENABLED: "1"
run: go build -trimpath ./...
- name: Vet
run: go vet ./...
- name: Test
env:
CGO_ENABLED: "1"
run: go test -race -count=1 ./...
1 change: 1 addition & 0 deletions .typos.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ xeodou = "xeodou"
libtomcrypt = "libtomcrypt"
zetetic = "zetetic"
Zetetic = "Zetetic"
intoto = "intoto"

# Real names of contributors — not typos.
Linz = "Linz"
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,19 @@
> Self-contained Go driver for [SQLCipher](https://www.zetetic.net/sqlcipher/) — encrypted SQLite, audited, easy.

<p align="left">
<a href="https://github.com/WissCore/go-sqlcipher/releases/latest"><img src="https://img.shields.io/github/v/release/WissCore/go-sqlcipher?sort=semver&color=blue" alt="Latest release"></a>
<a href="LICENSE"><img src="https://img.shields.io/badge/license-BSD--3--Clause-blue" alt="License"></a>
<a href="https://pkg.go.dev/github.com/WissCore/go-sqlcipher/v4"><img src="https://pkg.go.dev/badge/github.com/WissCore/go-sqlcipher/v4.svg" alt="Go Reference"></a>
<a href="https://scorecard.dev/viewer/?uri=github.com/WissCore/go-sqlcipher"><img src="https://api.scorecard.dev/projects/github.com/WissCore/go-sqlcipher/badge" alt="OpenSSF Scorecard"></a>
<a href="SECURITY.md"><img src="https://img.shields.io/badge/security-policy-orange" alt="Security policy"></a>
</p>

<p align="left">
<a href="https://github.com/WissCore/go-sqlcipher/actions/workflows/ci.yml?query=branch%3Amain"><img src="https://img.shields.io/github/actions/workflow/status/WissCore/go-sqlcipher/ci.yml?branch=main&label=CI" alt="CI status"></a>
<img src="https://img.shields.io/badge/tested-Linux%20x64%20%7C%20Linux%20arm64%20%7C%20macOS%20%7C%20Windows-success" alt="Tested platforms">
<img src="https://img.shields.io/badge/Go-oldstable%20%7C%20stable-00ADD8?logo=go" alt="Go versions">
</p>

Maintained by [@alanwiss](https://github.com/alanwiss), who picked up
maintenance of this driver in 2026 after the upstream had been dormant
since 2020. See [`CONTRIBUTORS.md`](CONTRIBUTORS.md) for the full chain
Expand Down
91 changes: 91 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Release process

This project ships a tagged release whenever there is enough accumulated
work to be worth a version bump. The default cadence is roughly
**quarterly** (matching SQLCipher upstream), with patch releases in
between for security or correctness fixes.

## Release flow

```sh
./scripts/release.sh v4.15.1
```

The script enforces every safety check that a manual `git tag` could
forget:

1. The version argument matches `vX.Y.Z[-pre]`.
2. You are on `main` with a clean working tree.
3. The tag does not already exist locally or on `origin`.
4. `CHANGELOG.md` has an entry for the new version (or a non-empty
`[Unreleased]` section to promote).
5. The latest CI run on `main` is green.

After the dry-run summary, you confirm `y` and the script:

- Creates a signed annotated tag (`git tag -s`) on the current commit.
- Pushes the tag to `origin`.

The `sigstore-sign.yml` workflow takes over and produces:

- Source tarball (`go-sqlcipher-vX.Y.Z.tar.gz`)
- SBOM (`go-sqlcipher.spdx.json`)
- cosign signature (`go-sqlcipher-vX.Y.Z.sigstore.json`)
- SLSA provenance (`*.intoto.jsonl` via slsa-github-generator)

All four are uploaded to the GitHub Release page.

## Choosing the version bump

SemVer 2.0:

| Change kind | Bump |
|---|---|
| Bug fix, no public API change (Tier 1/2 lint cleanup, security patch) | PATCH (`v4.15.0` → `v4.15.1`) |
| New public API, backwards-compatible (e.g. new helper func) | MINOR (`v4.15.0` → `v4.16.0`) |
| Breaking public API change (rare for a fork) | MAJOR (`v4.x.y` → `v5.0.0`) |
| SQLCipher upstream bump (e.g. 4.15 → 4.16) | MINOR by default |

The `Conventional Commits` types in commit subjects map roughly to:

- `fix:` → PATCH
- `feat:` → MINOR
- `feat!:` or `BREAKING CHANGE:` footer → MAJOR
- `chore:` / `docs:` / `test:` / `refactor:` → no bump on their own

## CHANGELOG editing

`CHANGELOG.md` follows [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/).
The `[Unreleased]` section accumulates entries between releases. When
tagging, manually rename `## [Unreleased]` to `## [X.Y.Z] — YYYY-MM-DD`
and start a new empty `## [Unreleased]` block above it.

The release script does **not** modify `CHANGELOG.md` — keeping that
edit explicit makes the audit trail clear.

## After tagging

1. The Release page appears within ~5 minutes at
`https://github.com/WissCore/go-sqlcipher/releases/tag/vX.Y.Z`.
2. pkg.go.dev usually picks up the new version within ~15-30 minutes.
Force the fetch with:

```sh
GOPROXY=https://proxy.golang.org go list -m -versions github.com/WissCore/go-sqlcipher/v4
```

3. Update downstream `go.mod` files that pin to a specific version.

## Branch protection

`main` is protected:

- Requires the single composite check `ci-success` (which depends on the
full matrix of build-test jobs across Linux x86_64, Linux ARM64, macOS,
and Windows; plus security scans, DCO, etc.).
- Requires PRs (no direct pushes).
- Requires conventional-commits PR titles.
- Requires DCO sign-off on every commit.

Tags are only pushed by maintainers via the release script; we do not
auto-tag on merge.
Loading
Loading