From 1f523c4b2e5fcc73d826104d34703346e40ae0cf Mon Sep 17 00:00:00 2001 From: "David Muto (pseudomuto)" Date: Wed, 24 Sep 2025 07:06:14 -0400 Subject: [PATCH] Add Nix flake and GoReleaser configuration - Add Nix flake with Go 1.25, go-task, golangci-lint, and goreleaser - Configure GoReleaser for automated releases with changelog generation - Update CI to use Nix for reproducible builds across all jobs - Add release workflow triggered by version tags - Configure Dependabot for Go modules and GitHub Actions - Update taskfile to remove golangci-lint installation (provided by Nix) --- .github/dependabot.yml | 30 ++++++++++++++++ .github/workflows/ci.yml | 62 +++++++++++++++++++-------------- .github/workflows/release.yml | 30 ++++++++++++++++ .gitignore | 3 +- .goreleaser.yaml | 65 +++++++++++++++++++++++++++++++++++ flake.lock | 61 ++++++++++++++++++++++++++++++++ flake.nix | 61 ++++++++++++++++++++++++++++++++ go.mod | 2 +- taskfile.yaml | 28 +++++---------- 9 files changed, 295 insertions(+), 47 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/release.yml create mode 100644 .goreleaser.yaml create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..fbf7eb2 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,30 @@ +version: 2 +updates: + # Enable version updates for Go modules + - package-ecosystem: "gomod" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 10 + reviewers: + - "pseudomuto" + assignees: + - "pseudomuto" + commit-message: + prefix: "deps" + include: "scope" + + # Enable version updates for GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 5 + reviewers: + - "pseudomuto" + assignees: + - "pseudomuto" + commit-message: + prefix: "ci" + include: "scope" + diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5c1ea6e..c5b360c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,48 +9,58 @@ on: jobs: test: runs-on: ubuntu-latest - strategy: - matrix: - go-version: ["1.24", "1.25"] steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v5 - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: ${{ matrix.go-version }} - cache: true - - - name: Install Task - run: sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin + - name: Install Nix + uses: DeterminateSystems/nix-installer-action@v20 - - name: Download dependencies - run: go mod download + - name: Setup Nix cache + uses: DeterminateSystems/magic-nix-cache-action@v13 - name: Run tests - run: task test:ci + run: nix develop -c task test:ci - name: Upload coverage to Codecov - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@v5 with: file: ./coverage.out + flags: unittests + name: codecov-umbrella + fail_ci_if_error: false lint: + name: Lint runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v5 - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: "1.25" - cache: true + - name: Install Nix + uses: DeterminateSystems/nix-installer-action@v20 + + - name: Setup Nix cache + uses: DeterminateSystems/magic-nix-cache-action@v13 + + - name: Run linter + run: nix develop -c task lint + + build: + name: Build + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v5 - - name: Install Task - run: sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin + - name: Install Nix + uses: DeterminateSystems/nix-installer-action@v20 - - name: Run linting - run: task lint + - name: Setup Nix cache + uses: DeterminateSystems/magic-nix-cache-action@v13 + - name: Run GoReleaser (no publish) + run: nix develop -c task build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..7192a81 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,30 @@ +name: Release + +on: + push: + tags: + - "v*" + +permissions: + contents: write + packages: write + +jobs: + release: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v5 + with: + fetch-depth: 0 + + - name: Install Nix + uses: DeterminateSystems/nix-installer-action@v20 + + - name: Setup Nix cache + uses: DeterminateSystems/magic-nix-cache-action@v13 + + - name: Run GoReleaser + run: nix develop -c goreleaser release --clean + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index e660fd9..5ce0a9e 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -bin/ +.direnv/ +dist/ diff --git a/.goreleaser.yaml b/.goreleaser.yaml new file mode 100644 index 0000000..dc522db --- /dev/null +++ b/.goreleaser.yaml @@ -0,0 +1,65 @@ +version: 2 + +# Project metadata +project_name: where + +# Build configuration +builds: + - skip: true + +# Archive configuration +archives: + - id: default + ids: + - where + name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}" + files: + - LICENSE.txt + - README.md + +# Checksum configuration +checksum: + name_template: "checksums.txt" + +# Snapshot configuration +snapshot: + version_template: "{{ incpatch .Version }}-next" + +# Changelog configuration +changelog: + sort: asc + use: github + filters: + exclude: + - "^docs:" + - "^test:" + - "^ci:" + - "^build:" + - "^chore:" + groups: + - title: Features + regexp: "^.*feat[(\\w)]*:+.*$" + order: 0 + - title: Bug Fixes + regexp: "^.*fix[(\\w)]*:+.*$" + order: 1 + - title: Others + order: 999 + +# Release configuration +release: + github: + owner: pseudomuto + name: where + draft: false + prerelease: auto + name_template: "Release {{ .Version }}" + header: | + ## Where - A SQL where clause parser. + + ### Installation + + `go get github.com/pseudomuto/where` + + footer: | + **Full Changelog**: https://github.com/pseudomuto/where/compare/{{ .PreviousTag }}...{{ .Tag }} diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..5e5518e --- /dev/null +++ b/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1758446476, + "narHash": "sha256-5rdAi7CTvM/kSs6fHe1bREIva5W3TbImsto+dxG4mBo=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a1f79a1770d05af18111fbbe2a3ab2c42c0f6cd0", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..922dae6 --- /dev/null +++ b/flake.nix @@ -0,0 +1,61 @@ +{ + description = "Where - A SQL where clause parser"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = + { + self, + nixpkgs, + flake-utils, + }: + flake-utils.lib.eachSystem + [ + "x86_64-linux" + "aarch64-linux" + "x86_64-darwin" + "aarch64-darwin" + ] + ( + system: + let + pkgs = import nixpkgs { + inherit system; + config.allowUnfree = true; + }; + + # Pick language/tool versions here (adjust as you like) + go = pkgs.go_1_25; + + # Common build utils + buildUtils = with pkgs; [ + go-task + golangci-lint + goreleaser + ]; + in + { + # `nix develop` drops you into this shell + devShells.default = pkgs.mkShell { + packages = [ + go + buildUtils + ]; + + CGO_ENABLED = "0"; + + # Helpful prompt when you enter the shell + shellHook = '' + echo "▶ Dev shell ready on ${system}" + echo " Go: $(${go}/bin/go version)" + ''; + }; + + # `nix fmt` to format nix files in this repo + formatter = pkgs.nixfmt-tree; + } + ); +} diff --git a/go.mod b/go.mod index 27a7dbb..879f47b 100644 --- a/go.mod +++ b/go.mod @@ -4,12 +4,12 @@ go 1.24.4 require ( github.com/alecthomas/participle/v2 v2.1.1 + github.com/pkg/errors v0.9.1 github.com/stretchr/testify v1.9.0 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/taskfile.yaml b/taskfile.yaml index 5be1db5..e5b22fe 100644 --- a/taskfile.yaml +++ b/taskfile.yaml @@ -1,9 +1,5 @@ version: "3" -vars: - BIN_DIR: "bin" - LINT_VERSION: 2.1.6 - tasks: update: desc: Updates all dependencies @@ -12,17 +8,21 @@ tasks: cmds: - go mod tidy + build: + desc: Build a local snapshot with goreleaser + silent: true + cmds: + - "goreleaser release --snapshot --clean --skip=publish" + lint: desc: Run golangci-lint on the codebase - deps: [install:golangci-lint] silent: true - cmd: "{{.BIN_DIR}}/golangci-lint run {{.CLI_ARGS}}" + cmd: "golangci-lint run {{.CLI_ARGS}}" lint:fix: desc: Run golangci-lint --fix on the codebase - deps: [install:golangci-lint] silent: true - cmd: "{{.BIN_DIR}}/golangci-lint run --fix" + cmd: "golangci-lint run --fix" test: desc: Run the test suite (unit tests only) @@ -32,7 +32,7 @@ tasks: test:ci: desc: Run the test suite for CI with coverage profile silent: true - cmd: go test -v -race -coverprofile=coverage.out ./... + cmd: go test -v -coverprofile=coverage.out ./... tag: desc: Create and push a new signed tag for release @@ -74,13 +74,3 @@ tasks: vars: TAG: sh: git describe --tags --abbrev=0 2>/dev/null | awk -F. '{print $1+1".0.0"}' | sed 's/^v/v/' || echo "v1.0.0" - - install:golangci-lint: - internal: true - silent: true - status: - - test -f {{.BIN_DIR}}/golangci-lint - - "{{.BIN_DIR}}/golangci-lint --version | grep 'version {{.LINT_VERSION}}' >/dev/null" - vars: - URL: https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh - cmd: curl -sSfL {{.URL}} | sh -s -- -b {{.BIN_DIR}} v{{.LINT_VERSION}}