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  release:
105    desc: Create and push a new tag following semver
106    vars:
107      NEXT:
108        sh: svu next --always || go run github.com/caarlos0/svu/v3@latest next --always
109    prompt: "This will release {{.NEXT}}. Continue?"
110    preconditions:
111      - sh: '[ $(git symbolic-ref --short HEAD) = "main" ]'
112        msg: Not on main branch
113      - sh: "[ $(git status --porcelain=2 | wc -l) = 0 ]"
114        msg: "Git is dirty"
115    cmds:
116      - task: fetch-tags
117      - git commit --allow-empty -m "{{.NEXT}}"
118      - git tag --annotate --sign -m "{{.NEXT}}" {{.NEXT}} {{.CLI_ARGS}}
119      - echo "Pushing {{.NEXT}}..."
120      - git push origin main --follow-tags
121
122  fetch-tags:
123    cmds:
124      - git tag -d nightly || true
125      - git fetch --tags
126
127  release:fork:
128    desc: Create and push a fork release tag (combined workflow)
129    cmds:
130      - task: release:fork:tag
131      - task: release:fork:push
132
133  release:fork:tag:
134    desc: Create a fork release tag locally (without pushing)
135    vars:
136      UPSTREAM_VERSION:
137        sh: git describe --tags --abbrev=0 upstream/main 2>/dev/null || echo "v0.0.0"
138      EXISTING_FORK_TAGS:
139        sh: git tag -l "{{.UPSTREAM_VERSION}}-fork.*" | wc -l
140      NEXT_NUM:
141        sh: echo $(({{.EXISTING_FORK_TAGS}} + 1))
142      TAG: "{{.UPSTREAM_VERSION}}-fork.{{.NEXT_NUM}}"
143    prompt: "Create fork release {{.TAG}}?"
144    preconditions:
145      - sh: '[ $(git symbolic-ref --short HEAD) = "dev" ]'
146        msg: Not on dev branch
147      - sh: "[ $(git status --porcelain=2 | wc -l) = 0 ]"
148        msg: "Git is dirty"
149    cmds:
150      - git tag -d nightly || true
151      - git fetch upstream --tags
152      - >-
153        crush run "Please update the mentioned version in the top of the README to {{.TAG}}.
154        You only need to read the first 65 lines for the relevant bits.
155        Commit with 'docs(README): bump to [ver]' when you're done."
156      - git show --stat HEAD
157      - defer:
158          task: release:fork:cleanup
159          vars:
160            TAG: "{{.TAG}}"
161      - task: release:fork:confirm
162      - git tag -a {{.TAG}}
163      - echo "Tagged {{.TAG}} locally. Run 'task release:fork:push' to push."
164
165  release:fork:push:
166    desc: Push an existing fork release tag and notify module proxy
167    vars:
168      TAG:
169        sh: git describe --tags --abbrev=0 --match "*-fork.*" 2>/dev/null || echo ""
170    preconditions:
171      - sh: '[ -n "{{.TAG}}" ]'
172        msg: "No fork tag found. Run 'task release:fork:tag' first."
173      - sh: 'git tag -l "{{.TAG}}" | grep -q "{{.TAG}}"'
174        msg: "Tag {{.TAG}} does not exist locally"
175    prompt: "Push {{.TAG}} to remote and notify module proxy?"
176    cmds:
177      - git push soft {{.TAG}}
178      - echo "Released {{.TAG}}"
179      - go list -m git.secluded.site/crush@{{.TAG}} > /dev/null
180      - echo "Module proxy notified"
181
182  release:fork:confirm:
183    desc: Review LLM-generated commit and confirm release
184    internal: true
185    prompt: "Proceed with tagging?"
186
187  release:fork:cleanup:
188    desc: Undo LLM commit if release aborted
189    internal: true
190    cmds:
191      - git reset --hard HEAD~1
192      - git tag -d {{.TAG}} 2>/dev/null || true
193    status:
194      - git tag -l {{.TAG}} | grep -q {{.TAG}}