Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions .github/workflows/dependency-checks-mvn.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

name: NetBeans Dependency Checks MVN

on:
# pull_request:
# Allows you to run this workflow manually from the Actions tab in GitHub UI
workflow_dispatch:

permissions:
contents: read

# cancel other workflow run in the same head-base group if it exists
concurrency:
group: dep-checker-${{ github.head_ref || github.run_id }}-${{ github.base_ref }}
cancel-in-progress: true

defaults:
run:
shell: bash

jobs:

base-build:
name: Check Dependencies
runs-on: ubuntu-latest
timeout-minutes: 20
steps:

- name: Checkout ${{ github.ref }} ( ${{ github.sha }} )
uses: actions/checkout@v7
with:
persist-credentials: false
submodules: false
show-progress: false

- name: Set up JDK
uses: actions/setup-java@v6
with:
java-version: 25
distribution: 'zulu'

- name: Check Dependencies
run: |
ant -quiet bootstrap
ant -quiet verify-libs-and-license

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

licenses

cd nbbuild/build/mavenpoms/;mvn eu.maveniverse.maven.plugins:toolbox:0.15.17:dependency-versions

@mbien mbien Sep 5, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: split line

          cd nbbuild/build/mavenpoms/
          mvn -B eu.maveniverse.maven.plugins:toolbox:0.15.17:libyear

btw, how about running libyear instead of dependency-versions?

difference: it will print less (won't show "up to date" lines) and it calculates age too, which can be useful for prioritization.

This is the most concice output I could come up with:

mvn -B\
 -Dorg.slf4j.simpleLogger.defaultLogLevel=warn\
 -Dorg.slf4j.simpleLogger.log.eu.maveniverse.maven=info\
 -DupToDate=true\
 eu.maveniverse.maven.plugins:0.15.17:toolbox:libyear

generates about 1200 lines.

I am not sure what the github limit is. Would be cool if we could post it there like the other action.

          echo "<pre>" >> $GITHUB_STEP_SUMMARY
          <command> | tee -a $GITHUB_STEP_SUMMARY
          echo "</pre>" >> $GITHUB_STEP_SUMMARY

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh nice. apparently github limits at 1MB - this will fit without problems.

16 changes: 1 addition & 15 deletions nbbuild/antsrc/org/netbeans/nbbuild/extlibs/MavenCoordinate.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,7 @@
import java.net.URLDecoder;
import java.net.URLEncoder;

class MavenCoordinate {

private final String groupId;
private final String artifactId;
private final String version;
private final String extension;
private final String classifier;

private MavenCoordinate(String groupId, String artifactId, String version, String extension, String classifier) {
this.groupId = groupId;
this.artifactId = artifactId;
this.version = version;
this.extension = extension;
this.classifier = classifier;
}
record MavenCoordinate(String groupId, String artifactId, String version, String extension, String classifier) {

public boolean hasClassifier() {
return !classifier.isEmpty();
Expand Down
185 changes: 112 additions & 73 deletions nbbuild/antsrc/org/netbeans/nbbuild/extlibs/MavenSkeletonProject.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
import java.nio.file.StandardOpenOption;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -97,34 +100,47 @@ private void buildLibPomForMaven() throws IOException {
}
Path pseudoMavendirectory = Files.createDirectory(pseudoMaven);
Path parentPom = Files.createFile(pseudoMavendirectory.resolve("pom.xml"));
Files.write(parentPom, ("<project>"
+ "\n <modelVersion>4.0.0</modelVersion>"
+ "\n <groupId>com.mycompany.app</groupId>"
+ "\n <artifactId>my-app</artifactId>"
+ "\n <version>1</version>"
+ "\n <packaging>pom</packaging>"
+ "<distributionManagement>\n"
+ " <site><id>dummy</id><url>https://netbeans.apache.org/dummy</url><name>dummy</name></site>\n"
+ " </distributionManagement>").getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE, StandardOpenOption.APPEND);
Files.write(parentPom, ("""
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>pseudo.org.netbeans</groupId>
<artifactId>netbeans</artifactId>
<version>1</version>
<packaging>pom</packaging><distributionManagement>
<site><id>dummy</id><url>https://netbeans.apache.org/dummy</url><name>dummy</name></site>
</distributionManagement>""").getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE, StandardOpenOption.APPEND);
Files.write(parentPom, "\n <modules>".getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
// scan module with external folder
Map<String,Set<String>> clusters = new HashMap<>();
for (String module : modules) {
File d = new File(new File(nball, module), "external");
if (d.exists() && d.isDirectory()) {
String moduleName = module.replace("/", "").replace(".", "");
Files.write(parentPom, ("\n <module>" + moduleName + "</module>").getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
Path modulesPathFolder = Files.createDirectory(pseudoMavendirectory.resolve(moduleName));
Path moduleparentPom = Files.createFile(modulesPathFolder.resolve("pom.xml"));
Files.write(moduleparentPom, ("<project>"
+ "\n <modelVersion>4.0.0</modelVersion>"
+ "\n <parent><groupId>com.mycompany.app</groupId><artifactId>my-app</artifactId><version>1</version></parent>"
+ "\n <groupId>com.mycompany.app</groupId>"
+ "\n <artifactId>" + moduleName + "</artifactId>"
+ "\n <version>1</version>").getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE, StandardOpenOption.APPEND);
var name = module.split("/");
String clusterName = module.split("/")[0];
clusters.computeIfAbsent(clusterName,k-> new HashSet<>());
Path clusterfolder;String moduleName;
if (name.length > 1) {
moduleName = name[1];
clusters.get(name[0]).add(moduleName);
} else {
moduleName = "nbbuild";
}
clusterfolder = Files.createDirectories(pseudoMavendirectory.resolve(clusterName).resolve(moduleName));
// write pom for the module in clusterfolder/modulefolder/pom.xml
Path moduleparentPom = Files.createFile(clusterfolder.resolve("pom.xml"));
Files.write(moduleparentPom, ("""
<project>
<modelVersion>4.0.0</modelVersion>
<parent><groupId>pseudo.org.netbeans</groupId><artifactId>%s</artifactId><version>1</version></parent>
<groupId>%s</groupId>
<artifactId>%s</artifactId>
<version>1</version>""".formatted(clusterName,clusterName,moduleName)).getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE, StandardOpenOption.APPEND);
Files.write(moduleparentPom, "\n <dependencies>".getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);

File list = new File(d, "binaries-list");
if (list.isFile()) {

// do not accept more than once a g:a artifacts
Set<MavenGA> duplicatecheck = new HashSet<>();
try ( Reader r = new FileReader(list)) {
BufferedReader br = new BufferedReader(r);
String line;
Expand All @@ -139,18 +155,21 @@ private void buildLibPomForMaven() throws IOException {
if (hashAndFile.length < 2) {
throw new BuildException("Bad line '" + line + "' in " + list);
}

if (MavenCoordinate.isMavenFile(hashAndFile[1])) {
MavenCoordinate coordinate = MavenCoordinate.fromGradleFormat(hashAndFile[1]);
Files.write(moduleparentPom, ("\n <dependency>").getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
Files.write(moduleparentPom, ("\n <groupId>" + coordinate.getGroupId() + "</groupId>").getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
Files.write(moduleparentPom, ("\n <artifactId>" + coordinate.getArtifactId() + "</artifactId>").getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
Files.write(moduleparentPom, ("\n <version>" + coordinate.getVersion() + "</version>").getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
Files.write(moduleparentPom, ("\n <type>" + coordinate.getExtension() + "</type>").getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);

if (coordinate.hasClassifier()) {
Files.write(moduleparentPom, ("\n <classifier>" + coordinate.getClassifier() + "</classifier>").getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
if (duplicatecheck.add(MavenGA.from(coordinate))) {
Files.write(moduleparentPom, ("\n <dependency>").getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
Files.write(moduleparentPom, ("\n <groupId>" + coordinate.getGroupId() + "</groupId>").getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
Files.write(moduleparentPom, ("\n <artifactId>" + coordinate.getArtifactId() + "</artifactId>").getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
Files.write(moduleparentPom, ("\n <version>" + coordinate.getVersion() + "</version>").getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
Files.write(moduleparentPom, ("\n <type>" + coordinate.getExtension() + "</type>").getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);

if (coordinate.hasClassifier()) {
Files.write(moduleparentPom, ("\n <classifier>" + coordinate.getClassifier() + "</classifier>").getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
}
Files.write(moduleparentPom, ("\n </dependency>").getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
}
Files.write(moduleparentPom, ("\n </dependency>").getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
}
}
}
Expand All @@ -160,53 +179,73 @@ private void buildLibPomForMaven() throws IOException {

}
}
// write clusters pom
for (Map.Entry<String, Set<String>> clusterEntry : clusters.entrySet()) {
String clusterName = clusterEntry.getKey();
Path clusterFolder = pseudoMavendirectory.resolve(clusterName) ;
Files.write(parentPom, ("\n <module>" + clusterName + "</module>").getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);

Path clusterparentPom = Files.createFile(clusterFolder.resolve("pom.xml"));
Files.write(clusterparentPom, ("""
<project>
<modelVersion>4.0.0</modelVersion>
<parent><groupId>pseudo.org.netbeans</groupId><artifactId>netbeans</artifactId><version>1</version></parent>
<artifactId>""" + clusterName + "</artifactId><packaging>pom</packaging>").getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE, StandardOpenOption.APPEND);
if (!clusterEntry.getValue().isEmpty()) {
Files.write(clusterparentPom, "\n <modules>".getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
for (String module : clusterEntry.getValue()) {
Files.write(clusterparentPom, ("\n <module>" + module + "</module>").getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);

}
Files.write(clusterparentPom, "\n </modules>".getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
}
Files.write(clusterparentPom, "</project>".getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
}
// parent pom with plugin for report owasp
Files.write(parentPom, "\n </modules>".getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
Files.write(parentPom, ("\n <build>\n"
+ " <pluginManagement>\n"
+ " <plugins>\n"
+ " <plugin>\n"
+ " <artifactId>maven-site-plugin</artifactId>\n"
+ " <version>4.0.0-M1</version>\n"
+ " </plugin>\n"
+ " </plugins>\n"
+ " </pluginManagement>\n"
+ " </build>").getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);

Files.write(parentPom, ("\n <reporting>\n"
+ " <plugins>\n"
+ " <plugin>\n"
+ " <groupId>org.owasp</groupId>\n"
+ " <artifactId>dependency-check-maven</artifactId>\n"
+ " <version>7.1.0</version>\n"
+ " <configuration>\n"
+ " <assemblyAnalyzerEnabled>false</assemblyAnalyzerEnabled>\n"
+ " <failOnError>false</failOnError>\n"
+ " </configuration>\n"
+ " <reportSets>\n"
+ " <reportSet>\n"
+ " <reports>\n"
+ " <report>aggregate</report>\n"
+ " </reports>\n"
+ " </reportSet>\n"
+ " </reportSets>\n"
+ " </plugin>\n"
+ " \n"
+ " <plugin>\n"
+ " <groupId>org.codehaus.mojo</groupId>\n"
+ " <artifactId>versions-maven-plugin</artifactId>\n"
+ " <version>2.11.0</version>\n"
+ " <reportSets>\n"
+ " <reportSet>\n"
+ " <reports>\n"
+ " <report>dependency-updates-report</report>\n"
+ " </reports>\n"
+ " </reportSet>\n"
+ " </reportSets>\n"
+ " </plugin>\n"
+ " </plugins>\n"
+ " </reporting>").getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
Files.write(parentPom, ("""
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.22.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>""").getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);

Files.write(parentPom, ("""
<reporting>
<plugins>
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>13.0.0</version>
<configuration>
<assemblyAnalyzerEnabled>false</assemblyAnalyzerEnabled>
<failOnError>false</failOnError>
</configuration>
<reportSets>
<reportSet>
<reports>
<report>aggregate</report>
</reports>
</reportSet>
</reportSets>
</plugin>
</plugins>
</reporting>""").getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
Files.write(parentPom, "</project>".getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);

}

record MavenGA(String groupId, String artifactId) {

private static MavenGA from(MavenCoordinate coordinate) {
return new MavenGA(coordinate.getGroupId(), coordinate.getArtifactId());
}

}

}
2 changes: 1 addition & 1 deletion nbbuild/build.properties
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ test.user.dir=testuserdir
nb.run.validation=true
build.compiler.debug=on

bootstrap.jdk.release=11
bootstrap.jdk.release=17
# Options to pass to NetBeans when starting it with "ant tryme":
tryme.arg.hack=-J-Dnetbeans.full.hack=true

Expand Down
4 changes: 2 additions & 2 deletions nbbuild/nbproject/project.xml
Original file line number Diff line number Diff line change
Expand Up @@ -211,14 +211,14 @@
<classpath mode="compile">${ant.core.lib}:${nb_all}/platform/javahelp/external/jhall-2.0_05.jar:${nb_all}/nbbuild/external/json-simple-1.1.1.jar:${nb_all}/nbbuild/external/jsoup-1.15.3.jar</classpath>
<built-to>${nb.build.dir}/antclasses</built-to>
<built-to>${nbantext.jar}</built-to>
<source-level>11</source-level>
<source-level>17</source-level>
</compilation-unit>
<compilation-unit>
<package-root>test/unit/src</package-root>
<unit-tests/>
<classpath mode="compile">${test.unit.cp}</classpath>
<built-to>${nb.build.dir}/test/unit/classes</built-to>
<source-level>11</source-level>
<source-level>17</source-level>
</compilation-unit>
</java-data>
</configuration>
Expand Down
Loading