Commit 8316a06

Eric Bower  ·  2026-05-08 11:35:58 -0400 EDT
parent 4eaacc1
fix: published.json
1 files changed,  +11, -6
M main.go
+11, -6
 1@@ -1047,6 +1047,7 @@ func monitorTick(cfg *Cfg, log *slog.Logger, output io.Writer, jobStates map[str
 2 		if allCompleted(group) {
 3 			// Check sentinel — publish terminal status exactly once
 4 			sentinel := filepath.Join(cfg.ArtifactDir, name, jobID, "published.json")
 5+			log.Debug("checking completion", "all_completed", true, "sentinel", sentinel)
 6 			if _, err := os.Stat(sentinel); err == nil {
 7 				log.Debug("terminal status already published, skipping", "sentinel", sentinel)
 8 				continue
 9@@ -1075,11 +1076,10 @@ func monitorTick(cfg *Cfg, log *slog.Logger, output io.Writer, jobStates map[str
10 					log.Error("publish final status", "err", err)
11 				}
12 			}
13-			// Sync artifacts before writing sentinel — syncArtifacts skips jobs with published.json
14-			if err := syncJobArtifacts(cfg, name, jobID, log); err != nil {
15-				log.Error("sync artifacts", "err", err)
16-			}
17-			// Write sentinel so we don't re-publish on subsequent ticks
18+			// Write published.json, then sync to include it in the rsync.
19+			// syncArtifacts at end-of-tick will skip this job (has published.json),
20+			// so this is the only sync for completed jobs. In-progress jobs are
21+			// synced every tick by syncArtifacts (no published.json yet).
22 			published := map[string]interface{}{
23 				"status":      status,
24 				"exit_code":   exitCode,
25@@ -1087,9 +1087,13 @@ func monitorTick(cfg *Cfg, log *slog.Logger, output io.Writer, jobStates map[str
26 				"finished_at": time.Now().UTC().Format(time.RFC3339),
27 			}
28 			publishedJSON, _ := json.Marshal(published)
29+			log.Info("writing sentinel", "path", sentinel)
30 			if err := os.WriteFile(sentinel, publishedJSON, 0644); err != nil {
31 				log.Error("write published sentinel", "err", err)
32 			}
33+			if err := syncJobArtifacts(cfg, name, jobID, log); err != nil {
34+				log.Error("sync artifacts", "err", err)
35+			}
36 		} else {
37 			log.Debug("job still running", "sessions", len(group))
38 			// Publish running status only when --include-running is set
39@@ -1530,7 +1534,8 @@ func syncArtifacts(cfg *Cfg, log *slog.Logger) error {
40 			jobDir := filepath.Join(cfg.ArtifactDir, entry.Name(), repoEntry.Name())
41 			publishedPath := filepath.Join(jobDir, "published.json")
42 
43-			// Skip if already published (job is complete)
44+			// Skip if job is complete (published.json exists)
45+			// In-progress jobs are synced every tick; completed jobs are skipped.
46 			if _, err := os.Stat(publishedPath); err == nil {
47 				continue
48 			}