package main import ( "fmt" "gitgud.io/mike/mpv-manager/pkg/releaseprovenance" ) // Apply mirrors only after the source artifacts have passed provenance checks. // The source URL remains in the lock as origin evidence; hashes never change. func applyReviewedDownloadURLs(release *Release, lock *releaseprovenance.Lock) error { if lock == nil { return nil } if err := lock.Validate(release.Version); err != nil { return err } assets := []struct { url *string hash string }{ {&release.Windows.X8664.URL, release.Windows.X8664.BLAKE3}, {&release.Windows.X8664v3.URL, release.Windows.X8664v3.BLAKE3}, {&release.Windows.Aarch64.URL, release.Windows.Aarch64.BLAKE3}, {&release.FFmpeg.X8664.URL, release.FFmpeg.X8664.BLAKE3}, {&release.FFmpeg.X8664v3.URL, release.FFmpeg.X8664v3.BLAKE3}, {&release.FFmpeg.Aarch64.URL, release.FFmpeg.Aarch64.BLAKE3}, {&release.MacOS.ARMLatest.URL, release.MacOS.ARMLatest.BLAKE3}, {&release.MacOS.ARM15.URL, release.MacOS.ARM15.BLAKE3}, {&release.MacOS.Intel15.URL, release.MacOS.Intel15.BLAKE3}, {&release.UOSC.URL, release.UOSC.BLAKE3}, {&release.UOSC.ConfURL, release.UOSC.ConfBLAKE3}, {&release.ModernZ.ScriptURL, release.ModernZ.ScriptBLAKE3}, {&release.ModernZ.FontURL, release.ModernZ.FontBLAKE3}, {&release.ModernZ.ConfURL, release.ModernZ.ConfBLAKE3}, {&release.MPCQT.X8664.URL, release.MPCQT.X8664.BLAKE3}, {&release.IINA.ARM.URL, release.IINA.ARM.BLAKE3}, {&release.IINA.Intel.URL, release.IINA.Intel.BLAKE3}, } used := make(map[string]bool) replacements := make(map[*string]string) for _, asset := range assets { artifact, ok := lock.ArtifactForURL(*asset.url) if !ok || artifact.DownloadURL == "" { continue } if asset.hash != artifact.BLAKE3 { return fmt.Errorf("mirror digest differs from verified artifact %s", artifact.ID) } replacements[asset.url] = artifact.DownloadURL used[artifact.URL] = true } for _, artifact := range lock.Artifacts { if artifact.DownloadURL != "" && !used[artifact.URL] { return fmt.Errorf("unused reviewed download URL for %s", artifact.ID) } } for target, replacement := range replacements { *target = replacement } return nil }