Applied a more general bugfix to path-resolution issues in the archive stage
This commit is contained in:
@@ -125,7 +125,8 @@ func (archiveStage) Run(ctx context.Context, env *Env, m *manifest.Manifest) (*S
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("archive: collect run files: %w", err)
|
||||
}
|
||||
promotions, err := resolveArchivePromotions(workDir, env.Config.Pipeline.Archive.PromoteArtifacts)
|
||||
workDirCandidates := archiveSourceWorkDirs(env, m, workDir)
|
||||
promotions, err := resolveArchivePromotions(workDirCandidates, env.Config.Pipeline.Archive.PromoteArtifacts)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("archive: resolve promotion rules: %w", err)
|
||||
}
|
||||
@@ -330,21 +331,37 @@ func archiveBucket(env *Env, m *manifest.Manifest) string {
|
||||
return strings.TrimSpace(env.Config.Pipeline.Storage.S3.Bucket)
|
||||
}
|
||||
|
||||
func resolveArchivePromotions(workDir string, rules []config.ArchivePromotionRule) ([]archivePromotion, error) {
|
||||
func resolveArchivePromotions(workDirs []string, rules []config.ArchivePromotionRule) ([]archivePromotion, error) {
|
||||
if len(workDirs) == 0 {
|
||||
return nil, fmt.Errorf("at least one workdir candidate is required")
|
||||
}
|
||||
out := make([]archivePromotion, 0, len(rules))
|
||||
for _, rule := range rules {
|
||||
from := strings.TrimSpace(rule.From)
|
||||
to := strings.TrimSpace(rule.To)
|
||||
required := rule.Required == nil || *rule.Required
|
||||
|
||||
localPath, err := resolveWorkDirRelativePath(workDir, from)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("promotion from %q: %w", from, err)
|
||||
}
|
||||
info, err := os.Stat(localPath)
|
||||
exists := err == nil && !info.IsDir()
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return nil, fmt.Errorf("promotion source %q: %w", from, err)
|
||||
var (
|
||||
localPath string
|
||||
exists bool
|
||||
)
|
||||
for _, candidateRoot := range workDirs {
|
||||
resolvedPath, err := resolveWorkDirRelativePath(candidateRoot, from)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("promotion from %q: %w", from, err)
|
||||
}
|
||||
info, err := os.Stat(resolvedPath)
|
||||
if err == nil && !info.IsDir() {
|
||||
localPath = resolvedPath
|
||||
exists = true
|
||||
break
|
||||
}
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return nil, fmt.Errorf("promotion source %q: %w", from, err)
|
||||
}
|
||||
if localPath == "" {
|
||||
localPath = resolvedPath
|
||||
}
|
||||
}
|
||||
|
||||
out = append(out, archivePromotion{
|
||||
@@ -358,6 +375,33 @@ func resolveArchivePromotions(workDir string, rules []config.ArchivePromotionRul
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func archiveSourceWorkDirs(env *Env, m *manifest.Manifest, runWorkDir string) []string {
|
||||
candidates := make([]string, 0, 2)
|
||||
if strings.TrimSpace(runWorkDir) != "" {
|
||||
candidates = append(candidates, filepath.Clean(runWorkDir))
|
||||
}
|
||||
sessionID := strings.TrimSpace(env.Config.Session.SessionID)
|
||||
if sessionID == "" && m != nil {
|
||||
sessionID = strings.TrimSpace(m.SessionID)
|
||||
}
|
||||
if sessionID != "" {
|
||||
sessionWorkDir := filepath.Clean(artifacts.SessionWorkDir(env.Config.Pipeline.Workspace.Root, sessionID))
|
||||
if sessionWorkDir != "" {
|
||||
candidates = append(candidates, sessionWorkDir)
|
||||
}
|
||||
}
|
||||
seen := make(map[string]struct{}, len(candidates))
|
||||
out := make([]string, 0, len(candidates))
|
||||
for _, c := range candidates {
|
||||
if _, ok := seen[c]; ok {
|
||||
continue
|
||||
}
|
||||
seen[c] = struct{}{}
|
||||
out = append(out, c)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func resolveWorkDirRelativePath(workDir, rel string) (string, error) {
|
||||
rel = filepath.Clean(filepath.FromSlash(strings.TrimSpace(rel)))
|
||||
if rel == "." || rel == "" {
|
||||
|
||||
Reference in New Issue
Block a user