From 198ae9257914d8994804e4ceba824211fa01297b Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Mon, 25 May 2026 22:35:51 -0500 Subject: [PATCH] fix: generate per-file [filename].sha256 instead of single manifest Each release attachment now gets its own .sha256 checksum file (e.g. asset.zip.sha256) instead of a single checksums.sha256 manifest. Old .sha256 files are cleaned up before regenerating. Co-Authored-By: Claude Opus 4.6 (1M context) --- services/release/checksum.go | 49 ++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/services/release/checksum.go b/services/release/checksum.go index fd4f7ae0d5..38840ccdee 100644 --- a/services/release/checksum.go +++ b/services/release/checksum.go @@ -9,6 +9,7 @@ import ( "crypto/sha256" "fmt" "io" + "strings" repo_model "git.mokoconsulting.tech/MokoConsulting/MokoGitea/models/repo" "git.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/log" @@ -17,9 +18,8 @@ import ( ) // GenerateReleaseChecksums computes SHA256 checksums for all attachments -// on a release and adds a checksums.sha256 manifest file as an attachment. +// on a release and creates a [filename].sha256 file for each one. func GenerateReleaseChecksums(ctx context.Context, rel *repo_model.Release) error { - // Load attachments into rel.Attachments if err := repo_model.GetReleaseAttachments(ctx, rel); err != nil { return fmt.Errorf("GetReleaseAttachments: %w", err) } @@ -28,20 +28,19 @@ func GenerateReleaseChecksums(ctx context.Context, rel *repo_model.Release) erro return nil } - // Remove existing checksums file if present + // Remove existing .sha256 files for _, a := range rel.Attachments { - if a.Name == "checksums.sha256" { + if strings.HasSuffix(a.Name, ".sha256") { if err := repo_model.DeleteAttachment(ctx, a, true); err != nil { - log.Warn("Failed to delete old checksums.sha256: %v", err) + log.Warn("Failed to delete old %s: %v", a.Name, err) } - break } } - // Compute SHA256 for each attachment - var manifest bytes.Buffer + // Compute SHA256 for each non-checksum attachment and create individual .sha256 files + created := 0 for _, a := range rel.Attachments { - if a.Name == "checksums.sha256" { + if strings.HasSuffix(a.Name, ".sha256") { continue } @@ -59,24 +58,24 @@ func GenerateReleaseChecksums(ctx context.Context, rel *repo_model.Release) erro } fr.Close() - fmt.Fprintf(&manifest, "%x %s\n", h.Sum(nil), a.Name) + checksumContent := fmt.Sprintf("%x %s\n", h.Sum(nil), a.Name) + checksumReader := bytes.NewBufferString(checksumContent) + + checksumAttach := &repo_model.Attachment{ + RepoID: rel.RepoID, + ReleaseID: rel.ID, + Name: a.Name + ".sha256", + } + + if _, err := attachment_service.NewAttachment(ctx, checksumAttach, checksumReader, int64(len(checksumContent))); err != nil { + log.Warn("Failed to create %s: %v", checksumAttach.Name, err) + continue + } + created++ } - if manifest.Len() == 0 { - return nil + if created > 0 { + log.Info("Generated %d .sha256 checksum files for release %s (repo %d)", created, rel.TagName, rel.RepoID) } - - // Create the checksums.sha256 attachment - checksumAttach := &repo_model.Attachment{ - RepoID: rel.RepoID, - ReleaseID: rel.ID, - Name: "checksums.sha256", - } - - if _, err := attachment_service.NewAttachment(ctx, checksumAttach, &manifest, int64(manifest.Len())); err != nil { - return fmt.Errorf("create checksums.sha256 attachment: %w", err) - } - - log.Info("Generated checksums.sha256 for release %s (repo %d)", rel.TagName, rel.RepoID) return nil } -- 2.52.0