Skip to content

Commit b280629

Browse files
machado144claude
andcommitted
feat: adopt yankrun test strategy and improve project infrastructure
- Update module path to github.com/AxeForging/structlint - Refactor tests to use binary-first approach (buildBinary helper) - Update Makefile with cross-platform builds (9 OS/arch combos) - Add GitHub Actions workflows for tests and releases - Create docs/user/ with getting-started, configuration, CLI reference - Create docs/AI/ with codebase map, contributing guide, testing guide - Add lefthook.yml for pre-commit hooks (gofmt, govet, commitlint) - Update .structlint.yaml to allow .claude and .github directories Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 90fc886 commit b280629

32 files changed

Lines changed: 1931 additions & 319 deletions

.github/workflows/release.yml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
name: Release
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
tag:
7+
description: 'Release tag (e.g., v1.0.0)'
8+
required: true
9+
type: string
10+
11+
permissions:
12+
contents: write
13+
14+
jobs:
15+
release:
16+
runs-on: ubuntu-latest
17+
steps:
18+
- name: Checkout code
19+
uses: actions/checkout@v4
20+
with:
21+
fetch-depth: 0
22+
23+
- name: Setup Go
24+
uses: actions/setup-go@v5
25+
with:
26+
go-version: '1.24'
27+
cache: true
28+
29+
- name: Run tests
30+
run: go test ./... -v
31+
32+
- name: Build binaries for all platforms
33+
run: VERSION=${{ github.event.inputs.tag }} make build-all
34+
35+
- name: Create archives
36+
run: |
37+
cd dist
38+
for file in structlint-*; do
39+
if [[ "$file" == *.exe ]]; then
40+
# Windows: create zip
41+
base="${file%.exe}"
42+
zip "${base}.zip" "$file"
43+
rm "$file"
44+
else
45+
# Unix: create tar.gz
46+
tar -czvf "${file}.tar.gz" "$file"
47+
rm "$file"
48+
fi
49+
done
50+
ls -la
51+
52+
- name: Create GitHub Release
53+
uses: softprops/action-gh-release@v2
54+
with:
55+
tag_name: ${{ github.event.inputs.tag }}
56+
name: Release ${{ github.event.inputs.tag }}
57+
generate_release_notes: true
58+
draft: false
59+
prerelease: false
60+
files: |
61+
dist/*.tar.gz
62+
dist/*.zip

.github/workflows/test.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: Test
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
- master
8+
pull_request:
9+
branches:
10+
- main
11+
- master
12+
13+
jobs:
14+
test:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- name: Checkout code
18+
uses: actions/checkout@v4
19+
20+
- name: Setup Go
21+
uses: actions/setup-go@v5
22+
with:
23+
go-version: '1.24'
24+
cache: true
25+
26+
- name: Download dependencies
27+
run: go mod download
28+
29+
- name: Run tests
30+
run: go test ./... -v
31+
32+
- name: Build binary
33+
run: make build
34+
35+
- name: Self-validate
36+
run: ./bin/structlint validate --config .structlint.yaml
37+
38+
lint:
39+
runs-on: ubuntu-latest
40+
steps:
41+
- name: Checkout code
42+
uses: actions/checkout@v4
43+
44+
- name: Setup Go
45+
uses: actions/setup-go@v5
46+
with:
47+
go-version: '1.24'
48+
cache: true
49+
50+
- name: Run golangci-lint
51+
uses: golangci/golangci-lint-action@v6
52+
with:
53+
version: latest
54+
args: --timeout=5m

.structlint.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ dir_structure:
1111
- "scripts/**" # Build and utility scripts
1212
- "bin/**" # Built binaries
1313
- "dist/**" # Distribution files
14+
- ".claude/**" # Claude Code configuration
15+
- ".github/**" # GitHub configuration
1416
disallowedPaths:
1517
- "vendor/**" # Vendor dependencies
1618
- "node_modules/**" # Node.js dependencies

Makefile

Lines changed: 78 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,67 @@
11
SHELL := /usr/bin/env bash
22
APP := structlint
33
BIN := bin/$(APP)
4-
PKG := github.com/youngestaxe/structlint
4+
PKG := github.com/AxeForging/structlint
5+
DIST_DIR := dist
6+
7+
# Cross-compilation targets
8+
GOOS_ARCH := linux/amd64 linux/arm64 linux/386 linux/arm darwin/amd64 darwin/arm64 windows/amd64 windows/arm64 windows/386
9+
10+
# Version information - can be overridden by environment variable
11+
ifeq ($(origin VERSION), environment)
12+
# VERSION is set from environment
13+
else
14+
VERSION := $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
15+
endif
16+
17+
BUILD_TIME := $(shell date -u '+%Y-%m-%dT%H:%M:%SZ')
18+
GIT_COMMIT := $(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown")
19+
BUILT_BY := $(shell whoami)
20+
21+
# Build flags
522
LDFLAGS := -s -w \
6-
-X $(PKG)/internal/build.Version=$$(git describe --tags --always --dirty) \
7-
-X $(PKG)/internal/build.Commit=$$(git rev-parse --short HEAD) \
8-
-X $(PKG)/internal/build.Date=$$(date -u +%Y-%m-%dT%H:%M:%SZ) \
9-
-X $(PKG)/internal/build.BuiltBy=$$(whoami)
23+
-X $(PKG)/internal/build.Version=$(VERSION) \
24+
-X $(PKG)/internal/build.Commit=$(GIT_COMMIT) \
25+
-X $(PKG)/internal/build.Date=$(BUILD_TIME) \
26+
-X $(PKG)/internal/build.BuiltBy=$(BUILT_BY)
1027

11-
.PHONY: all build run test test-self lint tidy clean completion validate-self
28+
.PHONY: all build build-all run test test-self lint tidy clean completion validate-self fmt format check ci version tag release-check
1229

1330
all: build
1431

32+
# Build for current platform
1533
build:
1634
@mkdir -p bin
17-
GOFLAGS="-trimpath" CGO_ENABLED=0 go build -ldflags "$(LDFLAGS)" -o $(BIN) ./cmd/$(APP)
35+
CGO_ENABLED=0 go build -trimpath -ldflags "$(LDFLAGS)" -o $(BIN) ./cmd/$(APP)
36+
@echo "Built $(BIN) ($(VERSION))"
37+
38+
# Build for all platforms
39+
build-all:
40+
@echo "Building binaries for all platforms..."
41+
@echo "Version: $(VERSION)"
42+
@echo "Build time: $(BUILD_TIME)"
43+
@echo "Git commit: $(GIT_COMMIT)"
44+
@mkdir -p $(DIST_DIR)
45+
@for t in $(GOOS_ARCH); do \
46+
os=$${t%/*}; arch=$${t#*/}; \
47+
bin_name=$(APP)-$${os}-$${arch}; \
48+
if [ "$$os" = "windows" ]; then bin_name="$${bin_name}.exe"; fi; \
49+
bin_path=$(DIST_DIR)/$$bin_name; \
50+
echo " Building for $$os/$$arch..."; \
51+
CGO_ENABLED=0 GOOS=$$os GOARCH=$$arch go build -trimpath -ldflags "$(LDFLAGS)" -o $$bin_path ./cmd/$(APP); \
52+
done
53+
@echo "Build complete. Binaries in $(DIST_DIR)/"
1854

