mirror of https://github.com/go-gitea/gitea.git
Merge bed592c075 into a440116a16
commit
f0fd730d71
@ -0,0 +1,6 @@
|
|||||||
|
-
|
||||||
|
id: 1
|
||||||
|
owner_id: 2
|
||||||
|
type: maven
|
||||||
|
name: com.gitea:test-project
|
||||||
|
lower_name: com.gitea:test-project
|
||||||
@ -0,0 +1,88 @@
|
|||||||
|
-
|
||||||
|
id: 1
|
||||||
|
size: 14
|
||||||
|
hash_md5: 27224a672372115e5a1d125ed7b2a0b1
|
||||||
|
hash_sha1: 9854582a2958b2d31541ce4a6a1a36201b80c01
|
||||||
|
hash_sha256: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a01
|
||||||
|
hash_sha512: ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a801
|
||||||
|
created_unix: 1672531200
|
||||||
|
-
|
||||||
|
id: 2
|
||||||
|
size: 14
|
||||||
|
hash_md5: 27224a672372115e5a1d125ed7b2a0b2
|
||||||
|
hash_sha1: 9854582a2958b2d31541ce4a6a1a36201b80c02
|
||||||
|
hash_sha256: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a02
|
||||||
|
hash_sha512: ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a802
|
||||||
|
created_unix: 1672531200
|
||||||
|
-
|
||||||
|
id: 3
|
||||||
|
size: 14
|
||||||
|
hash_md5: 27224a672372115e5a1d125ed7b2a0b3
|
||||||
|
hash_sha1: 9854582a2958b2d31541ce4a6a1a36201b80c03
|
||||||
|
hash_sha256: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a03
|
||||||
|
hash_sha512: ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a803
|
||||||
|
created_unix: 1672531200
|
||||||
|
-
|
||||||
|
id: 4
|
||||||
|
size: 14
|
||||||
|
hash_md5: 27224a672372115e5a1d125ed7b2a0b4
|
||||||
|
hash_sha1: 9854582a2958b2d31541ce4a6a1a36201b80c04
|
||||||
|
hash_sha256: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a04
|
||||||
|
hash_sha512: ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a804
|
||||||
|
created_unix: 1672531200
|
||||||
|
-
|
||||||
|
id: 5
|
||||||
|
size: 14
|
||||||
|
hash_md5: 27224a672372115e5a1d125ed7b2a0b5
|
||||||
|
hash_sha1: 9854582a2958b2d31541ce4a6a1a36201b80c05
|
||||||
|
hash_sha256: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a05
|
||||||
|
hash_sha512: ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a805
|
||||||
|
created_unix: 1672531200
|
||||||
|
-
|
||||||
|
id: 6
|
||||||
|
size: 14
|
||||||
|
hash_md5: 27224a672372115e5a1d125ed7b2a0b6
|
||||||
|
hash_sha1: 9854582a2958b2d31541ce4a6a1a36201b80c06
|
||||||
|
hash_sha256: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a06
|
||||||
|
hash_sha512: ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a806
|
||||||
|
created_unix: 1672531200
|
||||||
|
-
|
||||||
|
id: 7
|
||||||
|
size: 14
|
||||||
|
hash_md5: 27224a672372115e5a1d125ed7b2a0b7
|
||||||
|
hash_sha1: 9854582a2958b2d31541ce4a6a1a36201b80c07
|
||||||
|
hash_sha256: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a07
|
||||||
|
hash_sha512: ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a807
|
||||||
|
created_unix: 1672531200
|
||||||
|
-
|
||||||
|
id: 8
|
||||||
|
size: 14
|
||||||
|
hash_md5: 27224a672372115e5a1d125ed7b2a0b8
|
||||||
|
hash_sha1: 9854582a2958b2d31541ce4a6a1a36201b80c08
|
||||||
|
hash_sha256: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
|
||||||
|
hash_sha512: ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a808
|
||||||
|
created_unix: 1672531200
|
||||||
|
-
|
||||||
|
id: 9
|
||||||
|
size: 14
|
||||||
|
hash_md5: 27224a672372115e5a1d125ed7b2a0b9
|
||||||
|
hash_sha1: 9854582a2958b2d31541ce4a6a1a36201b80c09
|
||||||
|
hash_sha256: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a09
|
||||||
|
hash_sha512: ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a809
|
||||||
|
created_unix: 1672531200
|
||||||
|
-
|
||||||
|
id: 10
|
||||||
|
size: 14
|
||||||
|
hash_md5: 27224a672372115e5a1d125ed7b2a0ba
|
||||||
|
hash_sha1: 9854582a2958b2d31541ce4a6a1a36201b80c10
|
||||||
|
hash_sha256: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a10
|
||||||
|
hash_sha512: ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a810
|
||||||
|
created_unix: 1672531200
|
||||||
|
-
|
||||||
|
id: 11
|
||||||
|
size: 14
|
||||||
|
hash_md5: 27224a672372115e5a1d125ed7b2a0bb
|
||||||
|
hash_sha1: 9854582a2958b2d31541ce4a6a1a36201b80c11
|
||||||
|
hash_sha256: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a11
|
||||||
|
hash_sha512: ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a811
|
||||||
|
created_unix: 1672531200
|
||||||
@ -0,0 +1,99 @@
|
|||||||
|
-
|
||||||
|
id: 1
|
||||||
|
version_id: 1
|
||||||
|
blob_id: 1
|
||||||
|
name: gitea-test-1.0-20230101.000000-1.jar
|
||||||
|
lower_name: gitea-test-1.0-20230101.000000-1.jar
|
||||||
|
composite_key: ""
|
||||||
|
is_lead: false
|
||||||
|
created_unix: 1672531200
|
||||||
|
-
|
||||||
|
id: 2
|
||||||
|
version_id: 1
|
||||||
|
blob_id: 2
|
||||||
|
name: gitea-test-1.0-20230101.000000-2.jar
|
||||||
|
lower_name: gitea-test-1.0-20230101.000000-2.jar
|
||||||
|
composite_key: ""
|
||||||
|
is_lead: false
|
||||||
|
created_unix: 1672531200
|
||||||
|
-
|
||||||
|
id: 3
|
||||||
|
version_id: 1
|
||||||
|
blob_id: 3
|
||||||
|
name: gitea-test-1.0-20230101.000000-3.jar
|
||||||
|
lower_name: gitea-test-1.0-20230101.000000-3.jar
|
||||||
|
composite_key: ""
|
||||||
|
is_lead: false
|
||||||
|
created_unix: 1672531200
|
||||||
|
-
|
||||||
|
id: 4
|
||||||
|
version_id: 1
|
||||||
|
blob_id: 4
|
||||||
|
name: gitea-test-1.0-20230101.000000-4.jar
|
||||||
|
lower_name: gitea-test-1.0-20230101.000000-4.jar
|
||||||
|
composite_key: ""
|
||||||
|
is_lead: false
|
||||||
|
created_unix: 1672531200
|
||||||
|
-
|
||||||
|
id: 5
|
||||||
|
version_id: 1
|
||||||
|
blob_id: 5
|
||||||
|
name: gitea-test-1.0-20230101.000000-5.jar
|
||||||
|
lower_name: gitea-test-1.0-20230101.000000-5.jar
|
||||||
|
composite_key: ""
|
||||||
|
is_lead: false
|
||||||
|
created_unix: 1672531200
|
||||||
|
-
|
||||||
|
id: 6
|
||||||
|
version_id: 1
|
||||||
|
blob_id: 6
|
||||||
|
name: gitea-test-1.0-20230101.000000-3-sources.jar
|
||||||
|
lower_name: gitea-test-1.0-20230101.000000-3-sources.jar
|
||||||
|
composite_key: ""
|
||||||
|
is_lead: false
|
||||||
|
created_unix: 1672531200
|
||||||
|
-
|
||||||
|
id: 7
|
||||||
|
version_id: 1
|
||||||
|
blob_id: 7
|
||||||
|
name: gitea-test-1.0-20230101.000000-3-javadoc.jar
|
||||||
|
lower_name: gitea-test-1.0-20230101.000000-3-javadoc.jar
|
||||||
|
composite_key: ""
|
||||||
|
is_lead: false
|
||||||
|
created_unix: 1672531200
|
||||||
|
-
|
||||||
|
id: 8
|
||||||
|
version_id: 1
|
||||||
|
blob_id: 8
|
||||||
|
name: gitea-test-1.0-20230101.000000-4-sources.jar
|
||||||
|
lower_name: gitea-test-1.0-20230101.000000-4-sources.jar
|
||||||
|
composite_key: ""
|
||||||
|
is_lead: false
|
||||||
|
created_unix: 1672531200
|
||||||
|
-
|
||||||
|
id: 9
|
||||||
|
version_id: 1
|
||||||
|
blob_id: 9
|
||||||
|
name: gitea-test-1.0-20230101.000000-4-javadoc.jar
|
||||||
|
lower_name: gitea-test-1.0-20230101.000000-4-javadoc.jar
|
||||||
|
composite_key: ""
|
||||||
|
is_lead: false
|
||||||
|
created_unix: 1672531200
|
||||||
|
-
|
||||||
|
id: 10
|
||||||
|
version_id: 1
|
||||||
|
blob_id: 10
|
||||||
|
name: gitea-test-1.0-20230101.000000-5-sources.jar
|
||||||
|
lower_name: gitea-test-1.0-20230101.000000-5-sources.jar
|
||||||
|
composite_key: ""
|
||||||
|
is_lead: false
|
||||||
|
created_unix: 1672531200
|
||||||
|
-
|
||||||
|
id: 11
|
||||||
|
version_id: 1
|
||||||
|
blob_id: 11
|
||||||
|
name: gitea-test-1.0-20230101.000000-5-javadoc.jar
|
||||||
|
lower_name: gitea-test-1.0-20230101.000000-5-javadoc.jar
|
||||||
|
composite_key: ""
|
||||||
|
is_lead: false
|
||||||
|
created_unix: 1672531200
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
-
|
||||||
|
id: 1
|
||||||
|
package_id: 1
|
||||||
|
creator_id: 2
|
||||||
|
version: 1.0-SNAPSHOT
|
||||||
|
lower_version: 1.0-snapshot
|
||||||
|
metadata_json: '{"artifact_id":"test-project","group_id":"com.gitea"}'
|
||||||
|
created_unix: 1672531200
|
||||||
@ -0,0 +1,157 @@
|
|||||||
|
// Copyright 2025 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package maven
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/models/packages"
|
||||||
|
"code.gitea.io/gitea/modules/json"
|
||||||
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
"code.gitea.io/gitea/modules/packages/maven"
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
packages_service "code.gitea.io/gitea/services/packages"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CleanupSnapshotVersions removes outdated files for SNAPHOT versions for all Maven packages.
|
||||||
|
func CleanupSnapshotVersions(ctx context.Context) error {
|
||||||
|
retainBuilds := setting.Packages.RetainMavenSnapshotBuilds
|
||||||
|
debugSession := setting.Packages.DebugMavenCleanup
|
||||||
|
log.Debug("Maven Cleanup: starting with retainBuilds: %d, debugSession: %t", retainBuilds, debugSession)
|
||||||
|
|
||||||
|
if retainBuilds < 1 {
|
||||||
|
log.Warn("Maven Cleanup: skipped as value for retainBuilds less than 1: %d. Minimum 1 build should be retained", retainBuilds)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
versions, err := packages.GetVersionsByPackageType(ctx, 0, packages.TypeMaven)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("maven Cleanup: failed to retrieve Maven package versions: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var errs []error
|
||||||
|
var metadataErrors []error
|
||||||
|
|
||||||
|
for _, version := range versions {
|
||||||
|
if !isSnapshotVersion(version.Version) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var artifactID, groupID string
|
||||||
|
if version.MetadataJSON != "" {
|
||||||
|
var metadata map[string]any
|
||||||
|
if err := json.Unmarshal([]byte(version.MetadataJSON), &metadata); err != nil {
|
||||||
|
log.Warn("Maven Cleanup: error during cleanup: failed to unmarshal metadataJSON for package version ID: %d: %w", version.ID, err)
|
||||||
|
} else {
|
||||||
|
artifactID, _ = metadata["artifact_id"].(string)
|
||||||
|
groupID, _ = metadata["group_id"].(string)
|
||||||
|
log.Debug("Maven Cleanup: processing package version with ID: %s, Group ID: %s, Artifact ID: %s, Version: %s", version.ID, groupID, artifactID, version.Version)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := cleanSnapshotFiles(ctx, version.ID, retainBuilds, debugSession); err != nil {
|
||||||
|
formattedErr := fmt.Errorf("version '%s' (ID: %d, Group ID: %s, Artifact ID: %s): %w",
|
||||||
|
version.Version, version.ID, groupID, artifactID, err)
|
||||||
|
|
||||||
|
if errors.Is(err, packages.ErrMetadataFile) {
|
||||||
|
metadataErrors = append(metadataErrors, formattedErr)
|
||||||
|
} else {
|
||||||
|
errs = append(errs, formattedErr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, err := range metadataErrors {
|
||||||
|
log.Warn("Maven Cleanup: error during cleanup: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(errs) > 0 {
|
||||||
|
for _, err := range errs {
|
||||||
|
log.Error("Maven Cleanup: error during cleanup: %v", err)
|
||||||
|
}
|
||||||
|
return fmt.Errorf("maven Cleanup: completed with errors: %v", errs)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug("Completed Maven Cleanup")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func isSnapshotVersion(version string) bool {
|
||||||
|
return strings.HasSuffix(version, "-SNAPSHOT")
|
||||||
|
}
|
||||||
|
|
||||||
|
func cleanSnapshotFiles(ctx context.Context, versionID int64, retainBuilds int, debugSession bool) error {
|
||||||
|
log.Debug("Maven Cleanup: starting cleanSnapshotFiles for versionID: %d with retainBuilds: %d, debugSession: %t", versionID, retainBuilds, debugSession)
|
||||||
|
|
||||||
|
metadataFile, err := packages.GetFileForVersionByName(ctx, versionID, "maven-metadata.xml", packages.EmptyFileKey)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("%w: failed to retrieve maven-metadata.xml: %w", packages.ErrMetadataFile, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
maxBuildNumber, classifiers, err := extractMaxBuildNumber(ctx, metadataFile)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("%w: failed to extract max build number from maven-metadata.xml: %w", packages.ErrMetadataFile, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
thresholdBuildNumber := maxBuildNumber - retainBuilds
|
||||||
|
if thresholdBuildNumber <= 0 {
|
||||||
|
log.Debug("Maven Cleanup: no files to clean up, as the threshold build number is less than or equal to zero for versionID %d", versionID)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
filesToRemove, skippedFiles, err := packages.GetFilesBelowBuildNumber(ctx, versionID, thresholdBuildNumber, classifiers...)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cleanSnapshotFiles: failed to retrieve files for version: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if debugSession {
|
||||||
|
var fileNamesToRemove, skippedFileNames []string
|
||||||
|
|
||||||
|
for _, file := range filesToRemove {
|
||||||
|
fileNamesToRemove = append(fileNamesToRemove, file.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, file := range skippedFiles {
|
||||||
|
skippedFileNames = append(skippedFileNames, file.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug("Maven Cleanup: debug session active. Files to remove: %v, Skipped files: %v", fileNamesToRemove, skippedFileNames)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, file := range filesToRemove {
|
||||||
|
log.Debug("Maven Cleanup: removing file '%s' below threshold %d", file.Name, thresholdBuildNumber)
|
||||||
|
if err := packages_service.DeletePackageFile(ctx, file); err != nil {
|
||||||
|
return fmt.Errorf("cleanSnapshotFiles: failed to delete file '%s': %w", file.Name, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func extractMaxBuildNumber(ctx context.Context, metadataFile *packages.PackageFile) (int, []string, error) {
|
||||||
|
pb, err := packages.GetBlobByID(ctx, metadataFile.BlobID)
|
||||||
|
if err != nil {
|
||||||
|
return 0, nil, fmt.Errorf("failed to get package blob: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
content, _, _, err := packages_service.OpenBlobForDownload(ctx, metadataFile, pb, "", nil, true)
|
||||||
|
if err != nil {
|
||||||
|
return 0, nil, fmt.Errorf("failed to get package file stream: %w", err)
|
||||||
|
}
|
||||||
|
defer content.Close()
|
||||||
|
|
||||||
|
snapshotMetadata, err := maven.ParseSnapshotVersionMetaData(content)
|
||||||
|
if err != nil {
|
||||||
|
return 0, nil, fmt.Errorf("failed to parse maven-metadata.xml: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
buildNumber := snapshotMetadata.BuildNumber
|
||||||
|
classifiers := snapshotMetadata.Classifiers
|
||||||
|
|
||||||
|
return buildNumber, classifiers, nil
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue