1# https://taskfile.dev
2
3version: "3"
4
5vars:
6 VERSION:
7 sh: git describe --long 2>/dev/null || echo ""
8
9env:
10 CGO_ENABLED: 0
11 GOEXPERIMENT: greenteagc
12
13tasks:
14 lint:install:
15 desc: Install golangci-lint
16 cmds:
17 - go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest
18 env:
19 GOTOOLCHAIN: go1.25.0
20
21 lint:
22 desc: Run base linters
23 cmds:
24 - golangci-lint run --path-mode=abs --config=".golangci.yml" --timeout=5m
25 env:
26 GOEXPERIMENT: null
27
28 lint:fix:
29 desc: Run base linters and fix issues
30 cmds:
31 - golangci-lint run --path-mode=abs --config=".golangci.yml" --timeout=5m --fix
32 env:
33 GOEXPERIMENT: null
34
35 build:
36 desc: Run build
37 vars:
38 LDFLAGS: '{{if .VERSION}}-ldflags="-X git.secluded.site/crush/internal/version.Version={{.VERSION}}"{{end}}'
39 cmds:
40 - go build {{.LDFLAGS}} .
41 generates:
42 - crush
43
44 run:
45 desc: Run build
46 cmds:
47 - go run . {{.CLI_ARGS}}
48
49 test:
50 desc: Run tests
51 cmds:
52 - go test ./... {{.CLI_ARGS}}
53
54 test:record:
55 desc: Run tests and record all VCR cassettes again
56 aliases: [record]
57 cmds:
58 - rm -r internal/agent/testdata
59 - go test -v -count=1 -timeout=1h ./internal/agent
60
61 fmt:
62 desc: Run gofumpt
63 cmds:
64 - gofumpt -w .
65
66 dev:
67 desc: Run with profiling enabled
68 env:
69 CRUSH_PROFILE: true
70 cmds:
71 - go run .
72
73 install:
74 desc: Install the application
75 vars:
76 LDFLAGS: '{{if .VERSION}}-ldflags="-X git.secluded.site/crush/internal/version.Version={{.VERSION}}"{{end}}'
77 cmds:
78 - task: fetch-tags
79 - go install {{.LDFLAGS}} -v .
80
81 profile:cpu:
82 desc: 10s CPU profile
83 cmds:
84 - go tool pprof -http :6061 'http://localhost:6060/debug/pprof/profile?seconds=10'
85
86 profile:heap:
87 desc: Heap profile
88 cmds:
89 - go tool pprof -http :6061 'http://localhost:6060/debug/pprof/heap'
90
91 profile:allocs:
92 desc: Allocations profile
93 cmds:
94 - go tool pprof -http :6061 'http://localhost:6060/debug/pprof/allocs'
95
96 schema:
97 desc: Generate JSON schema for configuration
98 cmds:
99 - go run main.go schema > schema.json
100 - echo "Generated schema.json"
101 generates:
102 - schema.json
103
104 hyper:
105 desc: Update Hyper embedded provider.json
106 cmds:
107 - go generate ./internal/agent/hyper/...
108 generates:
109 - ./internal/agent/hyper/provider.json
110
111 release:
112 desc: Create and push a new tag following semver
113 vars:
114 NEXT:
115 sh: svu next --always || go run github.com/caarlos0/svu/v3@latest next --always
116 prompt: "This will release {{.NEXT}}. Continue?"
117 preconditions:
118 - sh: '[ $(git symbolic-ref --short HEAD) = "main" ]'
119 msg: Not on main branch
120 - sh: "[ $(git status --porcelain=2 | wc -l) = 0 ]"
121 msg: "Git is dirty"
122 cmds:
123 - task: fetch-tags
124 - git commit --allow-empty -m "{{.NEXT}}"
125 - git tag --annotate --sign -m "{{.NEXT}}" {{.NEXT}} {{.CLI_ARGS}}
126 - echo "Pushing {{.NEXT}}..."
127 - git push origin main --follow-tags
128
129 fetch-tags:
130 cmds:
131 - git tag -d nightly || true
132 - git fetch --tags
133
134 deps:
135 desc: Update Fantasy and Catwalk
136 cmds:
137 - go get charm.land/fantasy
138 - go get github.com/charmbracelet/catwalk
139 - go mod tidy
140
141 release:fork:
142 desc: Create and push a fork release tag (combined workflow)
143 cmds:
144 - task: release:fork:tag
145 - task: release:fork:push
146
147 release:fork:tag:
148 desc: Create a fork release tag locally (without pushing)
149 vars:
150 UPSTREAM_VERSION:
151 sh: git tag -l "v*" | sort -V | tail -1 || echo "v0.0.0"
152 EXISTING_FORK_TAGS:
153 sh: git tag -l "{{.UPSTREAM_VERSION}}-fork.*" | wc -l
154 NEXT_NUM:
155 sh: echo $(({{.EXISTING_FORK_TAGS}} + 1))
156 TAG: "{{.UPSTREAM_VERSION}}-fork.{{.NEXT_NUM}}"
157 prompt: "Create fork release {{.TAG}}?"
158 preconditions:
159 - sh: '[ $(git symbolic-ref --short HEAD) = "dev" ]'
160 msg: Not on dev branch
161 - sh: "[ $(git status --porcelain=2 | wc -l) = 0 ]"
162 msg: "Git is dirty"
163 cmds:
164 - git tag -d nightly || true
165 - git fetch upstream --tags
166 - >-
167 crush run "Please update the mentioned version in the top of the README to {{.TAG}}.
168 You only need to read the first 65 lines for the relevant bits.
169 Commit with 'docs(README): bump to [ver]' when you're done."
170 - git show --stat HEAD
171 - defer:
172 task: release:fork:cleanup
173 vars:
174 TAG: "{{.TAG}}"
175 - task: release:fork:confirm
176 - git push soft
177 - git tag -a {{.TAG}}
178 - echo "Tagged {{.TAG}} locally. Run 'task release:fork:push' to push."
179
180 release:fork:push:
181 desc: Push an existing fork release tag and notify module proxy
182 vars:
183 TAG:
184 sh: git describe --tags --abbrev=0 --match "*-fork.*" 2>/dev/null || echo ""
185 preconditions:
186 - sh: '[ -n "{{.TAG}}" ]'
187 msg: "No fork tag found. Run 'task release:fork:tag' first."
188 - sh: 'git tag -l "{{.TAG}}" | grep -q "{{.TAG}}"'
189 msg: "Tag {{.TAG}} does not exist locally"
190 prompt: "Push {{.TAG}} to remote and notify module proxy?"
191 cmds:
192 - git push soft {{.TAG}}
193 - echo "Released {{.TAG}}"
194 - go list -m git.secluded.site/crush@{{.TAG}} > /dev/null
195 - echo "Module proxy notified"
196
197 release:fork:confirm:
198 desc: Review LLM-generated commit and confirm release
199 internal: true
200 prompt: "Proceed with tagging?"
201
202 release:fork:cleanup:
203 desc: Undo LLM commit if release aborted
204 internal: true
205 cmds:
206 - git reset --hard HEAD~1
207 - git tag -d {{.TAG}} 2>/dev/null || true
208 status:
209 - git tag -l {{.TAG}} | grep -q {{.TAG}}