detached 6cbb6f5

ci: add Forgejo CI, lint config, self-check and GoReleaser release

commit
6cbb6f5f99670b5f77b967387eb22954e8d99192
author
brice · · 2026-10-08 05:44 UTC
parent
6122611
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
8 files · +170 -4
A .forgejo/workflows/ci.yml +39 -0
@@ -0,0 +1,39 @@
1+# CI for the Forgejo runner. Forgejo reads this directory instead of
2+# .github/workflows, so the GitHub mirror keeps its own CI.
3+name: CI
4+
5+on:
6+ push:
7+ branches: [main]
8+ pull_request:
9+
10+jobs:
11+ lint:
12+ name: Lint
13+ runs-on: ubuntu-latest
14+ steps:
15+ - uses: actions/checkout@v6
16+ - uses: actions/setup-go@v5
17+ with:
18+ go-version-file: go.mod
19+ cache: true
20+ - uses: golangci/golangci-lint-action@v9
21+ with:
22+ version: v2.14.0
23+
24+ test:
25+ name: Test
26+ runs-on: ubuntu-latest
27+ steps:
28+ - uses: actions/checkout@v6
29+ - uses: actions/setup-go@v5
30+ with:
31+ go-version-file: go.mod
32+ cache: true
33+ - name: Verify tidy
34+ run: |
35+ go mod tidy
36+ git diff --exit-code -- go.mod go.sum
37+ - run: go test -race ./...
38+ - name: Self-check
39+ run: go run ./cmd/hexcheck -fail-on warn ./...
@@ -0,0 +1,39 @@
1+# CI for the Forgejo runner. Forgejo reads this directory instead of
2+# .github/workflows, so the GitHub mirror keeps its own CI.
3+name: CI
4+
5+on:
6+ push:
7+ branches: [main]
8+ pull_request:
9+
10+jobs:
11+ lint:
12+ name: Lint
13+ runs-on: ubuntu-latest
14+ steps:
15+ - uses: actions/checkout@v6
16+ - uses: actions/setup-go@v5
17+ with:
18+ go-version-file: go.mod
19+ cache: true
20+ - uses: golangci/golangci-lint-action@v9
21+ with:
22+ version: v2.14.0
23+
24+ test:
25+ name: Test
26+ runs-on: ubuntu-latest
27+ steps:
28+ - uses: actions/checkout@v6
29+ - uses: actions/setup-go@v5
30+ with:
31+ go-version-file: go.mod
32+ cache: true
33+ - name: Verify tidy
34+ run: |
35+ go mod tidy
36+ git diff --exit-code -- go.mod go.sum
37+ - run: go test -race ./...
38+ - name: Self-check
39+ run: go run ./cmd/hexcheck -fail-on warn ./...
M .github/workflows/ci.yml +14 -1
@@ -6,6 +6,17 @@ on:
66 pull_request:
77
88 jobs:
9+ lint:
10+ runs-on: ubuntu-latest
11+ steps:
12+ - uses: actions/checkout@v4
13+ - uses: actions/setup-go@v5
14+ with:
15+ go-version-file: go.mod
16+ - uses: golangci/golangci-lint-action@v8
17+ with:
18+ version: v2.14.0
19+
920 test:
1021 runs-on: ubuntu-latest
1122 steps:
@@ -18,4 +29,6 @@ jobs:
1829 go mod tidy
1930 git diff --exit-code -- go.mod go.sum
2031 - name: Test
21- run: go test ./...
32+ run: go test -race ./...
33+ - name: Self-check
34+ run: go run ./cmd/hexcheck -fail-on warn ./...
@@ -6,6 +6,17 @@ on:
6 pull_request:6 pull_request:
7 7
8 jobs:8 jobs:
9+ lint:
10+ runs-on: ubuntu-latest
11+ steps:
12+ - uses: actions/checkout@v4
13+ - uses: actions/setup-go@v5
14+ with:
15+ go-version-file: go.mod
16+ - uses: golangci/golangci-lint-action@v8
17+ with:
18+ version: v2.14.0
19+
9 test:20 test:
10 runs-on: ubuntu-latest21 runs-on: ubuntu-latest
11 steps:22 steps:
@@ -18,4 +29,6 @@ jobs:
18 go mod tidy29 go mod tidy
19 git diff --exit-code -- go.mod go.sum30 git diff --exit-code -- go.mod go.sum
20 - name: Test31 - name: Test
21- run: go test ./...32+ run: go test -race ./...
33+ - name: Self-check
34+ run: go run ./cmd/hexcheck -fail-on warn ./...
A .github/workflows/release.yml +28 -0
@@ -0,0 +1,28 @@
1+name: Release
2+
3+on:
4+ push:
5+ tags:
6+ - 'v*'
7+
8+permissions:
9+ contents: write
10+
11+jobs:
12+ release:
13+ runs-on: ubuntu-latest
14+ steps:
15+ - uses: actions/checkout@v4
16+ with:
17+ fetch-depth: 0
18+ persist-credentials: false
19+ - uses: actions/setup-go@v5
20+ with:
21+ go-version-file: go.mod
22+ - uses: goreleaser/goreleaser-action@v6
23+ with:
24+ distribution: goreleaser
25+ version: "~> v2"
26+ args: release --clean
27+ env:
28+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,28 @@
1+name: Release
2+
3+on:
4+ push:
5+ tags:
6+ - 'v*'
7+
8+permissions:
9+ contents: write
10+
11+jobs:
12+ release:
13+ runs-on: ubuntu-latest
14+ steps:
15+ - uses: actions/checkout@v4
16+ with:
17+ fetch-depth: 0
18+ persist-credentials: false
19+ - uses: actions/setup-go@v5
20+ with:
21+ go-version-file: go.mod
22+ - uses: goreleaser/goreleaser-action@v6
23+ with:
24+ distribution: goreleaser
25+ version: "~> v2"
26+ args: release --clean
27+ env:
28+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
M .gitignore +2 -0
@@ -2,3 +2,5 @@ bin/
22 custom-gcl
33 coverage.out
44 .DS_Store
5+.worktrees/
6+dist/
@@ -2,3 +2,5 @@ bin/
2 custom-gcl2 custom-gcl
3 coverage.out3 coverage.out
4 .DS_Store4 .DS_Store
5+.worktrees/
6+dist/
A .golangci.yml +24 -0
@@ -0,0 +1,24 @@
1+version: "2"
2+
3+linters:
4+ enable:
5+ - errcheck
6+ - govet
7+ - ineffassign
8+ - misspell
9+ - staticcheck
10+ - unconvert
11+ - unused
12+ settings:
13+ errcheck:
14+ # CLI writes to stdout/stderr; a failed write has no useful recovery.
15+ exclude-functions:
16+ - fmt.Fprintf
17+ - fmt.Fprintln
18+ exclusions:
19+ paths:
20+ - analyzer/testdata
21+ rules:
22+ - path: _test\.go
23+ linters:
24+ - errcheck
@@ -0,0 +1,24 @@
1+version: "2"
2+
3+linters:
4+ enable:
5+ - errcheck
6+ - govet
7+ - ineffassign
8+ - misspell
9+ - staticcheck
10+ - unconvert
11+ - unused
12+ settings:
13+ errcheck:
14+ # CLI writes to stdout/stderr; a failed write has no useful recovery.
15+ exclude-functions:
16+ - fmt.Fprintf
17+ - fmt.Fprintln
18+ exclusions:
19+ paths:
20+ - analyzer/testdata
21+ rules:
22+ - path: _test\.go
23+ linters:
24+ - errcheck
A .goreleaser.yaml +34 -0
@@ -0,0 +1,34 @@
1+version: 2
2+
3+release:
4+ draft: true
5+ prerelease: auto
6+
7+builds:
8+ - id: hexcheck
9+ main: ./cmd/hexcheck
10+ binary: hexcheck
11+ goos: [linux, darwin, windows]
12+ goarch: [amd64, arm64]
13+ env:
14+ - CGO_ENABLED=0
15+ ldflags:
16+ - -s -w -X main.version={{.Version}}
17+
18+archives:
19+ - name_template: "{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}"
20+ formats: [tar.gz]
21+ format_overrides:
22+ - goos: windows
23+ formats: [zip]
24+
25+checksum:
26+ name_template: checksums.txt
27+
28+changelog:
29+ sort: asc
30+ filters:
31+ exclude:
32+ - "^docs"
33+ - "^test"
34+ - "^chore"
@@ -0,0 +1,34 @@
1+version: 2
2+
3+release:
4+ draft: true
5+ prerelease: auto
6+
7+builds:
8+ - id: hexcheck
9+ main: ./cmd/hexcheck
10+ binary: hexcheck
11+ goos: [linux, darwin, windows]
12+ goarch: [amd64, arm64]
13+ env:
14+ - CGO_ENABLED=0
15+ ldflags:
16+ - -s -w -X main.version={{.Version}}
17+
18+archives:
19+ - name_template: "{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}"
20+ formats: [tar.gz]
21+ format_overrides:
22+ - goos: windows
23+ formats: [zip]
24+
25+checksum:
26+ name_template: checksums.txt
27+
28+changelog:
29+ sort: asc
30+ filters:
31+ exclude:
32+ - "^docs"
33+ - "^test"
34+ - "^chore"
A .hexcheck.yaml +23 -0
@@ -0,0 +1,23 @@
1+# hexcheck checks its own layering: config is the core model, analyzer
2+# applies it, and cmd/golangci are the entrypoints.
3+version: 1
4+components:
5+ core:
6+ role: core
7+ paths:
8+ - config/**
9+ - internal/glob/**
10+ analyzer:
11+ role: usecase
12+ paths:
13+ - analyzer/**
14+ entrypoints:
15+ role: entrypoint
16+ paths:
17+ - cmd/**
18+ - golangci/**
19+ ignored:
20+ role: ignore
21+ paths:
22+ - analyzer/testdata/**
23+ - test/**
@@ -0,0 +1,23 @@
1+# hexcheck checks its own layering: config is the core model, analyzer
2+# applies it, and cmd/golangci are the entrypoints.
3+version: 1
4+components:
5+ core:
6+ role: core
7+ paths:
8+ - config/**
9+ - internal/glob/**
10+ analyzer:
11+ role: usecase
12+ paths:
13+ - analyzer/**
14+ entrypoints:
15+ role: entrypoint
16+ paths:
17+ - cmd/**
18+ - golangci/**
19+ ignored:
20+ role: ignore
21+ paths:
22+ - analyzer/testdata/**
23+ - test/**
M Makefile +6 -3
@@ -1,7 +1,7 @@
1-.PHONY: test lint tidy check smoke-local
1+.PHONY: test lint tidy self-check check smoke-local
22
33 test:
4- go test ./...
4+ go test -race ./...
55
66 lint:
77 golangci-lint run ./...
@@ -9,7 +9,10 @@ lint:
99 tidy:
1010 go mod tidy
1111
12-check: tidy test
12+self-check:
13+ go run ./cmd/hexcheck -fail-on warn ./...
14+
15+check: tidy lint test self-check
1316
1417 smoke-local:
1518 @if [ -z "$(HEXCHECK_SMOKE_REPO)" ]; then \
@@ -1,7 +1,7 @@
1-.PHONY: test lint tidy check smoke-local1+.PHONY: test lint tidy self-check check smoke-local
2 2
3 test:3 test:
4- go test ./...4+ go test -race ./...
5 5
6 lint:6 lint:
7 golangci-lint run ./...7 golangci-lint run ./...
@@ -9,7 +9,10 @@ lint:
9 tidy:9 tidy:
10 go mod tidy10 go mod tidy
11 11
12-check: tidy test12+self-check:
13+ go run ./cmd/hexcheck -fail-on warn ./...
14+
15+check: tidy lint test self-check
13 16
14 smoke-local:17 smoke-local:
15 @if [ -z "$(HEXCHECK_SMOKE_REPO)" ]; then \18 @if [ -z "$(HEXCHECK_SMOKE_REPO)" ]; then \

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 5

↑↓ moveenter openesc close