1955
run: build
2056
@$(BIN) $(ARGS)
2157

2258
test:
23-
go test ./...
59+
go test ./... -v
2460

2561
test-self: build
26-
@echo "🔍 Validating our own project structure..."
62+
@echo "Validating our own project structure..."
2763
@$(BIN) validate --config .structlint.yaml --json-output validation-report.json
28-
@echo "📊 Validation report saved to validation-report.json"
64+
@echo "Validation report saved to validation-report.json"
2965

3066
lint:
3167
golangci-lint run --timeout=5m
@@ -34,25 +70,49 @@ tidy:
3470
go mod tidy
3571

3672
clean:
37-
rm -rf bin validation-report.json
73+
rm -rf bin $(DIST_DIR) validation-report.json *.json
3874

39-
completion:
40-
@mkdir -p dist/completion
41-
@$(BIN) completion bash > dist/completion/$(APP).bash
42-
@$(BIN) completion zsh > dist/completion/_$(APP)
43-
@$(BIN) completion fish > dist/completion/$(APP).fish
75+
completion: build
76+
@mkdir -p $(DIST_DIR)/completion
77+
@$(BIN) completion bash > $(DIST_DIR)/completion/$(APP).bash
78+
@$(BIN) completion zsh > $(DIST_DIR)/completion/_$(APP)
79+
@$(BIN) completion fish > $(DIST_DIR)/completion/$(APP).fish
80+
@echo "Shell completions generated in $(DIST_DIR)/completion/"
4481

4582
validate-self: test-self
4683

4784
# Development helpers
4885
fmt:
4986
go fmt ./...
50-
goimports -w .
5187

5288
format: fmt
53-
gofumpt -w .
89+
@command -v gofumpt >/dev/null 2>&1 && gofumpt -w . || echo "gofumpt not installed, skipping"
90+
@command -v goimports >/dev/null 2>&1 && goimports -w . || echo "goimports not installed, skipping"
5491

5592
check: lint test
5693

5794
# CI/CD helpers
5895
ci: tidy check build test-self
96+
97+
# Version information
98+
version:
99+
@echo "Version: $(VERSION)"
100+
@echo "Build time: $(BUILD_TIME)"
101+
@echo "Git commit: $(GIT_COMMIT)"
102+
@echo "Built by: $(BUILT_BY)"
103+
104+
# Create a git tag for release
105+
tag:
106+
@if [ "$(VERSION)" = "dev" ]; then \
107+
echo "Error: Cannot tag dev version. Set VERSION env var (e.g., VERSION=v1.0.0 make tag)"; \
108+
exit 1; \
109+
fi
110+
@echo "Creating git tag: $(VERSION)"
111+
git tag -a $(VERSION) -m "Release $(VERSION)"
112+
@echo "Tag created. Push with: git push origin $(VERSION)"
113+
114+
# Build and test before release
115+
release-check: build-all
116+
@echo "Running tests..."
117+
go test ./... -v
118+
@echo "All tests passed. Ready for release $(VERSION)"

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

2828
```bash
2929
# Install
30-
go install github.com/youngestaxe/structlint@latest
30+
go install github.com/AxeForging/structlint@latest
3131

3232
# Create a basic config
3333
cat > .structlint.yaml << 'EOF'
@@ -166,7 +166,7 @@ After: "Create a new API handler following our .structlint.yaml structure:
166166
167167
```bash
168168
# Clone and build
169-
git clone https://github.com/youngestaxe/structlint.git
169+
git clone https://github.com/AxeForging/structlint.git
170170
cd structlint
171171
make build
172172

cmd/structlint/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
"context"
55
"os"
66

7-
"github.com/youngestaxe/structlint/internal/app"
7+
"github.com/AxeForging/structlint/internal/app"
88
)
99

1010
func main() {

0 commit comments

Comments
 (0)