Bugfix involving path resolution in the archive stage
This commit is contained in:
@@ -18,6 +18,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type archiveStage struct{}
|
type archiveStage struct{}
|
||||||
|
type archiveUploadFile struct {
|
||||||
|
RelativePath string
|
||||||
|
LocalPath string
|
||||||
|
}
|
||||||
|
|
||||||
var archivePrerequisiteStages = []string{
|
var archivePrerequisiteStages = []string{
|
||||||
"prepare",
|
"prepare",
|
||||||
@@ -112,7 +116,12 @@ func (archiveStage) Run(ctx context.Context, env *Env, m *manifest.Manifest) (*S
|
|||||||
return nil, fmt.Errorf("archive: run id is required")
|
return nil, fmt.Errorf("archive: run id is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
runFiles, err := collectArchiveRunFiles(workDir)
|
manifestSource, err := resolveArchiveManifestSource(env, m, workDir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("archive: resolve manifest source: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
runFiles, err := collectArchiveRunFiles(workDir, manifestSource)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("archive: collect run files: %w", err)
|
return nil, fmt.Errorf("archive: collect run files: %w", err)
|
||||||
}
|
}
|
||||||
@@ -120,21 +129,13 @@ func (archiveStage) Run(ctx context.Context, env *Env, m *manifest.Manifest) (*S
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("archive: resolve promotion rules: %w", err)
|
return nil, fmt.Errorf("archive: resolve promotion rules: %w", err)
|
||||||
}
|
}
|
||||||
currentManifestSource := filepath.Join(workDir, "manifest.json")
|
|
||||||
if info, err := os.Stat(currentManifestSource); err != nil {
|
|
||||||
return nil, fmt.Errorf("archive: current manifest source %q: %w", currentManifestSource, err)
|
|
||||||
} else if info.IsDir() {
|
|
||||||
return nil, fmt.Errorf("archive: current manifest source %q is a directory", currentManifestSource)
|
|
||||||
}
|
|
||||||
|
|
||||||
runUploaded := make([]string, 0, len(runFiles))
|
runUploaded := make([]string, 0, len(runFiles))
|
||||||
for _, rel := range runFiles {
|
for _, file := range runFiles {
|
||||||
localPath := filepath.Join(workDir, filepath.FromSlash(rel))
|
key := artifacts.S3RunRelativeDestinationKey(runPrefix, file.RelativePath)
|
||||||
key := artifacts.S3RunRelativeDestinationKey(runPrefix, rel)
|
if _, err := env.ObjectStore.Upload(ctx, file.LocalPath, key, storage.UploadOptions{}); err != nil {
|
||||||
if _, err := env.ObjectStore.Upload(ctx, localPath, key, storage.UploadOptions{}); err != nil {
|
return nil, fmt.Errorf("archive: upload run file %q to %q: %w", file.RelativePath, key, err)
|
||||||
return nil, fmt.Errorf("archive: upload run file %q to %q: %w", rel, key, err)
|
|
||||||
}
|
}
|
||||||
runUploaded = append(runUploaded, rel)
|
runUploaded = append(runUploaded, file.RelativePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
promotedUploaded := make([]string, 0, len(promotions))
|
promotedUploaded := make([]string, 0, len(promotions))
|
||||||
@@ -375,8 +376,8 @@ func resolveWorkDirRelativePath(workDir, rel string) (string, error) {
|
|||||||
return cleanedFull, nil
|
return cleanedFull, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func collectArchiveRunFiles(workDir string) ([]string, error) {
|
func collectArchiveRunFiles(workDir, manifestPath string) ([]archiveUploadFile, error) {
|
||||||
files := make([]string, 0, 64)
|
files := make([]archiveUploadFile, 0, 64)
|
||||||
|
|
||||||
for _, dirName := range archiveRunUploadDirs {
|
for _, dirName := range archiveRunUploadDirs {
|
||||||
fullDir := filepath.Join(workDir, dirName)
|
fullDir := filepath.Join(workDir, dirName)
|
||||||
@@ -403,30 +404,72 @@ func collectArchiveRunFiles(workDir string) ([]string, error) {
|
|||||||
return fmt.Errorf("relative path from %q to %q: %w", workDir, path, err)
|
return fmt.Errorf("relative path from %q to %q: %w", workDir, path, err)
|
||||||
}
|
}
|
||||||
rel = filepath.ToSlash(rel)
|
rel = filepath.ToSlash(rel)
|
||||||
files = append(files, rel)
|
files = append(files, archiveUploadFile{
|
||||||
|
RelativePath: rel,
|
||||||
|
LocalPath: path,
|
||||||
|
})
|
||||||
return nil
|
return nil
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return nil, fmt.Errorf("walk %q: %w", fullDir, err)
|
return nil, fmt.Errorf("walk %q: %w", fullDir, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
manifestPath := filepath.Join(workDir, "manifest.json")
|
|
||||||
manifestInfo, err := os.Stat(manifestPath)
|
manifestInfo, err := os.Stat(manifestPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return nil, fmt.Errorf("manifest.json not found in workdir %q", workDir)
|
return nil, fmt.Errorf("manifest.json not found (checked path %q)", manifestPath)
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("stat %q: %w", manifestPath, err)
|
return nil, fmt.Errorf("stat %q: %w", manifestPath, err)
|
||||||
}
|
}
|
||||||
if manifestInfo.IsDir() {
|
if manifestInfo.IsDir() {
|
||||||
return nil, fmt.Errorf("manifest path %q is a directory", manifestPath)
|
return nil, fmt.Errorf("manifest path %q is a directory", manifestPath)
|
||||||
}
|
}
|
||||||
files = append(files, "manifest.json")
|
files = append(files, archiveUploadFile{
|
||||||
|
RelativePath: "manifest.json",
|
||||||
|
LocalPath: manifestPath,
|
||||||
|
})
|
||||||
|
|
||||||
sort.Strings(files)
|
sort.Slice(files, func(i, j int) bool {
|
||||||
|
return files[i].RelativePath < files[j].RelativePath
|
||||||
|
})
|
||||||
return files, nil
|
return files, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func resolveArchiveManifestSource(env *Env, m *manifest.Manifest, workDir string) (string, error) {
|
||||||
|
candidates := make([]string, 0, 3)
|
||||||
|
candidates = append(candidates, filepath.Join(workDir, "manifest.json"))
|
||||||
|
|
||||||
|
sessionID := strings.TrimSpace(env.Config.Session.SessionID)
|
||||||
|
if sessionID == "" && m != nil {
|
||||||
|
sessionID = strings.TrimSpace(m.SessionID)
|
||||||
|
}
|
||||||
|
if sessionID != "" {
|
||||||
|
sessionManifest := filepath.Join(artifacts.SessionWorkDir(env.Config.Pipeline.Workspace.Root, sessionID), "manifest.json")
|
||||||
|
candidates = append(candidates, sessionManifest)
|
||||||
|
}
|
||||||
|
|
||||||
|
seen := make(map[string]struct{}, len(candidates))
|
||||||
|
for _, candidate := range candidates {
|
||||||
|
clean := filepath.Clean(candidate)
|
||||||
|
if _, ok := seen[clean]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
seen[clean] = struct{}{}
|
||||||
|
info, err := os.Stat(clean)
|
||||||
|
if err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("stat %q: %w", clean, err)
|
||||||
|
}
|
||||||
|
if info.IsDir() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return clean, nil
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("manifest.json not found in run workdir or session workdir")
|
||||||
|
}
|
||||||
|
|
||||||
func writeCurrentManifestSnapshot(m *manifest.Manifest, archiveMetadata map[string]any) (string, error) {
|
func writeCurrentManifestSnapshot(m *manifest.Manifest, archiveMetadata map[string]any) (string, error) {
|
||||||
if m == nil {
|
if m == nil {
|
||||||
return "", fmt.Errorf("manifest is required")
|
return "", fmt.Errorf("manifest is required")
|
||||||
|
|||||||
Reference in New Issue
Block a user