Repository navigation
Expand file tree
/
Copy pathTaskfile.yml
More file actions
198 lines (179 loc) · 9.73 KB
/
Copy pathTaskfile.yml
File metadata and controls
198 lines (179 loc) · 9.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
version: '3'
# lich is a pure-Go binary (no CGO), the backend; its window is lich-native,
# a separate cgo binary out of native/ that lich launches from beside itself
# (docs/native-window.md). Linux first; Windows and macOS supported.
vars:
APP_NAME: "lich"
BIN_DIR: "bin"
# Package version follows the git tag (env VERSION overrides) — no manual bump.
# The tag is trimmed in the template, not with sed: Task's shell is mvdan/sh
# on every OS, and a plain Windows box has no sed on PATH — the pipeline would
# fail silently and stamp an empty version into the binary.
RAW_VERSION:
sh: echo "${VERSION:-$(git describe --tags --always 2>/dev/null)}"
VERSION: '{{trimPrefix "v" .RAW_VERSION}}'
# -X main.version stamps the git tag into the binary so the in-app update
# check knows what it is running (dev builds via `go run` stay "dev").
LDFLAGS: '-s -w -X main.version={{.VERSION}}'
GO_BUILD_FLAGS: '-trimpath -ldflags "{{.LDFLAGS}}"'
tasks:
build:
desc: Build the static backend binary into bin/
cmds:
# {{exeExt}}: `go build -o bin/lich` writes exactly that name — no .exe —
# and Windows then refuses to exec it (PATHEXT resolution needs the
# extension), so `task run` fails on the binary `task build` just made.
- cmd: CGO_ENABLED=0 go build {{.GO_BUILD_FLAGS}} -o {{.BIN_DIR}}/{{.APP_NAME}}{{exeExt}} .
build:native:
desc: Build the native window into bin/lich-native (cgo; libghostty-vt on PKG_CONFIG_PATH, native/slice.sh)
# Its own module and binary, built with cgo (docs/native-window.md); it
# never reaches the lich binary's build. The packages ship it beside lich,
# where lich looks for it.
dir: native
cmds:
- cmd: CGO_ENABLED=1 go build -trimpath -ldflags "-s -w" -o ../{{.BIN_DIR}}/lich-native ./cmd/lich-native
build:native:windows:
desc: Cross-build bin/lich-native.exe from Linux with Zig (native/build-windows.sh)
cmds:
- cmd: sh native/build-windows.sh ../{{.BIN_DIR}}/lich-native.exe
icons:windows:
desc: Regenerate the rsrc_windows_amd64.syso of lich.exe and lich-native.exe from build/windows/lich.ico
cmds:
# The .syso is the resource the Windows executable links, and it is the
# only source of the exe's icon: the Start Menu shortcut and the native
# file picker (an in-process COM dialog) both draw it. Nothing rebuilds
# it automatically, so a new lich.ico that skips this task ships an
# executable still wearing the previous mark. lich.ico itself comes out
# of build/appicon.py, with appicon.png and appicon-256.png.
- cmd: go run github.com/akavel/[email protected] -ico build/windows/lich.ico -arch amd64 -o rsrc_windows_amd64.syso
# The window's class icon, its title bar and taskbar button: Gio loads
# the first icon group, which rsrc writes at resource ID 1.
- cmd: go run github.com/akavel/[email protected] -ico build/windows/lich.ico -arch amd64 -o native/cmd/lich-native/rsrc_windows_amd64.syso
build:windows:
desc: Cross-compile the Windows binary
cmds:
# GUI subsystem: no console window rides along. stdout/stderr go
# nowhere — the persistent lich.log is the diagnostic surface.
- cmd: CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -trimpath -ldflags "{{.LDFLAGS}} -H=windowsgui" -o {{.BIN_DIR}}/{{.APP_NAME}}.exe .
build:mac:
desc: Cross-compile the macOS binaries
cmds:
# Both arches: Apple Silicon (arm64) and Intel (amd64). Pure Go, so both
# cross-compile from any host. Unsigned — Gatekeeper quarantines until
# notarization ships (INSTALL.md says what a user has to do about it).
- cmd: CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build {{.GO_BUILD_FLAGS}} -o {{.BIN_DIR}}/{{.APP_NAME}}-darwin-arm64 .
- cmd: CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build {{.GO_BUILD_FLAGS}} -o {{.BIN_DIR}}/{{.APP_NAME}}-darwin-amd64 .
bundle:mac:
desc: Wrap the macOS binary and the window in bin/Lich.app (macOS host only)
deps: [build:mac]
# The native window builds apart (cgo, libghostty-vt), as for package.
preconditions:
- sh: test -x {{.BIN_DIR}}/lich-native
msg: "bin/lich-native is missing: task build:native puts it there"
cmds:
# The binary cross-compiles from anywhere; the bundle needs Apple's sips
# and iconutil for the icon, so this task only runs on a Mac.
- cmd: build/darwin/bundle.sh {{.BIN_DIR}}/{{.APP_NAME}}-darwin-{{ARCH}} {{.VERSION}} {{.BIN_DIR}} {{.BIN_DIR}}/lich-native
run:
desc: Build and run
deps: [build, build:native]
cmds:
- cmd: ./{{.BIN_DIR}}/{{.APP_NAME}}{{exeExt}}
dev:
desc: Dev mode — the native window on a backend with its own DB and port
deps: [build:native]
cmds:
# Dev isolation: separate DB (LICH_DEV, store.databasePath) and listener
# port, so a daily-driver lich keeps running untouched; LICH_DEV also
# gives the window its own class, lichdev. go run leaves the binary in a
# temp dir, where nothing sits beside it; the pin names the window
# build:native made. The build reports "dev" unless VERSION is set:
# `VERSION=Unreleased task dev` is how the What's new dialog is smoked
# against the [Unreleased] changelog section, `VERSION=v0.44.0` against
# a release.
- cmd: LICH_DEV=1 LICH_LISTEN_PORT=47822 LICH_NATIVE="{{.ROOT_DIR}}/{{.BIN_DIR}}/lich-native" go run {{if env "VERSION"}}-ldflags "-X main.version={{.VERSION}}" {{end}}.
gallery:
desc: Build the UI kit gallery into bin/lich-gallery and open it (cgo, no libghostty-vt)
cmds:
- cmd: cd native && CGO_ENABLED=1 go build -trimpath -o ../{{.BIN_DIR}}/lich-gallery ./cmd/ui-gallery
- cmd: LICH_GALLERY="{{.ROOT_DIR}}/{{.BIN_DIR}}/lich-gallery" go run . gallery
test:
desc: Run the backend and native window suites (native needs libghostty-vt on PKG_CONFIG_PATH)
cmds:
- cmd: go test ./...
- cmd: cd native && go test ./...
pricing:refresh:
desc: Reprice internal/pricing/prices.json from LiteLLM — run it when cutting a release
cmds:
# The baked floor is what an offline install prices with, so it drifts from
# the day it ships. This only reprices the ids already in the file; which
# models the floor carries stays a hand-picked list.
- cmd: go run internal/pricing/genfloor.go
stats:
desc: Downloads per release and OS from GitHub Releases, the AUR package and clone traffic (needs gh)
preconditions:
- sh: command -v gh
msg: "gh is required: https://cli.github.com"
cmds:
# Downloads count installs and updates through the package's own asset; a
# Homebrew, Scoop or AUR update fetches the same files, so this is downloads,
# not people. Checksums and update manifests are left out of the count.
- cmd: |
gh api --paginate repos/lichdotdev/lich/releases --jq '
.[] | select(.prerelease | not)
| [.assets[] | select(.name | test("checksums|SHA256SUMS|\\.json$") | not)] as $a
| def os($re): [$a[] | select(.name | test($re)) | .download_count] | add // 0;
[.tag_name, .published_at[:10], os("."), os("linux|\\.deb$|\\.rpm$|pkg\\.tar"), os("windows"), os("darwin")]
| @tsv' | awk 'BEGIN { print "release\tdate\ttotal\tlinux\twindows\tmac" } { print; t += $3 } END { print "all\t\t" t }' | column -t
- cmd: |
curl -fsS 'https://aur.archlinux.org/rpc/v5/info?arg[]=lich-bin' | jq -r '.results[] | "AUR \(.Name) \(.Version): \(.NumVotes) votes, popularity \(.Popularity)"'
# GitHub keeps only the last 14 days and needs push access to the repo.
# Every CI checkout is a clone too, so the totals lean on our own runs.
- cmd: |
gh api repos/lichdotdev/lich/traffic/clones --jq '"Clones, last 14 days: \(.count) total, \(.uniques) unique", (.clones[] | " \(.timestamp[:10]) \(.count) \(.uniques) unique")'
mutation:
desc: Mutation tests via gremlins — .gremlins.yaml, scope with -- ./internal/pkg/
preconditions:
- sh: command -v gremlins
msg: "gremlins is required: go install github.com/go-gremlins/gremlins/cmd/gremlins@latest"
cmds:
# No path → whole module (slow: single-worker, terminal spawns real PTYs).
# Scope a run with: task mutation -- ./internal/store/
- cmd: gremlins unleash {{.CLI_ARGS}}
package:
desc: Build the Linux packages (deb, rpm, archlinux)
deps: [build]
# The native window builds apart (cgo), in CI on an older glibc than a
# developer's machine: it is put in bin/ first, not rebuilt here.
preconditions:
- sh: test -x {{.BIN_DIR}}/lich-native
msg: "bin/lich-native is missing: task build:native puts it there"
cmds:
- task: package:nfpm
vars: { FORMAT: deb, TARGET: '{{.APP_NAME}}.deb' }
- task: package:nfpm
vars: { FORMAT: rpm, TARGET: '{{.APP_NAME}}.rpm' }
- task: package:nfpm
vars: { FORMAT: archlinux, TARGET: '{{.APP_NAME}}.pkg.tar.zst' }
package:windows:
desc: Build bin/lich-setup.exe with the window inside (needs Inno Setup 6, on Windows)
deps: [build:windows]
preconditions:
- sh: command -v iscc
msg: "iscc (Inno Setup 6) is required — on Windows: choco install innosetup"
- sh: test -f {{.BIN_DIR}}/lich-native.exe
msg: "bin/lich-native.exe is missing: task build:native:windows cross-builds it from Linux"
env:
VERSION: '{{.VERSION}}'
cmds:
- cmd: iscc build/windows/lich.iss
package:nfpm:
internal: true
preconditions:
- sh: command -v nfpm
msg: "nfpm is required: go install github.com/goreleaser/nfpm/v2/cmd/nfpm@latest"
env:
VERSION: '{{.VERSION}}'
GOARCH: amd64
cmds:
- cmd: nfpm package -f build/linux/nfpm/nfpm.yaml -p {{.FORMAT}} -t {{.BIN_DIR}}/{{.TARGET}}