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

时间:2015-09-17 08:24:01

标签: linux shell maven jenkins artifacts

我有一个.m2 / repository目录,里面有很多旧工件。有没有办法用脚本或任何插件清理.m2 / repository文件夹。

此外,我想告诉我要删除超过14天的工件。 .m2 / repository文件夹没有子文件夹。

任何领导都会高度评价

3 个答案:

答案 0 :(得分:1)

这样的事情就是你的答案:

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");
            }
        }
    }
}

答案 1 :(得分:1)

我确实花了几个小时来研究这个问题,答案很多都依赖于 atime(这是 UNIX 系统上的最后访问时间),这是一个不可靠的解决方案,原因有两个:< /p>

  1. 大多数 UNIX 系统(包括 Linux 和 macOS)最多不定期地更新 atime,这是有原因的:atime 的完整实现意味着整个文件系统将减慢每次读取文件时都必须更新(即写入磁盘)atime,而且如此大量的更新会很快磨损现代高性能 SSD 驱动器
  2. 在 CI/CD 环境中,用于构建 Maven 项目的 VM 将从共享存储中恢复其 Maven 存储库,这反过来会使 atime 设置为“最近”值< /li>

因此,我创建了一个 Maven 存储库清理器并使其在 https://github.com/alitokmen/maven-repository-cleaner/ 上可用。 bash maven-repository-cleaner.sh 脚本有一个函数 cleanDirectory,它是一个循环遍历 ~/.m2/repository/ 的递归函数,并执行以下操作:

  • 当子目录不是版本号时,它会深入该子目录进行分析
  • 当一个目录的子目录看起来是版本号时,它只会删除所有较低的版本

实际上,如果您有一个层次结构,例如:

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

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

  1. 导航到artifact-group
  2. artifact-group 中,导航至 artifact-name
  3. artifact-name中,删除子文件夹1.81.2,因为1.10优于1.21.8

要在您的 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

答案 2 :(得分:0)

this answer中,作者删除了一段时间未访问的文件。这比基于修改删除文件要好,因为会有一些文件很长时间没有修改,但您的构建仍然需要(例如稳定的依赖项)。

根据您的要求,我会稍微调整一下

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

转述作者:

<块引用>

这将查找最近一次访问超过 [14 天] [...] 的所有 *.pom 文件并删除它们的目录。

对于我们的用例,我们在单独的 Jenkins 作业中使用类似的命令,并带有 last_access 构建参数。

  • 此项目已参数化

    • 字符串参数
      • 姓名:last_access
      • 默认值:30
      • 说明 <块引用>

        删除上次访问日期早于过去指定天数的文件。

  • 构建:

    • 执行shell,命令:

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

    • 定期构建,安排:

      H 22 * * *
      

      (每天)

注意:这可以添加到 cron 中,但我更喜欢在 Jenkins 中使用它。