Commit 1c94e4e

Eric Bower  ·  2026-08-09 11:16:59 -0400 EDT
parent 4fdd561
chore: checksum for local runs
3 files changed,  +58, -8
+52, -7
......@@ -424,10 +424,11 @@ type Workspace interface {
424424 }
425425
426426 type WorkspaceRsync struct {
427- Cfg *Cfg
428- Logger *slog.Logger
429- Source string
430- Dest string
427+ Cfg *Cfg
428+ Logger *slog.Logger
429+ Source string
430+ Dest string
431+ checksum string
431432 }
432433
433434 func (w *WorkspaceRsync) Setup() error {
......@@ -451,7 +452,18 @@ func (w *WorkspaceRsync) Setup() error {
451452 } else {
452453 cmd = exec.Command("rsync", "-rv", "--exclude=/.git", "--exclude=/.jj", w.Source+"/", w.Dest+"/")
453454 }
454- return runCmd(cmd, log)
455+ if err := runCmd(cmd, log); err != nil {
456+ return err
457+ }
458+
459+ cs, err := computeDirChecksum(w.Dest)
460+ if err != nil {
461+ log.Error("compute workspace checksum", "err", err)
462+ } else {
463+ w.checksum = cs
464+ log.Debug("workspace checksum", "checksum", w.checksum)
465+ }
466+ return nil
455467 }
456468
457469 func (w *WorkspaceRsync) Cleanup() error {
......@@ -466,7 +478,40 @@ func (w *WorkspaceRsync) GetDir() string {
466478 }
467479
468480 func (w *WorkspaceRsync) Checksum() string {
469- return ""
481+ return w.checksum
482+}
483+
484+func computeDirChecksum(dir string) (string, error) {
485+ hasher := sha256.New()
486+ err := filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
487+ if err != nil {
488+ return err
489+ }
490+ if d.IsDir() {
491+ return nil
492+ }
493+ rel, err := filepath.Rel(dir, path)
494+ if err != nil {
495+ return err
496+ }
497+ hasher.Write([]byte(rel))
498+ hasher.Write([]byte{0})
499+
500+ f, err := os.Open(path)
501+ if err != nil {
502+ return err
503+ }
504+ _, copyErr := io.Copy(hasher, f)
505+ _ = f.Close()
506+ if copyErr != nil {
507+ return copyErr
508+ }
509+ return nil
510+ })
511+ if err != nil {
512+ return "", err
513+ }
514+ return fmt.Sprintf("sha256:%x", hasher.Sum(nil)), nil
470515 }
471516
472517 type WorkspaceTar struct {
......@@ -700,7 +745,7 @@ func eventHandler(cfg *Cfg, eventData *Event) error {
700745 if eventData.Type != "" {
701746 domain = eventData.Type
702747 }
703- fmt.Fprintf(os.Stdout, "🚀 starting job %s.%s.%s\n", domain, eventData.Name, jobID) //nolint:errcheck
748+ fmt.Fprintf(os.Stdout, "🚀 starting job %s.%s.%s\n", domain, eventData.Name, jobID) //nolint:errcheck
704749 fmt.Fprintf(os.Stdout, " event: type=%s name=%s workspace=%s\n", eventData.Type, eventData.Name, eventData.Workspace) //nolint:errcheck
705750 fmt.Fprintf(os.Stdout, " %s\n", string(eventBytes)) //nolint:errcheck
706751
+5, -1
......@@ -851,5 +851,9 @@ func TestWorkspaceRsync_ExcludesGitAndJJ(t *testing.T) {
851851 if _, err := os.Stat(filepath.Join(destDir, ".jj")); !os.IsNotExist(err) {
852852 t.Error("expected .jj to be excluded from dest workspace")
853853 }
854-}
855854
855+ checksum := wk.Checksum()
856+ if !strings.HasPrefix(checksum, "sha256:") {
857+ t.Errorf("expected checksum to start with 'sha256:', got %q", checksum)
858+ }
859+}
+1, -0
......@@ -8,6 +8,7 @@ EVENT_TYPE="${PICI_EVENT:-manual}"
88
99 printf "\x1b[33m[%s:%s] running ci (event=%s)\x1b[0m\n" "$REPO" "$JOB_ID" "$EVENT_TYPE"
1010
11+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'
1112 zmx run lint -d docker run -t --rm -v "$(pwd):/app" -w /app golangci/golangci-lint:v2.11.4 golangci-lint run
1213 zmx run test -d docker run -t --rm -v "$(pwd):/app" -w /app golang:1.26 go test ./...
1314 zmx wait "*"