I’m having an issue deploying my Spring Boot JARs to the company’s internal libs-release-local
repository. When I run the mvn deploy:deploy-file
command with the appropriate arguments, it deploys successfully from my workstation:
mvn package deploy:deploy-file -Durl=https://artifactory.domain.com/artifactory/libs-release-local -Dfile=target/my-app-3.0.0.jar -DpomFile=pom.xml -DrepositoryId=central
The above repositoryId
is defined in my home directory’s settings.xml
.
When I run the same command in GitLab CI, I get the following:
[INFO] Uploading to central: https://artifactory.domain.com/artifactory/libs-release-local/com/company/ui/my-app/3.0.0/my-app-3.0.0.jar [WARNING] Failed to upload checksum com/company/ui/my-app/3.0.0/my-app-3.0.0.jar.md5: Authorization failed for https://artifactory.domain.com/artifactory/libs-release-local/com/company/ui/my-app/3.0.0/my-app-3.0.0.jar.md5 403 Forbidden org.apache.maven.wagon.authorization.AuthorizationException: Authorization failed for https://artifactory.domain.com/artifactory/libs-release-local/com/company/ui/my-app/3.0.0/my-app-3.0.0.jar.md5 403 Forbidden
Both myself and our service account are configured with the same permissions in the User Management
section of Artifactory. Even though I see 403 Forbidden
above, the jar
file still uploads to Artifactory successfully, however the .jar.md5
and .pom
files fail with 403 Forbidden
. I don’t see these errors when running within IntelliJ.
Additionally, deploying a SNAPSHOT
jar to our snapshot repository completes successfully.
settings.xml
<?xml version="1.0" encoding="UTF-8"?> <settings xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd" xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <localRepository>/root/.m2/repository</localRepository> <interactiveMode>false</interactiveMode> <servers> <server> <username>${env.MAVEN_REPO_USER}</username> <password>${env.MAVEN_REPO_PASS}</password> <id>central</id> </server> <server> <username>${env.MAVEN_REPO_USER}</username> <password>${env.MAVEN_REPO_PASS}</password> <id>central-snapshots</id> </server> </servers> <profiles> <profile> <repositories> <repository> <snapshots> <enabled>false</enabled> </snapshots> <id>central</id> <name>libs-release</name> <url>https://artifactory.company.com/artifactory/libs-release</url> </repository> <repository> <snapshots/> <id>central-snapshots</id> <name>libs-snapshot</name> <url>https://artifactory.company.com/artifactory/libs-snapshot</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <snapshots> <enabled>false</enabled> </snapshots> <id>central</id> <name>libs-release</name> <url>https://artifactory.company.com/artifactory/libs-release</url> </pluginRepository> <pluginRepository> <snapshots/> <id>central-snapshots</id> <name>libs-snapshot</name> <url>https://artifactory.company.com/artifactory/libs-snapshot</url> </pluginRepository> </pluginRepositories> <properties> <altSnapshotDeploymentRepository> central-snapshots::default::https://artifactory.company.com/artifactory/libs-snapshot-local/ </altSnapshotDeploymentRepository> <altReleaseDeploymentRepository> central::default::https://artifactory.company.com/artifactory/libs-release-local/ </altReleaseDeploymentRepository> </properties> <id>artifactory</id> </profile> </profiles> <activeProfiles> <activeProfile>artifactory</activeProfile> </activeProfiles> </settings>
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <groupId>com.company.ui</groupId> <artifactId>my-app</artifactId> <version>3.0.0</version> <packaging>jar</packaging> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.3</version> </parent> <properties> <argLine/> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <groovy.version>3.0.12</groovy.version> <spock.version>2.1-groovy-3.0</spock.version> <checkmarx.version>8.90.2</checkmarx.version> <jacoco.version>0.8.7</jacoco.version> </properties> <dependencies> <dependency> <groupId>org.codehaus.groovy</groupId> <artifactId>groovy-all</artifactId> <version>${groovy.version}</version> <scope>compile</scope> <type>pom</type> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> <scope>compile</scope> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-reactor-netty</artifactId> <scope>compile</scope> </dependency> <dependency> <groupId>com.okta.spring</groupId> <artifactId>okta-spring-boot-starter</artifactId> <version>2.1.6</version> </dependency> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-core</artifactId> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> <dependency> <groupId>io.projectreactor.rabbitmq</groupId> <artifactId>reactor-rabbitmq</artifactId> <version>1.5.2</version> </dependency> <dependency> <groupId>io.pivotal.cfenv</groupId> <artifactId>java-cfenv-boot</artifactId> <version>2.4.0</version> </dependency> <!-- test dependencies --> <dependency> <groupId>org.spockframework</groupId> <artifactId>spock-core</artifactId> <version>${spock.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.spockframework</groupId> <artifactId>spock-spring</artifactId> <version>${spock.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>mockwebserver</artifactId> <version>4.9.0</version> <scope>test</scope> </dependency> <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>4.9.0</version> <scope>test</scope> </dependency> <dependency> <groupId>io.projectreactor</groupId> <artifactId>reactor-test</artifactId> <version>3.1.0.RELEASE</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-test</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>2021.0.3</version> <scope>import</scope> <type>pom</type> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${project.parent.version}</version> <scope>import</scope> <type>pom</type> </dependency> </dependencies> </dependencyManagement> <build> <!-- https://stackoverflow.com/questions/21358403/spring-boot-project-with-static-content-generates-404-when-running-jar --> <resources> <resource> <directory>src/main/resources</directory> </resource> <resource> <directory>./client/dist</directory> <includes> <include>**/*.*</include> </includes> <targetPath>static</targetPath> </resource> </resources> <plugins> <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>${jacoco.version}</version> <executions> <execution> <id>default-prepare-agent</id> <goals> <goal>prepare-agent</goal> </goals> </execution> <execution> <id>default-report</id> <phase>test</phase> <goals> <goal>report</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.codehaus.gmavenplus</groupId> <artifactId>gmavenplus-plugin</artifactId> <version>1.5</version> <configuration> <targetBytecode>11</targetBytecode> <sources> <source> <directory>src/main/groovy</directory> <includes> <include>**/*.groovy</include> </includes> </source> <source> <directory>${project.basedir}/target/generated-sources/openapi/src/gen/java/main</directory> <includes> <include>**/*.groovy</include> </includes> </source> </sources> </configuration> <executions> <execution> <goals> <goal>addSources</goal> <goal>compile</goal> <goal>addTestSources</goal> <goal>testCompile</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.0.0-M5</version> <configuration> <includes> <!-- By default only files ending in 'Test' will be included, so also include support for Spock style naming convention --> <!-- Oddly enough for Groovy files, *Spec.groovy does not work, but *Spec.java does --> <include>**/*Test.java</include> <include>**/*Spec.java</include> </includes> </configuration> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.0.0</version> <executions> <execution> <id>npm config set strict-ssl false</id> <phase>generate-resources</phase> <goals> <goal>exec</goal> </goals> <configuration> <executable>npm</executable> <workingDirectory>./client</workingDirectory> <arguments> <argument>config</argument> <argument>set</argument> <argument>strict-ssl</argument> <argument>false</argument> </arguments> </configuration> </execution> <execution> <id>npm install</id> <phase>generate-resources</phase> <goals> <goal>exec</goal> </goals> <configuration> <executable>npm</executable> <workingDirectory>./client</workingDirectory> <arguments> <argument>install</argument> </arguments> </configuration> </execution> <execution> <id>npm run build</id> <phase>generate-resources</phase> <goals> <goal>exec</goal> </goals> <configuration> <executable>npm</executable> <workingDirectory>./client</workingDirectory> <arguments> <argument>run</argument> <argument>build</argument> </arguments> </configuration> </execution> <execution> <id>npm run coverage</id> <phase>test</phase> <goals> <goal>exec</goal> </goals> <configuration> <skip>${maven.test.skip}</skip> <executable>npm</executable> <workingDirectory>./client</workingDirectory> <arguments> <argument>run</argument> <argument>coverage</argument> </arguments> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
Advertisement
Answer
I ended up using the standard mvn deploy
command instead of deploy-file
. I’m not sure why, but deploy-file
would return HTTP 403 Forbidden
whereas deploy
publishes the package successfully.