Skip to content

Commit 4f89478

Browse files
authored
feat: add CI/CD with GitHub Actions, GoReleaser, and Release Please (#1)
## Summary - Add test and lint workflows that run on PRs and pushes to main - Add Release Please for automated versioning based on conventional commits - Add GoReleaser for cross-platform CLI builds (linux/darwin × amd64/arm64) - Add Docker image builds published to `ghcr.io/defilan/issueparser` - Fix lint issues and update to Go 1.23 ## How it works 1. **On every PR/push to main**: tests and golangci-lint run 2. **When conventional commits merge to main**: Release Please opens a version bump PR 3. **When the Release Please PR merges**: GoReleaser builds binaries + Docker images and creates a GitHub release ## Files added - `.github/workflows/test.yml` - Test workflow - `.github/workflows/lint.yml` - Lint workflow - `.github/workflows/release-please.yml` - Release automation - `.goreleaser.yaml` - Cross-platform build config - `.golangci.yml` - Linter config - `release-please-config.json` / `.release-please-manifest.json` - Version tracking - `Dockerfile.goreleaser` - Minimal image for releases - `CLAUDE.md` - Developer guidance ## Test plan - [ ] Verify lint workflow passes - [ ] Verify test workflow passes - [ ] Merge and confirm Release Please opens a release PR
1 parent 116952b commit 4f89478

File tree

16 files changed

+466
-23
lines changed

16 files changed

+466
-23
lines changed

.github/workflows/lint.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: Lint
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
9+
jobs:
10+
lint:
11+
name: Run on Ubuntu
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Clone the code
15+
uses: actions/checkout@v4
16+
17+
- name: Setup Go
18+
uses: actions/setup-go@v5
19+
with:
20+
go-version-file: go.mod
21+
22+
- name: Run linter
23+
uses: golangci/golangci-lint-action@v8
24+
with:
25+
version: v2.1.6
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
name: Release Please
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
permissions:
9+
contents: write
10+
pull-requests: write
11+
packages: write
12+
13+
jobs:
14+
release-please:
15+
runs-on: ubuntu-latest
16+
outputs:
17+
release_created: ${{ steps.release.outputs.release_created }}
18+
tag_name: ${{ steps.release.outputs.tag_name }}
19+
version: ${{ steps.release.outputs.version }}
20+
steps:
21+
- name: Run Release Please
22+
id: release
23+
uses: googleapis/release-please-action@v4
24+
with:
25+
token: ${{ secrets.GITHUB_TOKEN }}
26+
config-file: release-please-config.json
27+
manifest-file: .release-please-manifest.json
28+
29+
goreleaser:
30+
needs: release-please
31+
if: ${{ needs.release-please.outputs.release_created == 'true' }}
32+
runs-on: ubuntu-latest
33+
steps:
34+
- name: Checkout code
35+
uses: actions/checkout@v4
36+
with:
37+
fetch-depth: 0
38+
39+
- name: Fetch all tags
40+
run: git fetch --force --tags
41+
42+
- name: Set up QEMU
43+
uses: docker/setup-qemu-action@v3
44+
45+
- name: Set up Docker Buildx
46+
uses: docker/setup-buildx-action@v3
47+
48+
- name: Log in to GitHub Container Registry
49+
uses: docker/login-action@v3
50+
with:
51+
registry: ghcr.io
52+
username: ${{ github.actor }}
53+
password: ${{ secrets.GITHUB_TOKEN }}
54+
55+
- name: Set up Go
56+
uses: actions/setup-go@v5
57+
with:
58+
go-version: '1.23'
59+
60+
- name: Run GoReleaser
61+
uses: goreleaser/goreleaser-action@v6
62+
with:
63+
distribution: goreleaser
64+
version: '~> v2'
65+
args: release --clean
66+
env:
67+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
68+
69+
- name: Upload artifacts
70+
uses: actions/upload-artifact@v4
71+
with:
72+
name: release-artifacts
73+
path: dist/*

.github/workflows/test.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: Tests
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
9+
jobs:
10+
test:
11+
name: Run on Ubuntu
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Clone the code
15+
uses: actions/checkout@v4
16+
17+
- name: Setup Go
18+
uses: actions/setup-go@v5
19+
with:
20+
go-version-file: go.mod
21+
22+
- name: Running Tests
23+
run: |
24+
go mod tidy
25+
make test

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ go.work.sum
2626
issue-analysis-report.md
2727
*.tar.gz
2828

29+
# GoReleaser
30+
dist/
31+
2932
# Local configuration
3033
.env
3134
.envrc

.golangci.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
version: "2"
2+
run:
3+
allow-parallel-runners: true
4+
linters:
5+
default: none
6+
enable:
7+
- copyloopvar
8+
- dupl
9+
- errcheck
10+
- goconst
11+
- gocyclo
12+
- govet
13+
- ineffassign
14+
- lll
15+
- misspell
16+
- nakedret
17+
- prealloc
18+
- revive
19+
- staticcheck
20+
- unconvert
21+
- unparam
22+
- unused
23+
settings:
24+
lll:
25+
line-length: 140
26+
revive:
27+
rules:
28+
- name: comment-spacings
29+
- name: import-shadowing
30+
exclusions:
31+
rules:
32+
# Allow longer lines in analyzer (LLM prompts)
33+
- linters:
34+
- lll
35+
path: internal/analyzer/
36+
formatters:
37+
enable:
38+
- gofmt
39+
- goimports

.goreleaser.yaml

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
# GoReleaser configuration for IssueParser
2+
# https://goreleaser.com/customization/
3+
4+
version: 2
5+
6+
before:
7+
hooks:
8+
- go mod tidy
9+
10+
builds:
11+
- id: issueparser
12+
main: ./cmd/issueparser
13+
binary: issueparser
14+
15+
# Build for Linux and macOS
16+
goos:
17+
- linux
18+
- darwin
19+
20+
goarch:
21+
- amd64
22+
- arm64
23+
24+
env:
25+
- CGO_ENABLED=0
26+
27+
ldflags:
28+
- -s -w
29+
30+
archives:
31+
- id: issueparser
32+
builds:
33+
- issueparser
34+
35+
name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
36+
37+
files:
38+
- LICENSE
39+
- README.md
40+
41+
checksum:
42+
name_template: "checksums.txt"
43+
algorithm: sha256
44+
45+
dockers:
46+
- id: issueparser-amd64
47+
goos: linux
48+
goarch: amd64
49+
ids:
50+
- issueparser
51+
image_templates:
52+
- "ghcr.io/defilan/issueparser:{{ .Version }}-amd64"
53+
- "ghcr.io/defilan/issueparser:latest-amd64"
54+
dockerfile: Dockerfile.goreleaser
55+
use: buildx
56+
build_flag_templates:
57+
- "--platform=linux/amd64"
58+
- "--label=org.opencontainers.image.created={{.Date}}"
59+
- "--label=org.opencontainers.image.title={{.ProjectName}}"
60+
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
61+
- "--label=org.opencontainers.image.version={{.Version}}"
62+
- "--label=org.opencontainers.image.source={{.GitURL}}"
63+
64+
- id: issueparser-arm64
65+
goos: linux
66+
goarch: arm64
67+
ids:
68+
- issueparser
69+
image_templates:
70+
- "ghcr.io/defilan/issueparser:{{ .Version }}-arm64"
71+
- "ghcr.io/defilan/issueparser:latest-arm64"
72+
dockerfile: Dockerfile.goreleaser
73+
use: buildx
74+
build_flag_templates:
75+
- "--platform=linux/arm64"
76+
- "--label=org.opencontainers.image.created={{.Date}}"
77+
- "--label=org.opencontainers.image.title={{.ProjectName}}"
78+
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
79+
- "--label=org.opencontainers.image.version={{.Version}}"
80+
- "--label=org.opencontainers.image.source={{.GitURL}}"
81+
82+
docker_manifests:
83+
- name_template: "ghcr.io/defilan/issueparser:{{ .Version }}"
84+
image_templates:
85+
- "ghcr.io/defilan/issueparser:{{ .Version }}-amd64"
86+
- "ghcr.io/defilan/issueparser:{{ .Version }}-arm64"
87+
88+
- name_template: "ghcr.io/defilan/issueparser:latest"
89+
image_templates:
90+
- "ghcr.io/defilan/issueparser:latest-amd64"
91+
- "ghcr.io/defilan/issueparser:latest-arm64"
92+
93+
snapshot:
94+
version_template: "{{ incpatch .Version }}-next"
95+
96+
changelog:
97+
sort: asc
98+
use: github
99+
100+
filters:
101+
exclude:
102+
- "^docs:"
103+
- "^test:"
104+
- "^ci:"
105+
- "^chore:"
106+
- "merge conflict"
107+
- Merge pull request
108+
- Merge remote-tracking branch
109+
- Merge branch
110+
111+
groups:
112+
- title: "New Features"
113+
regexp: "^feat:"
114+
order: 0
115+
- title: "Bug Fixes"
116+
regexp: "^fix:"
117+
order: 1
118+
- title: "Performance Improvements"
119+
regexp: "^perf:"
120+
order: 2
121+
- title: "Other Changes"
122+
order: 999
123+
124+
release:
125+
github:
126+
owner: defilan
127+
name: issueparser
128+
129+
name_template: "v{{.Version}}"
130+
131+
draft: false
132+
133+
replace_existing_draft: true
134+
135+
# Keep Release Please's changelog, just add assets
136+
mode: keep-existing
137+
138+
footer: |
139+
---
140+
141+
## Installation
142+
143+
### Docker
144+
```bash
145+
docker pull ghcr.io/defilan/issueparser:{{ .Version }}
146+
```
147+
148+
### Manual Download
149+
150+
**macOS**
151+
```bash
152+
# ARM64 (Apple Silicon)
153+
curl -L https://github.com/defilan/issueparser/releases/download/v{{ .Version }}/issueparser_{{ .Version }}_darwin_arm64.tar.gz | tar xz
154+
sudo mv issueparser /usr/local/bin/
155+
156+
# AMD64
157+
curl -L https://github.com/defilan/issueparser/releases/download/v{{ .Version }}/issueparser_{{ .Version }}_darwin_amd64.tar.gz | tar xz
158+
sudo mv issueparser /usr/local/bin/
159+
```
160+
161+
**Linux**
162+
```bash
163+
# AMD64
164+
curl -L https://github.com/defilan/issueparser/releases/download/v{{ .Version }}/issueparser_{{ .Version }}_linux_amd64.tar.gz | tar xz
165+
sudo mv issueparser /usr/local/bin/
166+
167+
# ARM64
168+
curl -L https://github.com/defilan/issueparser/releases/download/v{{ .Version }}/issueparser_{{ .Version }}_linux_arm64.tar.gz | tar xz
169+
sudo mv issueparser /usr/local/bin/
170+
```
171+
172+
### Verify Installation
173+
```bash
174+
issueparser --help
175+
```
176+
177+
metadata:
178+
mod_timestamp: "{{ .CommitTimestamp }}"

.release-please-manifest.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
".": "0.1.0"
3+
}

0 commit comments

Comments
 (0)