From e5c3fbf36782b7dbf1066fb98caf0fabd84e4d23 Mon Sep 17 00:00:00 2001 From: labkey-susanh Date: Wed, 7 Jan 2026 09:22:38 -0800 Subject: [PATCH 1/8] Filter out empty lines --- src/main/groovy/org/labkey/gradle/util/TaskUtils.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/groovy/org/labkey/gradle/util/TaskUtils.groovy b/src/main/groovy/org/labkey/gradle/util/TaskUtils.groovy index 9513d213..1b6f1148 100644 --- a/src/main/groovy/org/labkey/gradle/util/TaskUtils.groovy +++ b/src/main/groovy/org/labkey/gradle/util/TaskUtils.groovy @@ -67,7 +67,7 @@ class TaskUtils if (listing.exists()) { logger.quiet("Reading ${type} list from file ${listing.getAbsolutePath()}.") try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(listing)))) { - List lines = IOUtils.readLines(reader).stream().filter(line -> !line.startsWith("#")).toList() + List lines = IOUtils.readLines(reader).stream().filter(line -> !line.startsWith("#") && !line.trim().isEmpty()).toList() logger.quiet("... found ${lines.size()} uncommented lines") return lines } From 408f6b6685e02c69514d9ccee199f10790909f32 Mon Sep 17 00:00:00 2001 From: labkey-susanh Date: Wed, 7 Jan 2026 09:23:09 -0800 Subject: [PATCH 2/8] Check for empty version --- src/main/groovy/org/labkey/gradle/task/PurgeArtifacts.groovy | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/groovy/org/labkey/gradle/task/PurgeArtifacts.groovy b/src/main/groovy/org/labkey/gradle/task/PurgeArtifacts.groovy index 2039d141..cdadfae1 100644 --- a/src/main/groovy/org/labkey/gradle/task/PurgeArtifacts.groovy +++ b/src/main/groovy/org/labkey/gradle/task/PurgeArtifacts.groovy @@ -107,7 +107,8 @@ class PurgeArtifacts extends DefaultTask logger.quiet("### Begin purge for module ${moduleName} for ${versions.size()} versions\n") for (String version: versions) { - makeRequests(moduleName, moduleName, version, deleteStats, true) + if (!StringUtils.isEmpty(version.trim())) + makeRequests(moduleName, moduleName, version, deleteStats, true) } logger.quiet("Deleted ${deleteStats.get(NUM_DELETED)} artifacts; ${deleteStats.get(NUM_NOT_FOUND)} artifacts not found.") From 6e878dc03af0fcdc884420327e775d33a64ad040 Mon Sep 17 00:00:00 2001 From: labkey-susanh Date: Wed, 7 Jan 2026 09:25:52 -0800 Subject: [PATCH 3/8] Modify RestoreFromTrash task to read modules and versions from files --- .../gradle/task/RestoreFromTrash.groovy | 165 +++++++++++++----- 1 file changed, 124 insertions(+), 41 deletions(-) diff --git a/src/main/groovy/org/labkey/gradle/task/RestoreFromTrash.groovy b/src/main/groovy/org/labkey/gradle/task/RestoreFromTrash.groovy index 9a14481b..c7c87b3f 100644 --- a/src/main/groovy/org/labkey/gradle/task/RestoreFromTrash.groovy +++ b/src/main/groovy/org/labkey/gradle/task/RestoreFromTrash.groovy @@ -8,66 +8,149 @@ import org.apache.hc.client5.http.impl.classic.HttpClients import org.apache.hc.core5.http.HttpStatus import org.gradle.api.DefaultTask import org.gradle.api.GradleException -import org.gradle.api.Project +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Optional import org.gradle.api.tasks.TaskAction -import org.labkey.gradle.plugin.Api -import org.labkey.gradle.plugin.FileModule -import org.labkey.gradle.plugin.JavaModule -import org.labkey.gradle.plugin.Module -import org.labkey.gradle.util.BuildUtils +import org.labkey.gradle.util.TaskUtils import static org.labkey.gradle.task.PurgeArtifacts.Response -// TODO for more flexibility and for configuration cache support, needs to be converted to read projects and versions -// from a file, as for PurgeArtifacts class RestoreFromTrash extends DefaultTask { public static final String VERSION_PROPERTY = "restoreVersion" + public static final String VERSIONS_FILE_PROPERTY = 'restoreVersions' + public static final String RESTORE_LIST_FILE_PROPERTY = 'restoreList'; + + @Input @Optional + final abstract Property restoreVersion = project.objects.property(String).convention(project.hasProperty(VERSION_PROPERTY) ? (String) project.property(VERSION_PROPERTY) : "") + + @Input @Optional + final abstract Property restoreVersions = project.objects.property(String).convention(project.hasProperty(VERSIONS_FILE_PROPERTY) ? (String) project.property(VERSIONS_FILE_PROPERTY) : "") + @Input @Optional + final abstract Property restoreListFile = project.objects.property(String).convention(project.hasProperty(RESTORE_LIST_FILE_PROPERTY) ? (String) project.property(RESTORE_LIST_FILE_PROPERTY) : "") + @Input + final abstract Property isDryRun = project.objects.property(Boolean).convention(project.hasProperty(PurgeArtifacts.DRY_RUN_PROPERTY)) + + @Input + final abstract Property artifactoryUrl = project.objects.property(String).convention((String) project.property('artifactory_contextUrl')) + @Input + final abstract Property artifactoryUser = project.objects.property(String).convention((String) project.property('artifactory_user')) + @Input + final abstract Property artifactoryPassword = project.objects.property(String).convention((String) project.property('artifactory_password')) + + private static final String NUM_NOT_FOUND = "numNotFound" + private static final String NUM_RESTORED = "numRestored" + private static final String UNRESTORED_VERSIONS = "unrestoredVersions" @TaskAction void restoreVersions() { - String restoreVersion - if (!project.hasProperty(VERSION_PROPERTY)) - throw new GradleException("No value provided for ${VERSION_PROPERTY}.") - restoreVersion = project.property(VERSION_PROPERTY) - String[] unrestoredVersions = [] - int numRestored = 0 - int numNotFound = 0 - project.allprojects({ Project p -> - def plugins = p.getPlugins() - if (plugins.hasPlugin(Module.class) || plugins.hasPlugin(JavaModule.class) || plugins.hasPlugin(FileModule.class)) { - logger.quiet("Considering ${p.path}...") - Response response = makeRestoreRequest(p.name, restoreVersion, "module") - if (response == Response.NOT_FOUND) - numNotFound++ - else if (response == Response.ERROR) { - unrestoredVersions += "${p.path} - module: ${restoreVersion}" - } else - numRestored++ + String restoreModulesFileName = restoreListFile.get(); + if (StringUtils.isEmpty(restoreModulesFileName)) + throw new GradleException("Use -P${RESTORE_LIST_FILE_PROPERTY}= to provide a list of modules to work with.") + List moduleNames = TaskUtils.readInputFile(restoreModulesFileName, "modules", logger) + if (moduleNames.isEmpty()) + throw new GradleException("No module names found in file ${restoreModulesFileName}") + String version = this.restoreVersion.get() + if (!StringUtils.isEmpty(version.trim())) + this.restoreVersion(version, moduleNames) + else + { + Map overallStats = new HashMap<>() + overallStats.put(NUM_NOT_FOUND, 0) + overallStats.put(NUM_RESTORED, 0) + String restoreVersionsFileName = restoreVersions.get() + if (StringUtils.isEmpty(restoreVersionsFileName)) + throw new GradleException("Either -P${VERSION_PROPERTY}= or -P${VERSIONS_FILE_PROPERTY}= must be provided") + List versions = TaskUtils.readInputFile(restoreVersionsFileName, "versions", logger) + if (versions.isEmpty()) + throw new GradleException("No versions found for file ${restoreVersionsFileName}.") + if (versions.size() > 1) { + for (String moduleName : moduleNames) { + Map restoreStats = restoreModuleVersions(moduleName, versions) + overallStats.put(NUM_NOT_FOUND, overallStats.get(NUM_NOT_FOUND) + (Integer) restoreStats.get(NUM_NOT_FOUND)) + overallStats.put(NUM_RESTORED, overallStats.get(NUM_RESTORED) + (Integer) restoreStats.get(NUM_RESTORED)) + } + if (moduleNames.size() > 1) + logger.quiet("\nSummary:\n\tRestored ${overallStats.get(NUM_RESTORED)} artifacts.\n\t${overallStats.get(NUM_NOT_FOUND)} artifacts not found.") } - if (plugins.hasPlugin(Api.class) || project.path == BuildUtils.getApiProjectPath(project.gradle)) { - Response response = makeRestoreRequest(p.name, restoreVersion, "api") - if (response == Response.NOT_FOUND) - numNotFound++ - else if (response == Response.ERROR) { - unrestoredVersions += "${p.path} - api: ${restoreVersion}" - } else - numRestored++ + else { + for (String v : versions) { + if (!StringUtils.isEmpty(v.trim())) + this.restoreVersion(v, moduleNames) + } } - }) + } + } + + Map restoreModuleVersions(String moduleName, List versions) + { + Map restoreStats = new HashMap(); + restoreStats.put(NUM_RESTORED, 0) + restoreStats.put(NUM_NOT_FOUND, 0) + restoreStats.put(UNRESTORED_VERSIONS, new ArrayList<>()) + + logger.quiet("### Begin restore for module ${moduleName} for ${versions.size()} versions\n") + + for (String version: versions) { + if (!StringUtils.isEmpty(version.trim())) + makeRequests(moduleName, moduleName, version, restoreStats) + } + logStats(restoreStats) + logger.quiet("\n### End restore for module ${moduleName}\n") + return restoreStats + } + + Map restoreVersion(String version, List moduleNames) + { + if (StringUtils.isEmpty(version.trim())) + return + Map restoreStats = new HashMap(); + restoreStats.put(NUM_RESTORED, 0) + restoreStats.put(NUM_NOT_FOUND, 0) + restoreStats.put(UNRESTORED_VERSIONS, new ArrayList<>()) + for (String moduleName: moduleNames) { + makeRequests(moduleName, moduleName, version, restoreStats) + } + logStats(restoreStats) + return restoreStats + } - logger.quiet("Restored ${numRestored} artifacts; ${numNotFound} artifacts not found.") - if (unrestoredVersions.size() > 0 && !project.hasProperty("dryRun")) - throw new GradleException("The following ${unrestoredVersions.size()} versions were not restored.\n${StringUtils.join(unrestoredVersions, "\n")}\nCheck the log for more information.") + void logStats(Map restoreStats) + { + logger.quiet("Restored ${restoreStats.get(NUM_RESTORED)} artifacts; ${restoreStats.get(NUM_NOT_FOUND)} artifacts not found.") + if (((List) restoreStats.get(UNRESTORED_VERSIONS)).size() > 0 && !isDryRun.get()) + throw new GradleException("The following ${((List) restoreStats.get(UNRESTORED_VERSIONS)).size()} versions were not restored.\n${StringUtils.join(restoreStats.get(UNRESTORED_VERSIONS), "\n")}\nCheck the log for more information.") + } + + void makeRequests(String moduleName, String loggingName, String restoreVersion, Map statsMap) + { + if (StringUtils.isEmpty(restoreVersion.trim())) + return + logger.quiet("Considering ${loggingName} ${restoreVersion}...") + Response response = makeRestoreRequest(moduleName, restoreVersion, "module") + if (response == Response.NOT_FOUND) + statsMap.put(NUM_NOT_FOUND, statsMap.get(NUM_NOT_FOUND)+1); + else if (response == Response.ERROR) + statsMap.get(UNRESTORED_VERSIONS).add("${loggingName} - module: ${restoreVersion}") + else + statsMap.put(NUM_RESTORED, statsMap.get(NUM_RESTORED)+1) + response = makeRestoreRequest(moduleName, restoreVersion, "api") + if (response == Response.NOT_FOUND) + statsMap.put(NUM_NOT_FOUND, statsMap.get(NUM_NOT_FOUND)+1) + else if (response == Response.ERROR) + statsMap.get(UNRESTORED_VERSIONS).add("${loggingName} - api: ${restoreVersion}") + else + statsMap.put(NUM_RESTORED, statsMap.get(NUM_RESTORED)+1) } /** * This uses the Artifactory REST Api to request a restoration of a particular "item" (https://jfrog.com/help/r/jfrog-rest-apis/restore-item-from-trash-can) * - * @param artifactName the artifact whose version is to be deleted - * @param version the version of the artifact to delete (e.g., 21.11-SNAPSHOT) + * @param artifactName the artifact whose version is to be restored + * @param version the version of the artifact to restore (e.g., 21.11-SNAPSHOT) * @param type either "api" or "module" * @return Response summarizing http status from request * @throws GradleException if the restoration request throws an exception @@ -76,7 +159,7 @@ class RestoreFromTrash extends DefaultTask { if (project.hasProperty("dryRun")) { logger.quiet("\tRestoring version ${version} of ${artifactName} ${type} -- Skipped for dry run") - return + return null } CloseableHttpClient httpClient = HttpClients.createDefault() From 504e40d86508e4c7313a2a14ee35a2d0ed1fcce9 Mon Sep 17 00:00:00 2001 From: labkey-susanh Date: Wed, 7 Jan 2026 09:26:32 -0800 Subject: [PATCH 4/8] Update `BuildUtils.getDistributionVersion` to get VCS properties from git commands instead of versioning plugin that is no longer used --- .../org/labkey/gradle/util/BuildUtils.groovy | 47 +++++++++++-------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/src/main/groovy/org/labkey/gradle/util/BuildUtils.groovy b/src/main/groovy/org/labkey/gradle/util/BuildUtils.groovy index a0de0760..d14bc6d6 100644 --- a/src/main/groovy/org/labkey/gradle/util/BuildUtils.groovy +++ b/src/main/groovy/org/labkey/gradle/util/BuildUtils.groovy @@ -452,9 +452,10 @@ class BuildUtils } } - if (project.hasProperty("versioning")) + if (project.hasProperty("includeVcs")) { - String rootBranch = project.rootProject.versioning.info.branchId + Properties vcsProps = getStandardVCSProperties(project) + String rootBranch = vcsProps.get(VCS_BRANCH_PROP_NAME) project.logger.info("${project.path} rootBranch ${rootBranch}") if (rootBranch.startsWith("release") && /* e.g. release20.11-SNAPSHOT */ project.labkeyVersion.contains("-SNAPSHOT")) /* e.g. 20.11-SNAPSHOT */ @@ -490,6 +491,12 @@ class BuildUtils return version } + public static final String VCS_URL_PROP_NAME = "VcsURL" + public static final String VCS_BRANCH_PROP_NAME = "VcsBranch" + public static final String VCS_TAG_PROP_NAME = "VcsTag" + public static final String VCS_REVISION_PROP_NAME = "VcsRevision" + public static final String BUILD_NUMBER_PROP_NAME = "BuildNumber" + static Properties getStandardVCSProperties(project) { String buildNumber = @@ -497,34 +504,34 @@ class BuildUtils TeamCityExtension.getTeamCityProperty(project,"build.number", null)) Properties ret = new Properties() def gitCmd = SystemUtils.IS_OS_WINDOWS ? "git.exe" : "git" - if (project.hasProperty("includeVcs") && (!project.hasProperty("lkModule") || project.lkModule.getModProperties().get("VcsURL").isEmpty())) + if (project.hasProperty("includeVcs") && (!project.hasProperty("lkModule") || project.lkModule.getModProperties().get(VCS_URL_PROP_NAME).isEmpty())) { def url = "${gitCmd} -C ${project.projectDir.absolutePath} config --get remote.origin.url".execute().text.trim() Matcher matcher = GIT_URL_WITH_TOKEN.matcher(url) if (matcher.matches()) // Strip out the token if included in the URL. url = matcher.group(1) + "@" + matcher.group(3) - ret.setProperty("VcsURL", url) + ret.setProperty(VCS_URL_PROP_NAME, url) project.logger.info("${project.path} git url: ${url}") def branch = "${gitCmd} -C ${project.projectDir.absolutePath} rev-parse --abbrev-ref HEAD".execute().text.trim() project.logger.info("${project.path} git branch: ${branch}") - ret.setProperty("VcsBranch", branch) + ret.setProperty(VCS_BRANCH_PROP_NAME, branch) def revision = "${gitCmd} -C ${project.projectDir.absolutePath} rev-parse @".execute().text.trim() project.logger.info("${project.path} git revision: ${revision}") - ret.setProperty("VcsRevision", revision) + ret.setProperty(VCS_REVISION_PROP_NAME, revision) def tag = "${gitCmd} -C ${project.projectDir.absolutePath} describe --tags --exact-match 2> /dev/null".execute().text.trim() project.logger.info("${project.path} git tag: ${revision}") if (!tag.isEmpty() && !tag.equals(revision)) - ret.setProperty("VcsTag", tag) + ret.setProperty(VCS_TAG_PROP_NAME, tag) else - ret.setProperty("VcsTag", "")} - else + ret.setProperty(VCS_TAG_PROP_NAME, "")} + else if (!project.hasProperty("includeVcs")) { - ret.setProperty("VcsBranch", "Unknown") - ret.setProperty("VcsTag", "Unknown") - ret.setProperty("VcsURL", "Unknown") - ret.setProperty("VcsRevision", "Unknown") + ret.setProperty(VCS_BRANCH_PROP_NAME, "Unknown") + ret.setProperty(VCS_TAG_PROP_NAME, "Unknown") + ret.setProperty(VCS_URL_PROP_NAME, "Unknown") + ret.setProperty(VCS_REVISION_PROP_NAME, "Unknown") } - ret.setProperty("BuildNumber", buildNumber != null ? buildNumber : "Unknown") + ret.setProperty(BUILD_NUMBER_PROP_NAME, buildNumber != null ? buildNumber : "Unknown") return ret } @@ -594,7 +601,7 @@ class BuildUtils static void addModuleDistributionDependency(Project distributionProject, String depProjectPath, String config, boolean addTransitive) { - if (distributionProject.configurations.findByName(config) == null) + if (distributionProject.configurations.named(config) == null) distributionProject.configurations { config } @@ -613,16 +620,16 @@ class BuildUtils return distributionProject.evaluationDependsOn(depProject.getPath()) - if (depProject.configurations.findByName("modules") != null) { + if (depProject.configurations.named("modules") != null) { depProject.configurations.modules.dependencies.each { dep -> if (dep instanceof ProjectDependency) { if (!pathsAdded.contains(dep.getPath())) { - distributionProject.logger.info("${distributionProject.path}: Adding '${config}' dependency on project ${dep}") + distributionProject.logger.info("${distributionProject.path}: Adding '${config}' dependency on ${dep}") distributionProject.dependencies.add(config, dep) distributionProject.evaluationDependsOn(dep.getPath()) pathsAdded.add(dep.getPath()) - distributionProject.logger.debug("${distributionProject.path}: Adding recursive '${config}' dependenices from ${dep.getPath()}") + distributionProject.logger.info("${distributionProject.path}: Adding recursive '${config}' dependenices from ${dep.getPath()}") addTransitiveModuleDependencies(distributionProject, depProject.project(dep.getPath()), config, pathsAdded) } } @@ -974,7 +981,7 @@ class BuildUtils { try { project.configurations.named(configName) { Configuration config -> - resolutionStrategy.dependencySubstitution { DependencySubstitutions ds -> + config.resolutionStrategy.dependencySubstitution { DependencySubstitutions ds -> project.rootProject.subprojects { Project p -> { @@ -985,7 +992,7 @@ class BuildUtils p.plugins.hasPlugin('org.labkey.build.javaModule') ) { ds.substitute ds.module("org.labkey.module:${p.name}") using ds.project(p.path) - p.logger.debug("Substituting org.labkey.module:${p.name} with ${p.path}") + p.logger.info("Substituting org.labkey.module:${p.name} with ${p.path}") } // if (p.plugins.hasPlugin('org.labkey.build.api')) // { From ddce5d34be7b0240e5e2c8776c760ec0d7397f83 Mon Sep 17 00:00:00 2001 From: labkey-susanh Date: Wed, 7 Jan 2026 09:26:48 -0800 Subject: [PATCH 5/8] release notes --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index f37bcf45..2a5a33e9 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,13 @@ If you are making changes to the plugins, please see the [internal docs](https:/ on how to do that, including how to develop and test locally and the versioning information. ## Release Notes +### TBD +*Released* TBD +(Earliest compatible LabKey version: 25.10) +- Update `BuildUtils.getDistributionVersion` to get VCS properties from git commands instead of removed versioning plugin +- Add some trimming and empty string checks for `PurgeArtficats` task +- Modify `RestoreFromTrash` task to read modules and versions from files + ### 7.2.1 *Released* 23 December 2025 (Earliest compatible LabKey version: 25.10) From 908352a3d6537740c6aa5b315a2d29a5af5e434a Mon Sep 17 00:00:00 2001 From: labkey-susanh Date: Wed, 7 Jan 2026 09:27:24 -0800 Subject: [PATCH 6/8] version number --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 18a0e731..8f4237b5 100644 --- a/build.gradle +++ b/build.gradle @@ -43,7 +43,7 @@ dependencies { } group = 'org.labkey.build' -project.version = "7.3.0-SNAPSHOT" +project.version = "7.3.0-versionFixes-SNAPSHOT" gradlePlugin { plugins { From 58d031f03d40097ee2b1f6b260bfac02dfa49569 Mon Sep 17 00:00:00 2001 From: labkey-susanh Date: Wed, 7 Jan 2026 15:42:47 -0800 Subject: [PATCH 7/8] Remove another reference to versioning plugin --- .../org/labkey/gradle/util/BuildUtils.groovy | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/main/groovy/org/labkey/gradle/util/BuildUtils.groovy b/src/main/groovy/org/labkey/gradle/util/BuildUtils.groovy index d14bc6d6..64da1cd3 100644 --- a/src/main/groovy/org/labkey/gradle/util/BuildUtils.groovy +++ b/src/main/groovy/org/labkey/gradle/util/BuildUtils.groovy @@ -401,10 +401,11 @@ class BuildUtils { String version = project.labkeyVersion - if (project.hasProperty("versioning")) + if (project.hasProperty("includeVcs")) { - String branch = project.versioning.info.branchId - if (!["trunk", "develop", "master", "main", "none", ""].contains(branch) && + var vcsProps = getStandardVCSProperties(project) + String branch = vcsProps.get(VCS_BRANCH_PROP_NAME) + if (branch != null && !["trunk", "develop", "master", "main", "none", ""].contains(branch) && !branch.toLowerCase().matches("release.*-snapshot")) { Matcher matcher = Pattern.compile(".*fb_(.+)").matcher(branch) @@ -601,10 +602,7 @@ class BuildUtils static void addModuleDistributionDependency(Project distributionProject, String depProjectPath, String config, boolean addTransitive) { - if (distributionProject.configurations.named(config) == null) - distributionProject.configurations { - config - } + distributionProject.configurations.maybeCreate(config) distributionProject.logger.info("${distributionProject.path}: adding ${depProjectPath} as dependency for config ${config}") addLabKeyDependency(project: distributionProject, config: config, depProjectPath: depProjectPath, depProjectConfig: "published", depExtension: "module", depVersion: distributionProject.labkeyVersion) if (addTransitive) { @@ -620,7 +618,7 @@ class BuildUtils return distributionProject.evaluationDependsOn(depProject.getPath()) - if (depProject.configurations.named("modules") != null) { + if (depProject.configurations.findByName("modules") != null) { depProject.configurations.modules.dependencies.each { dep -> if (dep instanceof ProjectDependency) { From ebda20206764cb356c821151a1860753a5444bd2 Mon Sep 17 00:00:00 2001 From: labkey-susanh Date: Thu, 8 Jan 2026 12:35:45 -0800 Subject: [PATCH 8/8] Prepare for merge to develop --- README.md | 4 ++-- build.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2a5a33e9..d1d7669b 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,8 @@ If you are making changes to the plugins, please see the [internal docs](https:/ on how to do that, including how to develop and test locally and the versioning information. ## Release Notes -### TBD -*Released* TBD +### 7.3.0 +*Released* 8 January 2026 (Earliest compatible LabKey version: 25.10) - Update `BuildUtils.getDistributionVersion` to get VCS properties from git commands instead of removed versioning plugin - Add some trimming and empty string checks for `PurgeArtficats` task diff --git a/build.gradle b/build.gradle index 8f4237b5..a751b7ab 100644 --- a/build.gradle +++ b/build.gradle @@ -43,7 +43,7 @@ dependencies { } group = 'org.labkey.build' -project.version = "7.3.0-versionFixes-SNAPSHOT" +project.version = "7.4.0-SNAPSHOT" gradlePlugin { plugins {