Taskfile.yaml

  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}}