Skip to content

Commit 5f4045c

Browse files
Halehclaude
andcommitted
feat: release workflow, godoc, and --version flag
- Add .github/workflows/release.yml: builds cross-platform binaries (linux/darwin/windows × amd64/arm64) and publishes them to GitHub Releases whenever a vX.Y.Z tag is pushed - Add --version flag to CLI; version injected at build time via -ldflags "-X main.version=vX.Y.Z" - Add package-level doc comments to parser and rules packages - Add rules/doc.go listing all eight built-in rules Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 2a85aff commit 5f4045c

4 files changed

Lines changed: 94 additions & 0 deletions

File tree

.github/workflows/release.yml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
release:
13+
name: Build and publish
14+
runs-on: ubuntu-latest
15+
16+
strategy:
17+
matrix:
18+
include:
19+
- goos: linux
20+
goarch: amd64
21+
- goos: linux
22+
goarch: arm64
23+
- goos: darwin
24+
goarch: amd64
25+
- goos: darwin
26+
goarch: arm64
27+
- goos: windows
28+
goarch: amd64
29+
30+
steps:
31+
- uses: actions/checkout@v4
32+
33+
- uses: actions/setup-go@v5
34+
with:
35+
go-version: '1.21'
36+
cache: true
37+
38+
- name: Build binary
39+
env:
40+
GOOS: ${{ matrix.goos }}
41+
GOARCH: ${{ matrix.goarch }}
42+
CGO_ENABLED: '0'
43+
run: |
44+
EXT=""
45+
[ "$GOOS" = "windows" ] && EXT=".exe"
46+
OUTPUT="pgexplain-${{ github.ref_name }}-${GOOS}-${GOARCH}${EXT}"
47+
go build -trimpath -ldflags="-s -w -X main.version=${{ github.ref_name }}" \
48+
-o "$OUTPUT" ./cmd/pgexplain
49+
echo "ASSET=$OUTPUT" >> "$GITHUB_ENV"
50+
51+
- name: Upload binary to release
52+
uses: softprops/action-gh-release@v2
53+
with:
54+
files: ${{ env.ASSET }}
55+
generate_release_notes: true

cmd/pgexplain/main.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,24 @@ import (
2222
"github.com/Bright98/pgexplain/rules"
2323
)
2424

25+
// version is set at build time via -ldflags "-X main.version=vX.Y.Z".
26+
var version = "dev"
27+
2528
// valueColumn is the character position where field values start in text output.
2629
// It equals the width of the widest label prefix: " suggestion: " = 14.
2730
const valueColumn = 14
2831

2932
func main() {
3033
format := flag.String("format", "text", `Output format: "text" (default) or "json"`)
34+
showVersion := flag.Bool("version", false, "Print version and exit")
3135
flag.Usage = usage
3236
flag.Parse()
3337

38+
if *showVersion {
39+
fmt.Println(version)
40+
return
41+
}
42+
3443
data, err := readInput(flag.Args())
3544
if err != nil {
3645
fmt.Fprintf(os.Stderr, "pgexplain: %v\n", err)

parser/parser.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
// Package parser decodes the JSON produced by PostgreSQL's
2+
// EXPLAIN (FORMAT JSON) and EXPLAIN (ANALYZE, FORMAT JSON) commands
3+
// into a typed Go plan tree.
4+
//
5+
// The entry point is [Parse], which accepts the raw JSON bytes and returns
6+
// a [Plan] whose root node is a [Node]. Each Node may have child nodes in
7+
// its Plans slice, forming the full plan tree.
8+
//
9+
// Fields populated only when ANALYZE is used (ActualRows, ActualLoops,
10+
// HeapFetches, SortSpaceType, etc.) are exposed as pointers so callers can
11+
// distinguish "absent" from "zero".
112
package parser
213

314
import (

rules/doc.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Package rules provides built-in advisor rules for pgexplain.
2+
//
3+
// Each rule implements the [advisor.Rule] interface and is constructed via a
4+
// factory function (e.g. [SeqScan], [SortSpill]). Rules accept optional
5+
// functional options to override default thresholds.
6+
//
7+
// # Built-in rules
8+
//
9+
// - [SeqScan] — sequential scan on a large table
10+
// - [RowEstimateMismatch] — plan row estimate far from actual rows
11+
// - [HashJoinSpill] — hash join batch count > 1 (disk spill)
12+
// - [NestedLoopLarge] — nested-loop join over a large outer side
13+
// - [MissingIndexOnlyScan] — index-only scan with high heap-fetch ratio
14+
// - [SortSpill] — sort spilled to disk (external merge)
15+
// - [TopNHeapsort] — top-N heapsort over a full sequential scan
16+
// - [ParallelNotLaunched] — fewer parallel workers launched than planned
17+
//
18+
// All rules are safe for concurrent use.
19+
package rules

0 commit comments

Comments
 (0)