- GitLab 패키지 레지스트리에 게시하기
- 패키지 배포
- 패키지 설치
- Maven 패키지를 위한 CI/CD 통합
- 유용한 힌트
-
문제 해결
- 캐시 삭제
- 네트워크 추적 로그 검토
- Maven 설정 확인
- 패키지 게시 시 “401 Unauthorized” 오류
- “400 Bad Request” 오류: “Validation failed: Version is invalid” 메시지
- 게시할 때 “Artifact already exists” 오류
- UI에 게시한 패키지가 나타나지 않음
- Maven 저장소 의존성 충돌
- “Unable to find valid certification path to requested target” 오류
- “No plugin found for prefix” 파이프라인 오류
Maven 패키지 레지스트리의 Maven 패키지
프로젝트의 패키지 레지스트리에 Maven 아티팩트를 게시하세요.
그런 다음 종속성으로 사용할 때 필요할 때마다 패키지를 설치하세요.
Maven 패키지 관리자 클라이언트가 사용하는 특정 API 엔드포인트에 대한 문서는 Maven API 문서를 참조하세요.
지원되는 클라이언트:
GitLab 패키지 레지스트리에 게시하기
패키지 레지스트리에 인증하기
패키지를 게시하기 위해서는 토큰이 필요합니다. 목표에 따라 사용할 수 있는 다양한 토큰이 있습니다. 추가 정보는 토큰에 대한 가이드를 검토하세요.
토큰을 생성하고 나중에 프로세스에서 사용할 수 있도록 저장하세요.
여기 문서화된 방법 이외의 인증 방법은 사용하지 마세요. 문서화되지 않은 인증 방법은 향후 제거될 수 있습니다.
클라이언트 구성 수정
구성을 업데이트하여 HTTP를 사용하여 Maven 리포지토리에 인증하세요.
사용자 정의 HTTP 헤더
클라이언트의 구성 파일에 인증 세부정보를 추가해야 합니다.
mvn
토큰 유형 | 이름은 반드시 | 토큰 |
---|---|---|
개인 액세스 토큰 | Private-Token |
그대로 토큰을 붙여넣거나 토큰을 보관할 환경 변수를 정의하세요. |
배포 토큰 | Deploy-Token |
그대로 토큰을 붙여넣거나 토큰을 보관할 환경 변수를 정의하세요. |
CI 작업 토큰 | Job-Token |
${CI_JOB_TOKEN} |
참고:
<name>
필드는 선택한 토큰에 맞게 명명해야 합니다.
다음 섹션을 settings.xml
파일에 추가하세요.
<settings>
<servers>
<server>
<id>gitlab-maven</id>
<configuration>
<httpHeaders>
<property>
<name>REPLACE_WITH_NAME</name>
<value>REPLACE_WITH_TOKEN</value>
</property>
</httpHeaders>
</configuration>
</server>
</servers>
</settings>
gradle
토큰 유형 | 이름은 반드시 | 토큰 |
---|---|---|
개인 액세스 토큰 | Private-Token |
그대로 토큰을 붙여넣거나 토큰을 보관할 환경 변수를 정의하세요. |
배포 토큰 | Deploy-Token |
그대로 토큰을 붙여넣거나 토큰을 보관할 환경 변수를 정의하세요. |
CI 작업 토큰 | Job-Token |
System.getenv("CI_JOB_TOKEN") |
참고:
<name>
필드는 선택한 토큰에 맞게 명명해야 합니다.
your GRADLE_USER_HOME
디렉토리에서 gradle.properties
라는 파일을 생성하고 다음 내용을 추가하세요.
gitLabPrivateToken=REPLACE_WITH_YOUR_TOKEN
build.gradle
파일에 repositories
섹션을 추가하세요:
-
Groovy DSL에서:
repositories { maven { url "https://gitlab.example.com/api/v4/groups/<group>/-/packages/maven" name "GitLab" credentials(HttpHeaderCredentials) { name = 'REPLACE_WITH_NAME' value = gitLabPrivateToken } authentication { header(HttpHeaderAuthentication) } } }
-
Kotlin DSL에서:
repositories { maven { url = uri("https://gitlab.example.com/api/v4/groups/<group>/-/packages/maven") name = "GitLab" credentials(HttpHeaderCredentials::class) { name = "REPLACE_WITH_NAME" value = findProperty("gitLabPrivateToken") as String? } authentication { create("header", HttpHeaderAuthentication::class) } } }
기본 HTTP 인증
Maven 패키지 레지스트리에 인증하기 위해 기본 HTTP 인증을 사용할 수도 있습니다.
mvn
토큰 유형 | 이름은 반드시 | 토큰 |
---|---|---|
개인 액세스 토큰 | 사용자의 사용자 이름 | 있는 그대로 토큰을 붙여넣거나 토큰을 저장할 환경 변수를 정의하세요 |
배포 토큰 | 배포 토큰의 사용자 이름 | 있는 그대로 토큰을 붙여넣거나 토큰을 저장할 환경 변수를 정의하세요 |
CI 작업 토큰 | gitlab-ci-token |
${CI_JOB_TOKEN} |
다음 섹션을 settings.xml
파일에 추가하세요.
<settings>
<servers>
<server>
<id>gitlab-maven</id>
<username>REPLACE_WITH_NAME</username>
<password>REPLACE_WITH_TOKEN</password>
<configuration>
<authenticationInfo>
<userName>REPLACE_WITH_NAME</userName>
<password>REPLACE_WITH_TOKEN</password>
</authenticationInfo>
</configuration>
</server>
</servers>
</settings>
gradle
토큰 유형 | 이름은 반드시 | 토큰 |
---|---|---|
개인 액세스 토큰 | 사용자의 사용자 이름 | 있는 그대로 토큰을 붙여넣거나 토큰을 저장할 환경 변수를 정의하세요 |
배포 토큰 | 배포 토큰의 사용자 이름 | 있는 그대로 토큰을 붙여넣거나 토큰을 저장할 환경 변수를 정의하세요 |
CI 작업 토큰 | gitlab-ci-token |
System.getenv("CI_JOB_TOKEN") |
당신의 GRADLE_USER_HOME
디렉토리에서 다음 내용으로 gradle.properties
파일을 생성하세요:
gitLabPrivateToken=REPLACE_WITH_YOUR_TOKEN
build.gradle
파일에 repositories
섹션을 추가하세요.
-
Groovy DSL에서:
repositories { maven { url "https://gitlab.example.com/api/v4/groups/<group>/-/packages/maven" name "GitLab" credentials(PasswordCredentials) { username = 'REPLACE_WITH_NAME' password = gitLabPrivateToken } authentication { basic(BasicAuthentication) } } }
-
Kotlin DSL에서:
repositories { maven { url = uri("https://gitlab.example.com/api/v4/groups/<group>/-/packages/maven") name = "GitLab" credentials(BasicAuthentication::class) { username = "REPLACE_WITH_NAME" password = findProperty("gitLabPrivateToken") as String? } authentication { create("basic", BasicAuthentication::class) } } }
sbt
토큰 유형 | 이름은 반드시 | 토큰 |
---|---|---|
개인 액세스 토큰 | 사용자의 사용자 이름 | 있는 그대로 토큰을 붙여넣거나 토큰을 저장할 환경 변수를 정의하세요 |
배포 토큰 | 배포 토큰의 사용자 이름 | 있는 그대로 토큰을 붙여넣거나 토큰을 저장할 환경 변수를 정의하세요 |
CI 작업 토큰 | gitlab-ci-token |
sys.env.get("CI_JOB_TOKEN").get |
SBT에 대한 인증은 기본 HTTP 인증을 기반으로 합니다.
이름과 비밀번호를 제공해야 합니다.
참고: 이름 필드는 선택한 토큰과 일치해야 합니다.
sbt
를 사용하여 Maven GitLab 패키지 레지스트리에서 패키지를 설치하려면 Maven 리졸버를 구성해야 합니다.
비공식 또는 내부 프로젝트나 그룹에 접근하는 경우 자격 증명을 설정해야 합니다.
리졸버 및 인증 구성이 완료된 후 프로젝트, 그룹 또는 네임스페이스에서 패키지를 설치할 수 있습니다.
build.sbt
에서 다음 줄을 추가하세요:
resolvers += ("gitlab" at "<endpoint url>")
credentials += Credentials("GitLab Packages Registry", "<host>", "<name>", "<token>")
이 예에서:
-
<endpoint url>
은 엔드포인트 URL입니다. 예:https://gitlab.example.com/api/v4/projects/<project_id>/packages/maven
. -
<host>
는 프로토콜 스킴이나 포트 없이<endpoint url>
에 있는 호스트입니다. 예:gitlab.example.com
. -
<name>
과<token>
은 위 표에서 설명되어 있습니다.
명명 규칙
Maven 패키지를 설치하기 위해 세 가지 엔드포인트 중 하나를 사용할 수 있습니다. 패키지는 프로젝트에 게시해야 하지만, 선택한 엔드포인트에 따라 pom.xml
파일에 추가하는 설정이 결정됩니다.
세 가지 엔드포인트는 다음과 같습니다:
- 프로젝트 수준: Maven 패키지가 몇 개 없고, 동일한 GitLab 그룹에 포함되지 않을 때 사용합니다.
- 그룹 수준: 동일한 GitLab 그룹 내의 여러 다른 프로젝트에서 패키지를 설치하려고 할 때 사용합니다. GitLab은 그룹 내에서 패키지 이름의 고유성을 보장하지 않습니다. 동일한 패키지 이름과 패키지 버전을 가진 두 개의 프로젝트가 있을 수 있습니다. 결과적으로 GitLab은 최신 패키지를 제공합니다.
- 인스턴스 수준: 서로 다른 GitLab 그룹 또는 자체 네임스페이스에 여러 패키지가 있을 때 사용합니다.
인스턴스 수준 엔드포인트의 경우, Maven의 pom.xml
관련 섹션은 다음과 같아야 합니다:
<groupId>group-slug.subgroup-slug</groupId>
<artifactId>project-slug</artifactId>
프로젝트와 동일한 경로를 가진 패키지만 인스턴스 수준 엔드포인트에서 노출됩니다.
프로젝트 | 패키지 | 인스턴스 수준 엔드포인트 사용 가능 |
---|---|---|
foo/bar |
foo/bar/1.0-SNAPSHOT |
예 |
gitlab-org/gitlab |
foo/bar/1.0-SNAPSHOT |
아니오 |
gitlab-org/gitlab |
gitlab-org/gitlab/1.0-SNAPSHOT |
예 |
엔드포인트 URL
엔드포인트 |
pom.xml 의 엔드포인트 URL |
추가 정보 |
---|---|---|
프로젝트 | https://gitlab.example.com/api/v4/projects/<project_id>/packages/maven |
gitlab.example.com 을 도메인 이름으로 교체합니다. <project_id> 를 프로젝트 개요 페이지에서 찾은 프로젝트 ID로 교체합니다. |
그룹 | https://gitlab.example.com/api/v4/groups/<group_id>/-/packages/maven |
gitlab.example.com 을 도메인 이름으로 교체합니다. <group_id> 를 해당 그룹의 홈페이지에서 찾은 그룹 ID로 교체합니다. |
인스턴스 | https://gitlab.example.com/api/v4/packages/maven |
gitlab.example.com 을 도메인 이름으로 교체합니다. |
게시를 위한 구성 파일 편집
클라이언트의 구성 파일에 게시 세부정보를 추가해야 합니다.
mvn
어떤 엔드포인트를 선택하든, 다음을 갖추어야 합니다:
-
distributionManagement
섹션에 프로젝트 전용 URL. -
repository
및distributionManagement
섹션.
Maven의 pom.xml
에 관련된 repository
섹션은 다음과 같아야 합니다:
<repositories>
<repository>
<id>gitlab-maven</id>
<url><your_endpoint_url></url>
</repository>
</repositories>
<distributionManagement>
<repository>
<id>gitlab-maven</id>
<url>https://gitlab.example.com/api/v4/projects/<project_id>/packages/maven</url>
</repository>
<snapshotRepository>
<id>gitlab-maven</id>
<url>https://gitlab.example.com/api/v4/projects/<project_id>/packages/maven</url>
</snapshotRepository>
</distributionManagement>
-
id
는 settings.xml에서 정의한 내용입니다. -
<your_endpoint_url>
은 선택한 엔드포인트에 따라 다릅니다. -
gitlab.example.com
을 도메인 이름으로 교체합니다.
gradle
Gradle을 사용하여 패키지를 게시하려면:
-
Gradle 플러그인
maven-publish
를 플러그인 섹션에 추가합니다:-
Groovy DSL에서:
plugins { id 'java' id 'maven-publish' }
-
Kotlin DSL에서:
plugins { java `maven-publish` }
-
-
publishing
섹션을 추가합니다:-
Groovy DSL에서:
publishing { publications { library(MavenPublication) { from components.java } } repositories { maven { url "https://gitlab.example.com/api/v4/projects/<PROJECT_ID>/packages/maven" credentials(HttpHeaderCredentials) { name = "REPLACE_WITH_TOKEN_NAME" value = gitLabPrivateToken // 변수는 $GRADLE_USER_HOME/gradle.properties에 있습니다. } authentication { header(HttpHeaderAuthentication) } } } }
-
Kotlin DSL에서:
publishing { publications { create<MavenPublication>("library") { from(components["java"]) } } repositories { maven { url = uri("https://gitlab.example.com/api/v4/projects/<PROJECT_ID>/packages/maven") credentials(HttpHeaderCredentials::class) { name = "REPLACE_WITH_TOKEN_NAME" value = findProperty("gitLabPrivateToken") as String? // 변수는 $GRADLE_USER_HOME/gradle.properties에 있습니다. } authentication { create("header", HttpHeaderAuthentication::class) } } } }
-
패키지 배포
경고:
DeployAtEnd
옵션을 사용하면 400 bad request {"message":"Validation failed: Name has already been taken"}
오류로 업로드가 거부될 수 있습니다. 자세한 내용은 문제 424238를 참조하세요.
인증을 설정하고 게시를 위한 엔드포인트를 선택한 후, Maven 패키지를 프로젝트에 배포하세요.
mvn
Maven을 사용하여 패키지를 배포하려면:
mvn deploy
배포가 성공하면 빌드 성공 메시지가 표시되어야 합니다:
...
[INFO] BUILD SUCCESS
...
메시지는 패키지가 올바른 위치에 배포되었음을 보여야 합니다:
Uploading to gitlab-maven: https://example.com/api/v4/projects/PROJECT_ID/packages/maven/com/mycompany/mydepartment/my-project/1.0-SNAPSHOT/my-project-1.0-20200128.120857-1.jar
gradle
publish 작업을 실행합니다:
gradle publish
프로젝트의 Packages and registries 페이지로 이동하여 배포된 패키지를 확인합니다.
sbt
build.sbt
파일에서 publishTo
설정을 구성합니다:
publishTo := Some("gitlab" at "<endpoint url>")
자격 증명이 올바르게 참조되었는지 확인하십시오. 더 많은 정보는 sbt
문서를 참조하세요.
sbt
를 사용하여 패키지를 배포하려면:
sbt publish
배포가 성공하면 빌드 성공 메시지가 표시됩니다:
[success] Total time: 1 s, completed Jan 28, 2020 12:08:57 PM
성공 메시지를 확인하여 패키지가 올바른 위치에 배포되었는지 확인합니다:
[info] published my-project_2.12 to https://gitlab.example.com/api/v4/projects/PROJECT_ID/packages/maven/com/mycompany/my-project_2.12/0.1.1-SNAPSHOT/my-project_2.12-0.1.1-SNAPSHOT.pom
패키지 설치
GitLab 패키지 레지스트리에서 패키지를 설치하려면 원격을 구성하고 인증해야 합니다.
이 작업이 완료되면 프로젝트, 그룹 또는 네임스페이스에서 패키지를 설치할 수 있습니다.
동일한 이름과 버전을 가진 여러 패키지가 있는 경우 가장 최근에 배포된 패키지가 검색됩니다.
가장 최근에 배포된 패키지를 읽을 수 있는 권한이 없으면 403 Forbidden
이 반환됩니다.
mvn
mvn install
을 사용하여 패키지를 설치하려면:
-
프로젝트의
pom.xml
파일에 종속성을 수동으로 추가합니다. 이전에 생성한 예제를 추가하려면 XML은 다음과 같습니다:<dependency> <groupId>com.mycompany.mydepartment</groupId> <artifactId>my-project</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
-
프로젝트에서 다음을 실행합니다:
mvn install
메시지는 패키지가 패키지 레지스트리에서 다운로드되고 있음을 보여야 합니다:
Downloading from gitlab-maven: http://gitlab.example.com/api/v4/projects/PROJECT_ID/packages/maven/com/mycompany/mydepartment/my-project/1.0-SNAPSHOT/my-project-1.0-20200128.120857-1.pom
Maven dependency:get
명령을 직접 사용하여 패키지를 설치할 수도 있습니다.
-
프로젝트 디렉토리에서 다음을 실행합니다:
mvn dependency:get -Dartifact=com.nickkipling.app:nick-test-app:1.1-SNAPSHOT -DremoteRepositories=gitlab-maven::::<gitlab endpoint url> -s <path to settings.xml>
참고:
명령(gitlab-maven
)과 settings.xml
파일의 리포지토리 ID가 일치해야 합니다.
메시지는 패키지가 패키지 레지스트리에서 다운로드되고 있음을 보여야 합니다:
Downloading from gitlab-maven: http://gitlab.example.com/api/v4/projects/PROJECT_ID/packages/maven/com/mycompany/mydepartment/my-project/1.0-SNAPSHOT/my-project-1.0-20200128.120857-1.pom
gradle
gradle
을 사용하여 패키지를 설치하려면:
-
build.gradle
의 종속성 섹션에 종속성을 추가합니다:-
Groovy DSL:
dependencies { implementation 'com.mycompany.mydepartment:my-project:1.0-SNAPSHOT' }
-
Kotlin DSL:
dependencies { implementation("com.mycompany.mydepartment:my-project:1.0-SNAPSHOT") }
-
-
프로젝트에서 다음을 실행합니다:
gradle install
sbt
sbt
를 사용하여 패키지를 설치하려면:
-
build.sbt
에 인라인 종속성을 추가합니다:libraryDependencies += "com.mycompany.mydepartment" % "my-project" % "8.4"
-
프로젝트에서 다음을 실행합니다:
sbt update
Maven 패키지를 위한 CI/CD 통합
CI/CD를 사용하여 Maven 패키지를 자동으로 빌드, 테스트 및 게시할 수 있습니다.
이 섹션의 예제는 다음과 같은 시나리오를 다룹니다:
- 다중 모듈 프로젝트
- 버전이 있는 릴리즈
- 조건부 게시
- 코드 품질 및 보안 스캔과의 통합
특정 프로젝트 요구 사항에 맞게 이러한 예제를 조정하고 결합할 수 있습니다.
Maven 버전, Java 버전, 및 기타 세부 사항을 프로젝트 요구 사항에 맞게 조정하는 것을 잊지 마세요. 또한, GitLab 패키지 레지스트리에 게시하기 위한 필수 자격 증명 및 설정이 올바르게 구성되어 있는지 확인하세요.
기본 Maven 패키지 빌드 및 게시
이 예제는 Maven 패키지를 빌드하고 게시하는 파이프라인을 구성합니다:
image: maven:3.8.5-openjdk-17
variables:
MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode"
MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"
cache:
paths:
- .m2/repository/
- target/
stages:
- build
- test
- publish
build:
stage: build
script:
- mvn $MAVEN_CLI_OPTS compile
test:
stage: test
script:
- mvn $MAVEN_CLI_OPTS test
publish:
stage: publish
script:
- mvn $MAVEN_CLI_OPTS deploy
rules:
- if: $CI_COMMIT_BRANCH == "main"
병렬 작업이 있는 다중 모듈 Maven 프로젝트
더 큰 프로젝트의 경우 여러 모듈이 있을 때, 병렬 작업을 사용하여 빌드 프로세스를 가속화할 수 있습니다:
image: maven:3.8.5-openjdk-17
variables:
MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode"
MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"
cache:
paths:
- .m2/repository/
- target/
stages:
- build
- test
- publish
build:
stage: build
script:
- mvn $MAVEN_CLI_OPTS compile
test:
stage: test
parallel:
matrix:
- MODULE: [module1, module2, module3]
script:
- mvn $MAVEN_CLI_OPTS test -pl $MODULE
publish:
stage: publish
script:
- mvn $MAVEN_CLI_OPTS deploy
rules:
- if: $CI_COMMIT_BRANCH == "main"
태그가 있는 버전 릴리즈
이 예제는 태그가 푸시될 때 버전 릴리즈를 생성합니다:
image: maven:3.8.5-openjdk-17
variables:
MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode"
MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"
cache:
paths:
- .m2/repository/
- target/
stages:
- build
- test
- publish
- release
build:
stage: build
script:
- mvn $MAVEN_CLI_OPTS compile
test:
stage: test
script:
- mvn $MAVEN_CLI_OPTS test
publish:
stage: publish
script:
- mvn $MAVEN_CLI_OPTS deploy
only:
- main
release:
stage: release
script:
- mvn versions:set -DnewVersion=${CI_COMMIT_TAG}
- mvn $MAVEN_CLI_OPTS deploy
rules:
- if: $CI_COMMIT_TAG
변경 사항에 따른 조건부 게시
이 예제는 특정 파일이 변경될 때만 패키지를 게시합니다:
image: maven:3.8.5-openjdk-17
variables:
MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode"
MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"
cache:
paths:
- .m2/repository/
- target/
stages:
- build
- test
- publish
build:
stage: build
script:
- mvn $MAVEN_CLI_OPTS compile
test:
stage: test
script:
- mvn $MAVEN_CLI_OPTS test
publish:
stage: publish
script:
- mvn $MAVEN_CLI_OPTS deploy
only:
- main
rules:
- changes:
- pom.xml
- src/**/*
코드 품질 및 보안 스캔과의 통합
이 예제는 파이프라인에 코드 품질 검사 및 보안 스캔을 통합합니다:
image: maven:3.8.5-openjdk-17
variables:
MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode"
MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"
include:
- template: Security/SAST.gitlab-ci.yml
- template: Code-Quality.gitlab-ci.yml
cache:
paths:
- .m2/repository/
- target/
stages:
- build
- test
- quality
- publish
build:
stage: build
script:
- mvn $MAVEN_CLI_OPTS compile
test:
stage: test
script:
- mvn $MAVEN_CLI_OPTS test
code_quality:
stage: quality
sast:
stage: quality
publish:
stage: publish
script:
- mvn $MAVEN_CLI_OPTS deploy
rules:
- if: $CI_COMMIT_BRANCH == "main"
유용한 힌트
동일한 이름이나 버전으로 패키지 게시하기
기존 패키지와 동일한 이름 및 버전으로 패키지를 게시하면, 새로운 패키지 파일이 기존 패키지에 추가됩니다.
UI 또는 API를 사용하여 기존 패키지의 이전 자산을 접근하고 볼 수 있습니다.
이전 패키지 버전을 삭제하려면 Packages API 또는 UI를 사용하는 것이 좋습니다.
중복 Maven 패키지를 허용하지 않기
사용자가 중복 Maven 패키지를 게시하지 못하도록 하려면 GraphQl API 또는 UI를 사용할 수 있습니다.
UI에서:
- 왼쪽 사이드바에서 Search or go to를 선택하고 그룹을 찾습니다.
- Settings > Packages and registries를 선택합니다.
- Duplicate packages 테이블의 Maven 행에서 Allow duplicates 토글을 끕니다.
- 선택 사항: Exceptions 텍스트 상자에 허용할 패키지의 이름과 버전과 일치하는 정규 표현식을 입력합니다.
변경 사항은 자동으로 저장됩니다.
Maven Central로 요청 전달하기
- 필수 역할 변경됨: GitLab 17.0에서 Maintainer에서 Owner로.
maven_central_request_forwarding
이라는 기능 플래그를 활성화해야 합니다.이 기능은 GitLab.com 또는 GitLab Dedicated 사용자에게는 사용할 수 없습니다.
Maven 패키지가 패키지 레지스트리에서 발견되지 않으면 요청이 Maven Central로 전달됩니다.
기능 플래그가 활성화되면 관리자는 지속적 통합 설정에서 이 동작을 비활성화할 수 있습니다.
Maven 전달은 프로젝트 수준과 그룹 수준 엔드포인트로만 제한됩니다. 인스턴스 수준 엔드포인트는 그 규칙을 따르지 않는 패키지에 사용되지 못하도록 하는 명명 제한이 있으며 공급망 스타일 공격에 대한 너무 많은 보안 위험을 초래합니다.
mvn
에 대한 추가 구성
mvn
을 사용할 때, Maven Central에서 GitLab에 패키지를 요청하도록 Maven 프로젝트를 구성하는 여러 방법이 있습니다. Maven 리포지토리는 특정 순서로 쿼리됩니다. 기본적으로 Maven Central이 보통 Super POM을 통해 먼저 확인되므로, GitLab이 Maven Central보다 먼저 쿼리되도록 구성해야 합니다.
모든 패키지 요청이 Maven Central 대신 GitLab로 전송되도록 하려면, <mirror>
섹션을 settings.xml
에 추가하여 Maven Central을 중앙 리포지토리로 재정의할 수 있습니다:
<settings>
<servers>
<server>
<id>central-proxy</id>
<configuration>
<httpHeaders>
<property>
<name>Private-Token</name>
<value><personal_access_token></value>
</property>
</httpHeaders>
</configuration>
</server>
</servers>
<mirrors>
<mirror>
<id>central-proxy</id>
<name>GitLab 중앙 리포의 프록시</name>
<url>https://gitlab.example.com/api/v4/projects/<project_id>/packages/maven</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
</settings>
GitLab CI/CD로 Maven 패키지 만들기
패키지 리포지토리를 Maven에 사용하도록 구성한 후, GitLab CI/CD를 구성하여 새로운 패키지를 자동으로 빌드할 수 있습니다.
mvn
기본 브랜치가 업데이트될 때마다 새로운 패키지를 생성할 수 있습니다.
-
Maven의
settings.xml
파일 역할을 하는ci_settings.xml
파일을 만듭니다. -
pom.xml
파일에서 정의한 것과 동일한 ID를 가진server
섹션을 추가합니다. 예를 들어, ID로gitlab-maven
을 사용합니다:<settings xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd"> <servers> <server> <id>gitlab-maven</id> <configuration> <httpHeaders> <property> <name>Job-Token</name> <value>${CI_JOB_TOKEN}</value> </property> </httpHeaders> </configuration> </server> </servers> </settings>
-
pom.xml
파일에 다음 사항이 포함되어 있는지 확인합니다. 기본 CI/CD 변수를 사용하도록 Maven을 설정할 수 있으며, 이 예제처럼 구성할 수 있습니다. 또는 서버의 호스트 이름과 프로젝트 ID를 하드코딩할 수 있습니다.<repositories> <repository> <id>gitlab-maven</id> <url>${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/maven</url> </repository> </repositories> <distributionManagement> <repository> <id>gitlab-maven</id> <url>${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/maven</url> </repository> <snapshotRepository> <id>gitlab-maven</id> <url>${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/maven</url> </snapshotRepository> </distributionManagement>
-
.gitlab-ci.yml
파일에deploy
작업을 추가합니다:deploy: image: maven:3.6-jdk-11 script: - 'mvn deploy -s ci_settings.xml' rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
-
이러한 파일을 리포지토리에 푸시합니다.
다음 번에 deploy
작업이 실행되면 ci_settings.xml
이 사용자의 홈 위치로 복사됩니다. 이 예제에서:
- 사용자는 ‘root’이며, 작업은 Docker 컨테이너에서 실행됩니다.
- Maven은 구성된 CI/CD 변수를 사용합니다.
gradle
기본 브랜치가 업데이트될 때마다 패키지를 생성할 수 있습니다.
-
.gitlab-ci.yml
파일에deploy
작업을 추가합니다:deploy: image: gradle:6.5-jdk11 script: - 'gradle publish' rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
-
파일을 리포지토리에 커밋합니다.
파이프라인이 성공하면 Maven 패키지가 생성됩니다.
버전 검증
버전 문자열은 다음 정규 표현식을 사용하여 검증됩니다.
\A(?!.*\.\.)[\w+.-]+\z
정규 표현식을 실험하고 이 정규 표현식 편집기에서 버전 문자열을 시도해 보세요.
스냅샷 및 릴리스 배포에 대해 다른 설정 사용
스냅샷 및 릴리스에 대해 다른 URL 또는 설정을 사용하려면:
-
pom.xml
파일의<distributionManagement>
섹션에서 별도의<repository>
및<snapshotRepository>
요소를 정의합니다.
유용한 Maven 명령줄 옵션
GitLab CI/CD에서 작업을 수행할 때 사용할 수 있는 Maven 명령줄 옵션들이 있습니다.
-
파일 전송 진행 상황은 CI 로그를 읽기 어렵게 만들 수 있습니다.
옵션-ntp,--no-transfer-progress
는 3.6.1에서 추가되었습니다.
또는-B,--batch-mode
또는 더 낮은 수준의 로깅 변경을 고려하세요. -
pom.xml
파일의 위치를 지정합니다 (-f,--file
):package: script: - 'mvn --no-transfer-progress -f helloworld/pom.xml package'
-
사용자 설정의 위치를 지정합니다 (
-s,--settings
) 기본 위치 대신에
기본 위치.-gs,--global-settings
옵션도 있습니다:package: script: - 'mvn -s settings/ci.xml package'
지원되는 CLI 명령
GitLab Maven 저장소는 다음 CLI 명령을 지원합니다:
mvn
-
mvn deploy
: 패키지를 패키지 레지스트리에 게시합니다. -
mvn install
: Maven 프로젝트에 지정된 패키지를 설치합니다. -
mvn dependency:get
: 특정 패키지를 설치합니다.
gradle
-
gradle publish
: 패키지를 패키지 레지스트리에 게시합니다. -
gradle install
: Gradle 프로젝트에 지정된 패키지를 설치합니다.
문제 해결
GitLab에서 Maven 패키지로 작업하는 동안 문제에 직면할 수 있습니다.
많은 일반적인 문제를 해결하려면 다음 단계를 시도해 보세요:
- 인증 확인 - 인증 토큰이 올바르고 만료되지 않았는지 확인하세요.
- 권한 확인 - 패키지를 게시하거나 설치할 수 있는 권한이 있는지 확인하세요.
- Maven 설정 유효성 검증 -
settings.xml
파일의 구성이 올바른지 다시 확인하세요. - GitLab CI/CD 로그 검토 - CI/CD 문제의 경우 오류 메시지를 위해 작업 로그를 자세히 검사하세요.
- 올바른 엔드포인트 URL 확인 - 프로젝트 또는 그룹에 대해 올바른 엔드포인트 URL을 사용하고 있는지 확인하세요.
-
mvn
명령에서 -s 옵션 사용 - 항상-s
옵션과 함께 Maven 명령을 실행하세요. 예:mvn package -s settings.xml
. 이 옵션 없이는 인증 설정이 적용되지 않으며 Maven이 패키지를 찾지 못할 수 있습니다.
캐시 삭제
성능을 개선하기 위해 클라이언트는 패키지와 관련된 파일을 캐시합니다. 문제가 발생하면 다음 명령으로 캐시를 지우세요:
mvn
rm -rf ~/.m2/repository
gradle
rm -rf ~/.gradle/caches # 또는 ~/.gradle를 사용자 정의 GRADLE_USER_HOME으로 바꿉니다.
네트워크 추적 로그 검토
Maven 저장소에 문제가 있는 경우, 네트워크 추적 로그를 검토할 수 있습니다.
예를 들어, 아래와 같은 옵션과 함께 PAT 토큰으로 로컬에서 mvn deploy
를 실행해 보세요:
mvn deploy \
-Dorg.slf4j.simpleLogger.log.org.apache.maven.wagon.providers.http.httpclient=trace \
-Dorg.slf4j.simpleLogger.log.org.apache.maven.wagon.providers.http.httpclient.wire=trace
경고:
이 옵션을 설정하면 모든 네트워크 요청이 기록되고 대량의 출력이 생성됩니다.
Maven 설정 확인
settings.xml
파일과 관련된 CI/CD에서 문제가 발생하는 경우, 유효한 설정 확인을 위한 추가 스크립트 작업이나 작업을 추가해 보세요.
헬프 플러그인은 또한 환경 변수를 포함한 시스템 속성을 제공할 수 있습니다:
mvn-settings:
script:
- 'mvn help:effective-settings'
package:
script:
- 'mvn help:system'
- 'mvn package'
패키지 게시 시 “401 Unauthorized” 오류
이는 일반적으로 인증 문제를 나타냅니다. 다음 내용을 확인하세요:
- 인증 토큰이 유효하고 만료되지 않았는지 확인하세요.
- 올바른 토큰 유형(개인 액세스 토큰, 배포 토큰 또는 CI 작업 토큰)을 사용하고 있는지 확인하세요.
- 토큰이 필요한 권한(
api
,read_api
, 또는read_repository
)을 가지고 있는지 확인하세요. - Maven 프로젝트의 경우, mvn 명령어에
-s
옵션을 사용하고 있는지 확인하세요 (예:mvn deploy -s settings.xml
). 이 옵션이 없으면, Maven은settings.xml
파일의 인증 설정을 적용하지 않아 인증되지 않은 오류가 발생할 수 있습니다.
“400 Bad Request” 오류: “Validation failed: Version is invalid” 메시지
GitLab은 버전 문자열에 대해 특정 요구 사항이 있습니다. 버전이 다음 형식에 따르는지 확인하세요:
^(?!.*\.\.)(?!.*\.$)[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*(\+[0-9A-Za-z-]+)?$
예를 들어, “1.0.0”, “1.0-SNAPSHOT” 및 “1.0.0-alpha”는 유효하지만 “1..0” 또는 “1.0.”은 유효하지 않습니다.
게시할 때 “Artifact already exists” 오류
이 오류는 이미 존재하는 패키지 버전을 게시하려고 할 때 발생합니다. 해결 방법:
- 게시하기 전에 패키지 버전을 증가시키세요.
- SNAPSHOT 버전을 사용하는 경우, 구성에서 SNAPSHOT 덮어쓰기를 허용하고 있는지 확인하세요.
UI에 게시한 패키지가 나타나지 않음
방금 패키지를 게시했다면, 나타나기까지 잠시 걸릴 수 있습니다. 여전히 나타나지 않으면:
- 패키지를 볼 수 있는 권한이 있는지 확인하세요.
- CI/CD 로그 또는 Maven 출력을 검토하여 패키지가 성공적으로 게시되었는지 확인하세요.
- 올바른 프로젝트나 그룹을 보고 있는지 확인하세요.
Maven 저장소 의존성 충돌
의존성 충돌은 다음 방법으로 해결할 수 있습니다:
-
pom.xml
에서 버전을 명시적으로 정의합니다. - Maven의 의존성 관리 섹션을 사용하여 버전을 제어합니다.
-
<exclusions>
태그를 사용하여 충돌하는 전이 의존성을 제외합니다.
“Unable to find valid certification path to requested target” 오류
이는 일반적으로 SSL 인증서 문제입니다. 해결 방법:
- JDK가 GitLab 서버의 SSL 인증서를 신뢰하는지 확인하세요.
- 자체 서명된 인증서를 사용하는 경우, 이를 JDK의 신뢰 저장소에 추가하세요.
- 마지막 수단으로, Maven 설정에서 SSL 검증을 비활성화할 수 있습니다. 프로덕션에서는 권장되지 않습니다.
“No plugin found for prefix” 파이프라인 오류
이것은 일반적으로 Maven이 플러그인을 찾을 수 없다는 의미입니다. 해결 방법:
-
플러그인이
pom.xml
에 올바르게 정의되었는지 확인하세요. -
CI/CD 구성에서 올바른 Maven 설정 파일을 사용하고 있는지 확인하세요.
-
파이프라인이 모든 필요한 리포지토리에 접근할 수 있는지 확인하세요.