package artifacts import ( "fmt" "strings" "gitea.maximumdirect.net/eric/narratio/internal/config" "gitea.maximumdirect.net/eric/narratio/internal/manifest" ) // ResolvePublishBucket resolves publish bucket identity with manifest-first precedence. func ResolvePublishBucket(cfg *config.Config, m *manifest.Manifest) string { if m != nil && strings.TrimSpace(m.S3Bucket) != "" { return strings.TrimSpace(m.S3Bucket) } if cfg == nil || cfg.Pipeline == nil || cfg.Pipeline.Storage.S3 == nil { return "" } return strings.TrimSpace(cfg.Pipeline.Storage.S3.Bucket) } // ResolvePublishSessionPrefix resolves publish session prefix with manifest-first precedence. func ResolvePublishSessionPrefix(cfg *config.Config, m *manifest.Manifest) (string, error) { if m != nil && strings.TrimSpace(m.S3SessionPrefix) != "" { return strings.TrimSpace(m.S3SessionPrefix), nil } if cfg == nil || cfg.Session == nil || cfg.Pipeline == nil { return "", fmt.Errorf("resolved config is required") } sessionID := strings.TrimSpace(cfg.Session.SessionID) if sessionID == "" && m != nil { sessionID = strings.TrimSpace(m.SessionID) } campaign := strings.TrimSpace(cfg.Session.Campaign) if campaign == "" && m != nil { campaign = strings.TrimSpace(m.Campaign) } if cfg.Pipeline.Storage.S3 == nil { return "", fmt.Errorf("pipeline.storage.s3 configuration is required") } if err := ValidateSessionIdentity(campaign, sessionID); err != nil { return "", err } sessionPrefix := S3SessionPrefix(cfg.Pipeline.Storage.S3.RootPrefix, campaign, sessionID) if strings.TrimSpace(sessionPrefix) == "" { return "", fmt.Errorf("session prefix is required") } return sessionPrefix, nil } // ResolvePublishRunPrefix resolves publish run prefix with manifest-first precedence. func ResolvePublishRunPrefix(cfg *config.Config, m *manifest.Manifest) (string, error) { if m != nil { runPrefix := strings.TrimSpace(m.S3RunPrefix) if runPrefix != "" { return runPrefix, nil } } sessionPrefix, err := ResolvePublishSessionPrefix(cfg, m) if err != nil { return "", err } runID := "" if m != nil { runID = strings.TrimSpace(m.RunID) } if runID == "" { return "", fmt.Errorf("run id is required") } if err := ValidateRunIdentity(runID); err != nil { return "", err } return S3RunPrefix(sessionPrefix, runID), nil } // ResolveCurrentStateKeys returns current pointer keys for a session prefix. func ResolveCurrentStateKeys(sessionPrefix string) (manifestKey, runIDKey string) { return S3CurrentManifestKey(sessionPrefix), S3CurrentRunPointerKey(sessionPrefix) }