简体   繁体   English

如何在 jenkins 中删除 Maven 本地存储库中的旧工件

[英]How to delete old artifacts in maven local repository in jenkins

I have a .m2/repository directory which has a lot of old artifacts.我有一个 .m2/repository 目录,里面有很多旧工件。 Is there a way to clean up the .m2/repository folder with a script or any plugins.有没有办法用脚本或任何插件清理 .m2/repository 文件夹。

Also I would like to tell that the I want to delete the artifacts that are older than 14 days.另外我想告诉我,我想删除超过 14 天的工件。 The .m2/repository folder has no of subfolders. .m2/repository 文件夹没有子文件夹。

Any lead would be highly appriciated任何线索都会受到高度评价

Something like this would be your answer :这样的事情将是你的答案:

now = new Date()
configuration = new Configuration()
cleanedSize = 0
details = []
directoryFilter = new DirectoryFilter()
nonSnapshotDirectoryFilter = new NonSnapshotDirectoryFilter()

def class Configuration {
    def homeFolder = System.getProperty("user.home")
    def path = homeFolder + "/.m2/repository"
    def dryRun = true
    def printDetails = true
    def maxAgeSnapshotsInDays = 60
    def maxAgeInDays = 14
    def versionsToKeep = ["3.1.0.M1"]
    def snapshotsOnly = true
}


private def cleanMavenRepository(File file) {
    def lastModified = new Date(file.lastModified());
    def ageInDays = now - lastModified;
    def directories = file.listFiles(directoryFilter);

    if (directories.length > 0) {
        directories.each {
            cleanMavenRepository(it);
        }
    } else {
        if (ageInDays > configuration.maxAgeSnapshotsInDays && file.canonicalPath.endsWith("-SNAPSHOT")) {
            int size = removeDirAndReturnFreedKBytes(file)
            details.add("About to remove directory $file.canonicalPath with total size $size and $ageInDays days old");
        } else if (ageInDays > configuration.maxAgeInDays && !file.canonicalPath.endsWith("-SNAPSHOT") && !configuration.snapshotsOnly) {
            String highest = obtainHighestVersionOfArtifact(file)
            if (file.name != highest && !configuration.versionsToKeep.contains(file.name)) {
                int size = removeDirAndReturnFreedKBytes(file)
                details.add("About to remove directory $file.canonicalPath with total size $size and $ageInDays days old and not highest version $highest");
            }
        }
    }
}

In this answer , the author removes files not accessed for a period of time.这个答案中,作者删除了一段时间未访问的文件。 This is better than removing files based on modifications, as there will be a few files that are not modified for a long time, but still needed by your build (eg stable dependencies).这比基于修改删除文件要好,因为会有一些文件很长时间没有修改,但您的构建仍然需要(例如稳定的依赖项)。

For your requirements, I would adapt it slightly with this根据您的要求,我会稍微调整一下

find ~jenkins/.m2/repository -atime +14 -iname '*.pom' | \
while read pom; \
    do parent=`dirname "$pom"`; \
    rm -rf "$parent"; \
done

Paraphrasing the author:转述作者:

This will find all *.pom files which have last been accessed more than [14 days] ago [...] and delete their directories.这将找到所有上次访问超过 [14 天] [...] 的*.pom文件并删除它们的目录。

For our use case, we are using a similar command in a separate Jenkins job with a last_access build parameter.对于我们的用例,我们在带有last_access构建参数的单独 Jenkins 作业中使用类似的命令。

  • This project is parameterized这个项目是参数化的

    • String Parameter字符串参数
      • Name: last_access名称: last_access
      • Default Value: 30默认值: 30
      • Description描述

        Remove files with a last access date older than the specified number of days in the past.删除上次访问日期早于过去指定天数的文件。

  • Build:建造:

    • Execute shell, command:执行shell,命令:

       find $JENKINS_HOME/.m2/repository -atime +$last_access -iname '*.pom' | \\ while read pom; \\ do parent=`dirname "$pom"`; \\ rm -rf "$parent"; \\ done
  • Build Triggers:构建触发器:

    • Build periodically, schedule:定期构建,安排:

       H 22 * * *

      (every day) (每天)

Note : This could just be added to cron, but I prefer it in Jenkins.注意:这可以添加到 cron 中,但我更喜欢在 Jenkins 中使用它。

I did spend some hours looking at this problem and to the answers, many of them rely on the atime (which is the last access time on UNIX systems), which is an unreliable solution for two reasons:我确实花了几个小时来研究这个问题和答案,其中许多都依赖于atime (这是 UNIX 系统上的最后访问时间),这是一个不可靠的解决方案,原因有两个:

  1. Most UNIX systems (including Linux and macOS) update the atime irregularly at best, and that is for a reason: a complete implementation of atime would imply the whole file system would be slowed down by having to update (ie, write to the disk) the atime every time a file is read, moreover having a such an extreme number of updates would very rapidly wear out the modern, high performance SSD drives大多数 UNIX 系统(包括 Linux 和 macOS)充其量不定期地更新atime ,这是有原因的: atime的完整实现意味着整个文件系统将因必须更新(即写入磁盘)而变慢在atime每一个文件的读取时间,而且有更新的这么极端的数字将很快磨损现代化,高性能的固态硬盘驱动器
  2. On a CI/CD environment, the VM that's used to build your Maven project will have its Maven repository restored from a shared storage, which in turn will make the atime get set to a "recent" value在 CI/CD 环境中,用于构建 Maven 项目的 VM 将从共享存储恢复其 Maven 存储库,这反过来会使atime设置为“最近”值

I hence created a Maven repository cleaner and made it available on https://github.com/alitokmen/maven-repository-cleaner/ .因此,我创建了一个 Maven 存储库清理器,并在https://github.com/alitokmen/maven-repository-cleaner/ 上提供它。 The bash maven-repository-cleaner.sh script has one function, cleanDirectory , which is a recursive function looping through the ~/.m2/repository/ and does the following: bash maven-repository-cleaner.sh脚本有一个函数cleanDirectory ,它是一个循环遍历~/.m2/repository/的递归函数,并执行以下操作:

  • When the subdirectory is not a version number, it digs into that subdirectory for analysis当子目录不是版本号时,它会深入该子目录进行分析
  • When a directory has subdirectories which appear to be version numbers, it only deletes all lower versions当目录具有看起来是版本号的子目录时,它只会删除所有较低版本

In practice, if you have a hierarchy such as:在实践中,如果您有一个层次结构,例如:

  • artifact-group
    • artifact-name
      • 1.8
      • 1.10
      • 1.2

... maven-repository-cleaner.sh script will: ... maven-repository-cleaner.sh脚本将:

  1. Navigate to artifact-group导航到artifact-group
  2. In artifact-group , navigate to artifact-nameartifact-group ,导航到artifact-name
  3. In artifact-name , delete the subfolders 1.8 and 1.2 , as 1.10 is superior to both 1.2 and 1.8artifact-name ,删除子文件夹1.81.2 ,因为1.10优于1.21.8

To run the tool on your CI/CD platform (or any other form of UNIX system), simply use the below three lines, either at the beginning or at the end of the build:要在您的 CI/CD 平台(或任何其他形式的 UNIX 系统)上运行该工具,只需在构建的开头或结尾使用以下三行:

wget https://raw.githubusercontent.com/alitokmen/maven-repository-cleaner/main/maven-repository-cleaner.sh
chmod +x maven-repository-cleaner.sh
./maven-repository-cleaner.sh

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM