﻿<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <packaging>pom</packaging>

    <groupId>io.github.berrywang1996</groupId>
    <artifactId>netty-spring-parent</artifactId>
    <version>1.10.0</version>

    <name>netty-spring-parent</name>
    <description>
        Spring Boot integration for Netty — HTTP MVC, WebSocket, application-layer crypto,
        observability (Micrometer / Actuator / MDC) and production-ready connection lifecycle.
    </description>
    <url>https://github.com/BerryWang1996/netty-spring</url>

    <modules>
        <module>netty-spring-web</module>
        <module>netty-spring-webmvc</module>
        <module>netty-spring-websocket</module>
        <module>netty-spring-websocket-cluster</module>
        <module>netty-spring-boot-autoconfigure</module>
        <module>netty-web-spring-boot-starter</module>
        <module>netty-webmvc-spring-boot-starter</module>
        <module>netty-websocket-spring-boot-starter</module>
        <module>netty-websocket-cluster-spring-boot-starter</module>
        <module>demo-netty-web-spring-boot-starter</module>
    </modules>

    <developers>
        <developer>
            <name>wangbor</name>
            <email>wangbor@yeah.net</email>
            <url>https://github.com/BerryWang1996</url>
        </developer>
    </developers>

    <licenses>
        <license>
            <name>Apache License, Version 2.0</name>
            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
            <distribution>repo</distribution>
        </license>
    </licenses>

    <scm>
        <connection>scm:git:git://github.com/BerryWang1996/netty-spring.git</connection>
        <developerConnection>scm:git:ssh://git@github.com/BerryWang1996/netty-spring.git</developerConnection>
        <url>https://github.com/BerryWang1996/netty-spring</url>
        <tag>HEAD</tag>
    </scm>

    <properties>
        <java.version>17</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.compiler.release>${java.version}</maven.compiler.release>
        <!-- runtime  -->
        <netty.version>4.1.134.Final</netty.version>
        <spring-boot.version>2.7.18</spring-boot.version>
        <!-- test only: Spring Boot 2.7.x BOM does not manage testcontainers (Boot 3.1+ does) -->
        <testcontainers.version>1.20.4</testcontainers.version>
        <!-- optional NATS client — only pulled in by the NATS cluster broker impl -->
        <jnats.version>2.20.4</jnats.version>
        <!-- activation -->
        <activation.version>1.1.1</activation.version>
        <!-- provided -->
        <lombok.version>1.18.38</lombok.version>
        <!-- build -->
        <maven-compiler-plugin.version>3.13.0</maven-compiler-plugin.version>
        <maven-surefire-plugin.version>3.2.5</maven-surefire-plugin.version>
        <maven-deploy-plugin.version>3.1.2</maven-deploy-plugin.version>
        <cyclonedx-maven-plugin.version>2.9.1</cyclonedx-maven-plugin.version>
        <dependency-check-maven.version>12.2.1</dependency-check-maven.version>
        <dependency-check.fail-build-on-cvss>7.0</dependency-check.fail-build-on-cvss>

        <!-- GPG signing key — full fingerprint of the publisher's key.
             Override on the command line if you fork: -Dgpg.keyname=YOUR_KEY -->
        <gpg.keyname>09CC1D729D9E1CBBA18DE39E8B24A2A210E4168C</gpg.keyname>
        <!-- Path to the GPG executable that owns the keyring with the above key.
             Defaults to `gpg` on PATH. On the project maintainer's Windows machine
             the Git Bash bundled gpg uses a different keyring, so point at Gpg4win:
             override per environment via -Dgpg.executable=... -->
        <gpg.executable>gpg</gpg.executable>
    </properties>

    <dependencyManagement>
        <dependencies>

            <!-- netty managed versions -->
            <dependency>
                <groupId>io.netty</groupId>
                <artifactId>netty-bom</artifactId>
                <version>${netty.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!--
              logback 1.2.13 override: Spring Boot 2.7.18 BOM pins logback 1.2.12, which
              still has CVE-2023-6378 (serialization vulnerability in SocketReceiver /
              SocketAppender). 1.2.13 is the last 1.2.x release and ships the fix. Declared
              BEFORE spring-boot-dependencies so this version wins.
            -->
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-classic</artifactId>
                <version>1.2.13</version>
            </dependency>
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-core</artifactId>
                <version>1.2.13</version>
            </dependency>

            <!--
              spring-framework 5.3.39 override: Spring Boot 2.7.18 BOM pins Spring Framework
              5.3.31, which has several advisories fixed later in the 5.3.x line — CVE-2024-22243 /
              CVE-2024-22259 / CVE-2024-22262 (UriComponentsBuilder open-redirect / SSRF) and
              CVE-2024-38809 / CVE-2024-38816 / CVE-2024-38820 (content-negotiation DoS, static-
              resource path traversal, data-binding). 5.3.39 is the last 5.3.x release (EOL line)
              and ships all fixes; it is ABI-compatible with Boot 2.7.18. Imported BEFORE
              spring-boot-dependencies so these versions win.
            -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-framework-bom</artifactId>
                <version>5.3.39</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!--
              snakeyaml 1.33 override: Spring Boot 2.7.18 BOM pins snakeyaml 1.30, vulnerable to
              CVE-2022-38751 / CVE-2022-38752 / CVE-2022-41854 (stack-overflow / DoS on untrusted
              YAML). 1.33 is the last 1.x release with the DoS fixes (used by Boot for
              application.yml parsing). Declared BEFORE spring-boot-dependencies so it wins.
            -->
            <dependency>
                <groupId>org.yaml</groupId>
                <artifactId>snakeyaml</artifactId>
                <version>1.33</version>
            </dependency>

            <!-- spring boot managed versions -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!--
              testcontainers managed versions — TEST scope only. Spring Boot 2.7.x's BOM does NOT
              manage testcontainers (that began in Boot 3.1), so we import its BOM here. Used solely
              by the two cluster modules' integration tests to provision a fallback Redis in CI; it
              never appears on any main/runtime classpath or in a published artifact.
            -->
            <dependency>
                <groupId>org.testcontainers</groupId>
                <artifactId>testcontainers-bom</artifactId>
                <version>${testcontainers.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- NATS client (optional cluster transport) -->
            <dependency>
                <groupId>io.nats</groupId>
                <artifactId>jnats</artifactId>
                <version>${jnats.version}</version>
            </dependency>

            <!-- lombok -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
                <scope>provided</scope>
            </dependency>

            <!-- activation -->
            <dependency>
                <groupId>javax.activation</groupId>
                <artifactId>activation</artifactId>
                <version>${activation.version}</version>
            </dependency>

        </dependencies>
    </dependencyManagement>

    <dependencies>

        <!-- log -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!-- test -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>${maven-compiler-plugin.version}</version>
                    <configuration>
                        <release>${maven.compiler.release}</release>
                        <encoding>${project.build.sourceEncoding}</encoding>
                        <parameters>true</parameters>
                        <annotationProcessorPaths>
                            <path>
                                <groupId>org.projectlombok</groupId>
                                <artifactId>lombok</artifactId>
                                <version>${lombok.version}</version>
                            </path>
                        </annotationProcessorPaths>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>${maven-surefire-plugin.version}</version>
                    <configuration>
                        <useModulePath>false</useModulePath>
                        <!-- Pin docker-java's negotiated Docker API version for Testcontainers. docker-java
                             3.4.0 first-probes /v1.32, which modern Docker (29.x, minAPIVersion 1.40) rejects
                             with HTTP 400, so DockerClientFactory reports "no valid Docker environment" and the
                             cluster Testcontainers ITs (Redis / NATS / JetStream) SKIP even though Docker is
                             live. Setting api.version at JVM start — before Testcontainers' first probe — fixes
                             it reliably in every surefire fork (the static-initializer fallback in the test
                             resolvers is class-load-order racy). 1.43 is within [1.40, current]. -->
                        <systemPropertyVariables>
                            <api.version>1.43</api.version>
                        </systemPropertyVariables>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-deploy-plugin</artifactId>
                    <version>${maven-deploy-plugin.version}</version>
                </plugin>
            </plugins>
        </pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <profiles>
        <profile>
            <id>sbom</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.cyclonedx</groupId>
                        <artifactId>cyclonedx-maven-plugin</artifactId>
                        <version>${cyclonedx-maven-plugin.version}</version>
                        <inherited>false</inherited>
                        <configuration>
                            <projectType>library</projectType>
                            <schemaVersion>1.6</schemaVersion>
                            <outputFormat>all</outputFormat>
                            <outputName>netty-spring-sbom</outputName>
                            <outputReactorProjects>false</outputReactorProjects>
                            <includeTestScope>false</includeTestScope>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
        <profile>
            <id>dependency-scan</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.owasp</groupId>
                        <artifactId>dependency-check-maven</artifactId>
                        <version>${dependency-check-maven.version}</version>
                        <inherited>false</inherited>
                        <configuration>
                            <formats>
                                <format>HTML</format>
                                <format>JSON</format>
                                <format>SARIF</format>
                            </formats>
                            <failBuildOnCVSS>${dependency-check.fail-build-on-cvss}</failBuildOnCVSS>
                            <failOnError>true</failOnError>
                            <skipTestScope>true</skipTestScope>
                            <nvdApiKeyEnvironmentVariable>NVD_API_KEY</nvdApiKeyEnvironmentVariable>
                            <dataDirectory>${settings.localRepository}/../dependency-check-data</dataDirectory>
                            <outputDirectory>${project.build.directory}/dependency-check</outputDirectory>
                            <suppressionFiles>
                                <suppressionFile>${maven.multiModuleProjectDirectory}/dependency-check-suppressions.xml</suppressionFile>
                            </suppressionFiles>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>

        <!--
          release profile: Maven Central via Sonatype Central Portal.
          Activate with: mvn deploy -P release
          Requires:
            * a GPG keypair installed locally (the gpg list-secret-keys command must show it)
            * server id="central" in ~/.m2/settings.xml with the Central Portal user token
              (username + password generated at central.sonatype.com)
            * optional server id="gpg.passphrase" with a passphrase element in settings.xml,
              or set GPG_PASSPHRASE env var so gpg-agent picks it up
        -->
        <profile>
            <id>release</id>
            <build>
                <plugins>
                    <!-- 1. Attach sources jar (Central requirement) -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-source-plugin</artifactId>
                        <version>3.3.1</version>
                        <executions>
                            <execution>
                                <id>attach-sources</id>
                                <goals>
                                    <goal>jar-no-fork</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                    <!-- 2. Attach javadoc jar (Central requirement) -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-javadoc-plugin</artifactId>
                        <version>3.10.0</version>
                        <executions>
                            <execution>
                                <id>attach-javadocs</id>
                                <goals>
                                    <goal>jar</goal>
                                </goals>
                            </execution>
                        </executions>
                        <configuration>
                            <!-- Be lenient about old-style Javadoc; project mixes Chinese + English comments -->
                            <doclint>none</doclint>
                            <failOnError>false</failOnError>
                            <source>${java.version}</source>
                            <encoding>${project.build.sourceEncoding}</encoding>
                            <docencoding>${project.build.sourceEncoding}</docencoding>
                            <charset>${project.build.sourceEncoding}</charset>
                        </configuration>
                    </plugin>
                    <!-- 3. PGP sign every artifact (Central requirement).
                         The local GPG key has no passphrase, so we let gpg-agent
                         handle signing without loopback/pinentry interaction.
                         keyname explicitly points to the project's signing key so
                         gpg-plugin 3.2.x's new Signer abstraction doesn't fall back
                         to a non-existent "default" key. -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-gpg-plugin</artifactId>
                        <version>3.2.4</version>
                        <executions>
                            <execution>
                                <id>sign-artifacts</id>
                                <phase>verify</phase>
                                <goals>
                                    <goal>sign</goal>
                                </goals>
                                <configuration>
                                    <keyname>${gpg.keyname}</keyname>
                                    <executable>${gpg.executable}</executable>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                    <!-- 4. Upload bundle to Sonatype Central Portal -->
                    <plugin>
                        <groupId>org.sonatype.central</groupId>
                        <artifactId>central-publishing-maven-plugin</artifactId>
                        <version>0.11.0</version>
                        <extensions>true</extensions>
                        <configuration>
                            <publishingServerId>central</publishingServerId>
                            <!-- false = upload then wait for manual "Publish" click on portal.
                                 Set to true once the workflow is trusted. -->
                            <autoPublish>false</autoPublish>
                            <waitUntil>validated</waitUntil>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>

    <distributionManagement>
        <!--
          Maven Central deployment is handled by central-publishing-maven-plugin
          inside the "release" profile above. This block is intentionally minimal
          and only matters for the rare case of `mvn deploy` without -P release.
          The Aliyun private repository from earlier versions is retired.
        -->
        <repository>
            <id>central</id>
            <name>Sonatype Central Portal</name>
            <url>https://central.sonatype.com/api/v1/publisher</url>
        </repository>
    </distributionManagement>

</project>
