Commit 377fb0b

Eric Bower  ·  2026-05-08 15:29:38 -0400 EDT
parent 9772fc9
chore: sessions dir
2 files changed,  +22, -30
M main.go
+19, -27
 1@@ -1061,7 +1061,7 @@ func monitorTick(cfg *Cfg, log *slog.Logger, output io.Writer, jobStates map[str
 2 				log.Error("fetch history html", "session", s.Name, "err", err)
 3 				continue
 4 			}
 5-			if err := stageArtifact(cfg.ArtifactDir, name, jobID, s.Short, html, ".html"); err != nil {
 6+			if err := stageArtifact(cfg.ArtifactDir, name, jobID, filepath.Join("sessions", s.Short), html, ".html"); err != nil {
 7 				log.Error("stage html artifact", "session", s.Short, "err", err)
 8 			}
 9 
10@@ -1070,7 +1070,7 @@ func monitorTick(cfg *Cfg, log *slog.Logger, output io.Writer, jobStates map[str
11 				log.Error("fetch history plain", "session", s.Name, "err", err)
12 				continue
13 			}
14-			if err := stageArtifact(cfg.ArtifactDir, name, jobID, s.Short, plain, ".txt"); err != nil {
15+			if err := stageArtifact(cfg.ArtifactDir, name, jobID, filepath.Join("sessions", s.Short), plain, ".txt"); err != nil {
16 				log.Error("stage txt artifact", "session", s.Short, "err", err)
17 			}
18 		}
19@@ -1795,7 +1795,7 @@ func formatTimestamp(ts string) string {
20 
21 // generateJobIndex produces HTML and plain-text index pages listing all
22 // sessions for a job with links and metadata (status, exit code, ended at).
23-// It also includes any other artifacts in the job directory (e.g., event.json, workspace.tar).
24+// It also includes any other artifacts in the job directory (e.g., event.json, attestation.json, workspace.tar).
25 func generateJobIndex(artifactDir, name, jobID string, sessions []SessionInfo) (htmlContent, txtContent string) {
26 	rows := make([]sessionRow, 0, len(sessions))
27 	for _, s := range sessions {
28@@ -1819,35 +1819,27 @@ func generateJobIndex(artifactDir, name, jobID string, sessions []SessionInfo) (
29 		rows = append(rows, row)
30 	}
31 
32-	// Gather other artifacts in the job directory
33+	// Gather artifacts by scanning the job directory (excluding sessions/)
34 	var artifacts []artifactRow
35 	jobDir := filepath.Join(artifactDir, name, jobID)
36 
37-	// Always add workspace.tar (it's uploaded before pici runs)
38-	artifacts = append(artifacts, artifactRow{Name: "workspace.tar", Size: "—", ModTime: "—"})
39-
40-	// Add event.json if it exists
41-	eventJSON := filepath.Join(jobDir, "event.json")
42-	if info, err := os.Stat(eventJSON); err == nil {
43-		artifacts = append(artifacts, artifactRow{
44-			Name:    "event.json",
45-			Size:    formatFileSize(info.Size()),
46-			ModTime: formatTimestamp(fmt.Sprintf("%d", info.ModTime().Unix())),
47-		})
48-	}
49-
50-	// Add published.json if it exists
51-	publishedJSON := filepath.Join(jobDir, "published.json")
52-	if info, err := os.Stat(publishedJSON); err == nil {
53-		artifacts = append(artifacts, artifactRow{
54-			Name:    "published.json",
55-			Size:    formatFileSize(info.Size()),
56-			ModTime: formatTimestamp(fmt.Sprintf("%d", info.ModTime().Unix())),
57-		})
58+	if entries, err := os.ReadDir(jobDir); err == nil {
59+		for _, entry := range entries {
60+			if entry.IsDir() {
61+				continue // skip subdirectories (e.g. sessions/)
62+			}
63+			info, err := entry.Info()
64+			if err != nil {
65+				continue
66+			}
67+			artifacts = append(artifacts, artifactRow{
68+				Name:    entry.Name(),
69+				Size:    formatFileSize(info.Size()),
70+				ModTime: formatTimestamp(fmt.Sprintf("%d", info.ModTime().Unix())),
71+			})
72+		}
73 	}
74 
75-	// Skip zmx task artifacts (runner.html, runner.txt, etc.) — already in tasks table
76-
77 	// Resolve overall job status
78 	jobStatus := "success"
79 	hasRunning := false
M main_test.go
+3, -3
 1@@ -126,8 +126,8 @@ zmx run step2 echo "hello from step2"
 2 
 3 				// Track per-session artifacts
 4 				for _, s := range p.Sessions {
 5-					htmlPath := filepath.Join(artifactDir, p.Name, p.JobID, s.Short+".html")
 6-					txtPath := filepath.Join(artifactDir, p.Name, p.JobID, s.Short+".txt")
 7+					htmlPath := filepath.Join(artifactDir, p.Name, p.JobID, "sessions", s.Short+".html")
 8+					txtPath := filepath.Join(artifactDir, p.Name, p.JobID, "sessions", s.Short+".txt")
 9 					if _, err := os.Stat(htmlPath); err == nil {
10 						sessionArtifactShorts[s.Short+"_html"] = true
11 					}
12@@ -215,7 +215,7 @@ zmx run step2 echo "hello from step2"
13 
14 	// 8. Assert HTML artifacts were staged for each session
15 	for _, s := range finalPayload.Sessions {
16-		artifactPath := filepath.Join(cfg.ArtifactDir, finalPayload.Name, finalPayload.JobID, s.Short+".html")
17+		artifactPath := filepath.Join(cfg.ArtifactDir, finalPayload.Name, finalPayload.JobID, "sessions", s.Short+".html")
18 		data, err := os.ReadFile(artifactPath)
19 		if err != nil {
20 			t.Errorf("read artifact %s: %v", artifactPath, err)