MCPcopy Create free account
hub / github.com/bytebase/bytebase / validateAndSanitizeReleaseFiles

Function validateAndSanitizeReleaseFiles

backend/api/v1/release_service.go:370–455  ·  view source on GitHub ↗

validateAndSanitizeReleaseFiles validates and sanitizes the release files inputs. It ensures that each file has either a sheet or a statement, and that the sheet is valid. It also checks for duplicate versions in versioned releases and sorts the files by version. The input files are modified in pla

(ctx context.Context, s *store.Store, files []*v1pb.Release_File, releaseType v1pb.Release_Type)

Source from the content-addressed store, hash-verified

368// If a sheet is provided, it populates the statement from the sheet.
369// If a statement is provided, it computes the sheetSha256 from the statement.
370func validateAndSanitizeReleaseFiles(ctx context.Context, s *store.Store, files []*v1pb.Release_File, releaseType v1pb.Release_Type) ([]*v1pb.Release_File, error) {
371 if len(files) == 0 {
372 return nil, errors.Errorf("release files cannot be empty")
373 }
374
375 versionSet := map[string]struct{}{}
376
377 for _, f := range files {
378 switch {
379 // Validate that either sheet or statement is provided
380 // For DECLARATIVE releases, empty content is allowed (represents dropping all objects)
381 case f.Sheet == "" && len(f.Statement) == 0:
382 if releaseType != v1pb.Release_DECLARATIVE {
383 return nil, errors.Errorf("either sheet or statement must be set for file %q", f.Path)
384 }
385 // For declarative releases with empty content, set empty statement and compute SHA256
386 f.Statement = []byte{}
387 h := sha256.Sum256(f.Statement)
388 f.SheetSha256 = hex.EncodeToString(h[:])
389 case f.Sheet != "" && len(f.Statement) > 0:
390 return nil, errors.Errorf("cannot set both sheet and statement for file %q", f.Path)
391
392 // If sheet is provided but statement is not, populate statement from sheet
393 case f.Sheet != "":
394 _, sheetSha256, err := common.GetProjectResourceIDSheetSha256(f.Sheet)
395 if err != nil {
396 return nil, errors.Wrapf(err, "failed to get sheet SHA256 from %q", f.Sheet)
397 }
398 sheet, err := s.GetSheetFull(ctx, sheetSha256)
399 if err != nil {
400 return nil, errors.Wrapf(err, "failed to get sheet %q", f.Sheet)
401 }
402 if sheet == nil {
403 return nil, errors.Errorf("sheet %q not found", f.Sheet)
404 }
405 // Sheets are now project-agnostic, no need to check projectID
406 f.Statement = []byte(sheet.Statement)
407 f.SheetSha256 = sheet.Sha256
408 case len(f.Statement) > 0:
409 // populate sheetSha256 from statement
410 h := sha256.Sum256(f.Statement)
411 f.SheetSha256 = hex.EncodeToString(h[:])
412 default:
413 }
414
415 // Version validation for versioned releases only.
416 // Declarative releases can have multiple files with the same version.
417 if releaseType == v1pb.Release_VERSIONED {
418 if _, ok := versionSet[f.Version]; ok {
419 return nil, errors.Errorf("found duplicate version %q", f.Version)
420 }
421 versionSet[f.Version] = struct{}{}
422 }
423 }
424
425 // Create files with additional parsed version data for sorting.
426 type fileWithVersion struct {
427 file *v1pb.Release_File

Callers 2

CreateReleaseMethod · 0.85
CheckReleaseMethod · 0.85

Calls 5

NewVersionFunction · 0.92
ErrorfMethod · 0.80
GetSheetFullMethod · 0.80
LessThanMethod · 0.80

Tested by

no test coverage detected