Commit 1c94e4e
Eric Bower
·
2026-08-09 11:16:59 -0400 EDT
parent 4fdd561
chore: checksum for local runs
3 files changed,
+58,
-8
M
main.go
+52,
-7
1@@ -424,10 +424,11 @@ type Workspace interface {
2 }
3
4 type WorkspaceRsync struct {
5- Cfg *Cfg
6- Logger *slog.Logger
7- Source string
8- Dest string
9+ Cfg *Cfg
10+ Logger *slog.Logger
11+ Source string
12+ Dest string
13+ checksum string
14 }
15
16 func (w *WorkspaceRsync) Setup() error {
17@@ -451,7 +452,18 @@ func (w *WorkspaceRsync) Setup() error {
18 } else {
19 cmd = exec.Command("rsync", "-rv", "--exclude=/.git", "--exclude=/.jj", w.Source+"/", w.Dest+"/")
20 }
21- return runCmd(cmd, log)
22+ if err := runCmd(cmd, log); err != nil {
23+ return err
24+ }
25+
26+ cs, err := computeDirChecksum(w.Dest)
27+ if err != nil {
28+ log.Error("compute workspace checksum", "err", err)
29+ } else {
30+ w.checksum = cs
31+ log.Debug("workspace checksum", "checksum", w.checksum)
32+ }
33+ return nil
34 }
35
36 func (w *WorkspaceRsync) Cleanup() error {
37@@ -466,7 +478,40 @@ func (w *WorkspaceRsync) GetDir() string {
38 }
39
40 func (w *WorkspaceRsync) Checksum() string {
41- return ""
42+ return w.checksum
43+}
44+
45+func computeDirChecksum(dir string) (string, error) {
46+ hasher := sha256.New()
47+ err := filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
48+ if err != nil {
49+ return err
50+ }
51+ if d.IsDir() {
52+ return nil
53+ }
54+ rel, err := filepath.Rel(dir, path)
55+ if err != nil {
56+ return err
57+ }
58+ hasher.Write([]byte(rel))
59+ hasher.Write([]byte{0})
60+
61+ f, err := os.Open(path)
62+ if err != nil {
63+ return err
64+ }
65+ _, copyErr := io.Copy(hasher, f)
66+ _ = f.Close()
67+ if copyErr != nil {
68+ return copyErr
69+ }
70+ return nil
71+ })
72+ if err != nil {
73+ return "", err
74+ }
75+ return fmt.Sprintf("sha256:%x", hasher.Sum(nil)), nil
76 }
77
78 type WorkspaceTar struct {
79@@ -700,7 +745,7 @@ func eventHandler(cfg *Cfg, eventData *Event) error {
80 if eventData.Type != "" {
81 domain = eventData.Type
82 }
83- fmt.Fprintf(os.Stdout, "🚀 starting job %s.%s.%s\n", domain, eventData.Name, jobID) //nolint:errcheck
84+ fmt.Fprintf(os.Stdout, "🚀 starting job %s.%s.%s\n", domain, eventData.Name, jobID) //nolint:errcheck
85 fmt.Fprintf(os.Stdout, " event: type=%s name=%s workspace=%s\n", eventData.Type, eventData.Name, eventData.Workspace) //nolint:errcheck
86 fmt.Fprintf(os.Stdout, " %s\n", string(eventBytes)) //nolint:errcheck
87
+5,
-1
1@@ -851,5 +851,9 @@ func TestWorkspaceRsync_ExcludesGitAndJJ(t *testing.T) {
2 if _, err := os.Stat(filepath.Join(destDir, ".jj")); !os.IsNotExist(err) {
3 t.Error("expected .jj to be excluded from dest workspace")
4 }
5-}
6
7+ checksum := wk.Checksum()
8+ if !strings.HasPrefix(checksum, "sha256:") {
9+ t.Errorf("expected checksum to start with 'sha256:', got %q", checksum)
10+ }
11+}
M
pico.sh
+1,
-0
1@@ -8,6 +8,7 @@ EVENT_TYPE="${PICI_EVENT:-manual}"
2
3 printf "\x1b[33m[%s:%s] running ci (event=%s)\x1b[0m\n" "$REPO" "$JOB_ID" "$EVENT_TYPE"
4
5+zmx run fmt -d docker run -t --rm -v "$(pwd):/app" -w /app golang:1.26 bash -c 'files=$(gofmt -l .); if [ -n "$files" ]; then echo "unformatted files:"; echo "$files"; exit 1; fi'
6 zmx run lint -d docker run -t --rm -v "$(pwd):/app" -w /app golangci/golangci-lint:v2.11.4 golangci-lint run
7 zmx run test -d docker run -t --rm -v "$(pwd):/app" -w /app golang:1.26 go test ./...
8 zmx wait "*"