Reuse local asset verification during delivery uploads
This commit is contained in:
@@ -183,7 +183,7 @@ func Deliver(ctx context.Context, request Request) (Result, error) {
|
||||
result.Uncertain = assetIdentities(assets)
|
||||
return result, err
|
||||
}
|
||||
uploadResult, uploadErr := (gitea.Client{}).UploadMissing(ctx, request.Destination, releaseResult.Release.ID, inspection)
|
||||
uploadResult, uploadErr := (gitea.Client{}).UploadVerifiedMissing(ctx, request.Destination, releaseResult.Release.ID, inspection)
|
||||
result.Matching = uploadResult.Matching
|
||||
result.Uploaded = uploadResult.Uploaded
|
||||
result.Pending = uploadResult.Pending
|
||||
|
||||
@@ -68,6 +68,17 @@ func VerifyLocalAssets(assets []ExpectedAsset) error {
|
||||
// before the first write if any declared existing asset conflicts or cannot be
|
||||
// verified, and never replaces an existing attachment.
|
||||
func (c Client) UploadMissing(ctx context.Context, destination Destination, releaseID int64, inspection Inspection) (UploadResult, error) {
|
||||
return c.uploadMissing(ctx, destination, releaseID, inspection, true)
|
||||
}
|
||||
|
||||
// UploadVerifiedMissing uploads missing assets whose local contents have already
|
||||
// passed VerifyLocalAssets. It reuses that verification while retaining remote
|
||||
// inspection, conflict handling, and upload reconciliation.
|
||||
func (c Client) UploadVerifiedMissing(ctx context.Context, destination Destination, releaseID int64, inspection Inspection) (UploadResult, error) {
|
||||
return c.uploadMissing(ctx, destination, releaseID, inspection, false)
|
||||
}
|
||||
|
||||
func (c Client) uploadMissing(ctx context.Context, destination Destination, releaseID int64, inspection Inspection, verifyLocal bool) (UploadResult, error) {
|
||||
if releaseID <= 0 {
|
||||
return UploadResult{State: DeliveryPartial}, failure(FailureInvalid, "upload release assets", 0, errors.New("release ID must be positive"))
|
||||
}
|
||||
@@ -127,12 +138,14 @@ func (c Client) UploadMissing(ctx context.Context, destination Destination, rele
|
||||
missing[observation.Expected.Filename] = observation.Expected
|
||||
}
|
||||
}
|
||||
for _, item := range expected {
|
||||
if _, needsUpload := missing[item.Filename]; !needsUpload {
|
||||
continue
|
||||
}
|
||||
if err := verifyLocalAsset(item); err != nil {
|
||||
return result, err
|
||||
if verifyLocal {
|
||||
for _, item := range expected {
|
||||
if _, needsUpload := missing[item.Filename]; !needsUpload {
|
||||
continue
|
||||
}
|
||||
if err := verifyLocalAsset(item); err != nil {
|
||||
return result, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,31 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestUploadMissingVerifiesEveryMissingLocalFileBeforeWriting(t *testing.T) {
|
||||
fixture := &uploadFixture{files: make(map[string][]byte)}
|
||||
server := httptest.NewServer(fixture)
|
||||
defer server.Close()
|
||||
client := testClient(server)
|
||||
destination := testDestination(server.URL)
|
||||
assets := localAssets(t, []string{"alpha.bin", "beta.bin"})
|
||||
inspection, err := client.InspectAssets(t.Context(), destination, 10, assets)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
contents := readExpectedFile(t, assets[1])
|
||||
contents[0] ^= 0xff
|
||||
if err := os.WriteFile(assets[1].Path, contents, 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
result, err := client.UploadMissing(t.Context(), destination, 10, inspection)
|
||||
if err == nil || result.State != DeliveryPartial {
|
||||
t.Fatalf("upload = %#v, error = %v; want local verification failure", result, err)
|
||||
}
|
||||
if posts := fixture.postNames(); len(posts) != 0 {
|
||||
t.Fatalf("uploaded %v before rejecting local content", posts)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUploadMissingPartialFailureThenRerunOnlyMissingAssets(t *testing.T) {
|
||||
fixture := &uploadFixture{files: make(map[string][]byte), failName: "beta.bin"}
|
||||
server := httptest.NewServer(fixture)
|
||||
|
||||
Reference in New Issue
Block a user