正式なドキュメントは英語版であり、この日本語訳はAI支援翻訳により作成された参考用のものです。日本語訳の一部の内容は人間によるレビューがまだ行われていないため、翻訳のタイミングにより英語版との間に差異が生じることがあります。最新かつ正確な情報については、英語版をご参照ください。

パッケージレジストリ内のMavenパッケージ

  • プラン: Free、Premium、Ultimate
  • 提供形態: GitLab.com、GitLab Self-Managed、GitLab Dedicated

プロジェクトのパッケージレジストリにMavenアーティファクトを公開します。その後、依存関係として使用する必要があるときはいつでもパッケージをインストールします。

Mavenパッケージマネージャーのクライアントが使用する特定のAPIエンドポイントのドキュメントについては、Maven APIドキュメントを参照してください。

サポートされているクライアント:

  • mvnMavenパッケージをビルドする方法については、リンク先を参照してください。
  • gradleGradleパッケージをビルドする方法については、リンク先を参照してください。
  • sbt

GitLabパッケージレジストリに公開する

パッケージレジストリへの認証

パッケージを公開するにはトークンが必要です。実現しようとしていることに応じて、さまざまなトークンを利用できます。詳細については、トークンに関するガイダンスをご確認ください。

トークンを作成し、後で使用するために保存します。

ここに記載されている方法以外の認証方法は使用しないでください。ドキュメント化されていない認証方法は、将来削除される可能性があります。

クライアント設定を編集する

HTTPでMavenリポジトリに対して認証するように設定を更新します。

カスタムHTTPヘッダー

クライアントの設定ファイルに認証の詳細を追加する必要があります。

トークンの種類名前は次のようになっている必要がありますトークン
パーソナルアクセストークン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>
トークンの種類名前は次のようになっている必要がありますトークン
パーソナルアクセストークンPrivate-Tokenトークンをそのまま貼り付けるか、トークンを保持するための環境変数を定義します
デプロイトークンDeploy-Tokenトークンをそのまま貼り付けるか、トークンを保持するための環境変数を定義します
CIジョブトークンJob-TokenSystem.getenv("CI_JOB_TOKEN")

<name>フィールドは、選択したトークンと一致するように名前を付ける必要があります。

GRADLE_USER_HOMEディレクトリで、次の内容のgradle.propertiesファイルを作成します:

gitLabPrivateToken=REPLACE_WITH_YOUR_TOKEN

repositoriesセクションをbuild.gradleファイルに追加します:

  • 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認証

基本HTTP認証を使用してMavenパッケージレジストリに対して認証することもできます。

トークンの種類名前は次のようになっている必要がありますトークン
パーソナルアクセストークンユーザーのユーザー名トークンをそのまま貼り付けるか、トークンを保持するための環境変数を定義します
デプロイトークンデプロイトークンのユーザー名トークンをそのまま貼り付けるか、トークンを保持するための環境変数を定義します
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>
トークンの種類名前は次のようになっている必要がありますトークン
パーソナルアクセストークンユーザーのユーザー名トークンをそのまま貼り付けるか、トークンを保持するための環境変数を定義します
デプロイトークンデプロイトークンのユーザー名トークンをそのまま貼り付けるか、トークンを保持するための環境変数を定義します
CIジョブトークンgitlab-ci-tokenSystem.getenv("CI_JOB_TOKEN")

GRADLE_USER_HOMEディレクトリで、次の内容のgradle.propertiesファイルを作成します:

gitLabPrivateToken=REPLACE_WITH_YOUR_TOKEN

repositoriesセクションをbuild.gradleに追加します。

  • 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)
            }
        }
    }
トークンの種類名前は次のようになっている必要がありますトークン
パーソナルアクセストークンユーザーのユーザー名トークンをそのまま貼り付けるか、トークンを保持するための環境変数を定義します
デプロイトークンデプロイトークンのユーザー名トークンをそのまま貼り付けるか、トークンを保持するための環境変数を定義します
CIジョブトークンgitlab-ci-tokensys.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>については、上の表で説明しています。

命名規則

3つのエンドポイントのいずれかを使用して、Mavenパッケージをインストールできます。パッケージはプロジェクトに公開する必要がありますが、選択するエンドポイントによって、公開のためにpom.xmlファイルに追加する設定が決まります。

3つのエンドポイントは次のとおりです:

  • プロジェクト: Mavenパッケージが少数で、同じGitLabグループに属していない場合に使用します。
  • グループ: 同じGitLabグループ内のさまざまなプロジェクトからパッケージをインストールする場合に使用します。GitLabは、グループ内のパッケージ名の一意性を保証しません。パッケージ名とパッケージバージョンが同じ2つのプロジェクトを持つことができます。その結果、GitLabはより新しい方を提供します。
  • インスタンス: 異なるGitLabグループまたは独自のネームスペースに多数のパッケージがある場合に使用します。

インスタンスレベルのエンドポイントの場合、Mavenのpom.xmlの関連セクションが次のようになっていることを確認してください:

  <groupId>group-slug.subgroup-slug</groupId>
  <artifactId>project-slug</artifactId>

プロジェクトと同じパスを持つパッケージのみがインスタンスレベルのエンドポイントによって公開されます。

プロジェクトパッケージインスタンスレベルのエンドポイントを利用可能
foo/barfoo/bar/1.0-SNAPSHOT
gitlab-org/gitlabfoo/bar/1.0-SNAPSHOTいいえ
gitlab-org/gitlabgitlab-org/gitlab/1.0-SNAPSHOTはい

エンドポイントURL

エンドポイントpom.xmlのエンドポイントURL追加情報
プロジェクトhttps://gitlab.example.com/api/v4/projects/<project_id>/packages/mavengitlab.example.comをドメイン名に置き換えます。<project_id>をプロジェクトのプロジェクト概要ページにあるプロジェクトIDに置き換えます。
グループhttps://gitlab.example.com/api/v4/groups/<group_id>/-/packages/mavengitlab.example.comをドメイン名に置き換えます。<group_id>をグループのホームページにあるグループIDに置き換えます。
インスタンスhttps://gitlab.example.com/api/v4/packages/mavengitlab.example.comをドメイン名に置き換えます。

公開用の設定ファイを編集する

クライアントの設定ファイルに公開の詳細を追加する必要があります。

どのエンドポイントを選択しても、次のものが必要です:

  • 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>

Gradleを使用してパッケージを公開するには:

  1. Gradleプラグインmaven-publishをプラグインセクションに追加します:

    • Groovy DSLの場合:

      plugins {
          id 'java'
          id 'maven-publish'
      }
    • Kotlin DSLの場合:

      plugins {
          java
          `maven-publish`
      }
  2. 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 // the variable resides in $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? // the variable resides in $GRADLE_USER_HOME/gradle.properties
                  }
                  authentication {
                      create("header", HttpHeaderAuthentication::class)
                  }
              }
          }
      }

パッケージを公開する

DeployAtEndオプションを使用すると、400 bad request {"message":"Validation failed: Name has already been taken"}でアップロードが拒否される可能性があります。詳細については、イシュー424238を参照してください。

認証を設定し、公開するエンドポイントを選択したら、Mavenパッケージをプロジェクトに公開します。

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

プロジェクトのパッケージとレジストリページに移動し、公開されたパッケージを表示します。

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

Mavenパッケージを公開する前に保護すると、403 ForbiddenエラーとAuthorization failedエラーメッセージが返され、パッケージが拒否されます。公開時にMavenパッケージが保護されていないことを確認します。パッケージ保護ルールの詳細については、パッケージを保護する方法を参照してください。

パッケージをインストールする

GitLabパッケージレジストリからパッケージをインストールするには、リモートを設定して認証する必要があります。これが完了すると、プロジェクト、グループ、またはネームスペースからパッケージをインストールできます。

複数のパッケージの名前とバージョンが同じ場合、パッケージをインストールすると、最後に公開されたパッケージが取得されます。

mvn installを使用してパッケージをインストールするには:

  1. プロジェクトのpom.xmlファイルに依存関係を手動で追加します。以前に作成した例を追加する場合、XMLは次のようになります:

    <dependency>
      <groupId>com.mycompany.mydepartment</groupId>
      <artifactId>my-project</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>
  2. プロジェクトで、次を実行します:

    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コマンドを直接使用してパッケージをインストールすることもできます。

  1. プロジェクトディレクトリで、次を実行します:

    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を使用してパッケージをインストールするには:

  1. 依存関係セクションの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")
      }
  2. プロジェクトで、次を実行します:

    gradle build

sbtを使用してパッケージをインストールするには:

  1. build.sbtインライン依存関係を追加します:

    libraryDependencies += "com.mycompany.mydepartment" % "my-project" % "8.4"
  2. プロジェクトで、次を実行します:

    sbt update

Mavenパッケージのプロキシダウンロード

GitLab Mavenパッケージレジストリは、リモートに含まれるチェックサムを使用します。ファイルをダウンロードすると、レジストリはファイルをプロキシ処理し、ファイルと関連するチェックサムの両方を1つのリクエストでMavenクライアントに送信します。

最新のMavenクライアントでリモートに含まれるチェックサムを使用すると、次のようになります:

  • クライアントからGitLab MavenパッケージレジストリへのWebリクエストの数が削減されます。
  • GitLabインスタンスを読み込む際の負荷が軽減されます。
  • クライアントコマンドの実行時間が改善されます。

技術的な制約により、オブジェクトストレージを使用すると、Mavenパッケージレジストリは、packagesのオブジェクトストレージ構成のプロキシダウンロード設定を無視します。代わりに、プロキシダウンロードは常Mavenパッケージレジストリのダウンロードに対して有効になります。

オブジェクトストレージを使用しない場合、この動作はインスタンスに影響を与えません。

MavenパッケージのCI/CDインテグレーション

CI/CDを使用して、Mavenパッケージを自動的にビルド、テスト、公開できます。このセクションの例では、次のようなシナリオを取り上げます:

  • マルチモジュールプロジェクト
  • バージョン管理されたリリース
  • 条件付き公開
  • コード品質およびセキュリティスキャンとのインテグレーション

これらの例を適応および組み合わせて、特定のプロジェクトのニーズに合わせることができます。

Mavenのバージョン、Javaのバージョン、およびその他の詳細をプロジェクトの要件に応じて調整することを忘れないでください。また、GitLabパッケージレジストリへの公開に必要な認証情報と設定が正しく構成されていることを確認してください。

基本的なMavenパッケージのビルドと公開

この例では、Mavenパッケージをビルドおよび公開するパイプラインを設定します:

default:
  image: maven:3.8.5-openjdk-17
  cache:
    paths:
      - .m2/repository/
      - target/

variables:
  MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode"
  MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"

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プロジェクト

複数のモジュールを含む大規模なプロジェクトでは、並列ジョブを使用してビルドプロセスを高速化できます:

default:
  image: maven:3.8.5-openjdk-17
  cache:
    paths:
      - .m2/repository/
      - target/

variables:
  MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode"
  MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"

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"

タグ付きバージョン管理リリース

この例では、タグがプッシュされるときにバージョン管理されたリリースを作成します:

default:
  image: maven:3.8.5-openjdk-17
  cache:
    paths:
      - .m2/repository/
      - target/

variables:
  MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode"
  MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"

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
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

release:
  stage: release
  script:
    - mvn versions:set -DnewVersion=${CI_COMMIT_TAG}
    - mvn $MAVEN_CLI_OPTS deploy
  rules:
    - if: $CI_COMMIT_TAG

変更に基づく条件付き公開

この例では、特定のファイルが変更された場合にのみパッケージを公開します:

default:
  image: maven:3.8.5-openjdk-17
  cache:
    paths:
      - .m2/repository/
      - target/

variables:
  MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode"
  MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"

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 == $CI_DEFAULT_BRANCH
      changes:
        - pom.xml
        - src/**/*

コード品質およびセキュリティスキャンとのインテグレーション

この例では、コード品質チェックとセキュリティスキャンをパイプラインに統合します:

default:
  image: maven:3.8.5-openjdk-17
  cache:
    paths:
      - .m2/repository/
      - target/

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

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を使用して、既存のパッケージの古いアセットにアクセスして表示することもできます。

古いパッケージバージョンを削除するには、パッケージAPIまたはUIの使用を検討してください。

Mavenパッケージの重複を許可しない

ユーザーがMavenパッケージを重複して公開することを防ぐには、GraphQl APIまたはUIを使用します。

UIの場合:

  1. 左側のサイドバーで、検索または移動先を選択して、グループを見つけます。
  2. 設定 > パッケージとレジストリを選択します。
  3. パッケージの重複テーブルのMaven行で、重複を許可の切替をオフにします。
  4. オプション。例外テキストボックスに、許可するパッケージの名前とバージョンに一致する正規表現を入力します。

重複を許可がオンになっている場合は、例外テキストボックスで、重複してはならないパッケージ名とバージョンを指定できます。

変更は自動的に保存されます。

Maven Centralへのリクエスト転送

この機能の利用可否は、機能フラグによって制御されます。詳細については、履歴を参照してください。

パッケージレジストリにMavenパッケージが見つからない場合、リクエストはMaven Centralに転送されます。

この機能フラグが有効になっている場合、管理者は継続的インテグレーション設定でこの動作を無効にできます。

Mavenの転送は、プロジェクトレベルおよびグループレベルのエンドポイントのみに制限されています。インスタンスレベルのエンドポイントには、その規則に従わないパッケージに使用できない命名制限があり、サプライチェーンスタイルの攻撃に対して過剰なセキュリティリスクも発生します。

mvnの追加設定

mvnを使用する場合、GitLabからMaven CentralのパッケージをリクエストするようにMavenプロジェクトを設定する方法は多数あります。Mavenリポジトリは、特定の順序でクエリされます。デフォルトでは、Maven Centralは通常、Super POMを介して最初に確認されるため、maven-centralの前にクエリされるようにGitLabを設定する必要があります。

すべてのパッケージリクエストがMaven CentralではなくGitLabに送信されるようにするには、settings.xml<mirror>セクションを追加して、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 proxy of central repo</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を設定して新しいパッケージを自動的にビルドできます。

デフォルトブランチが更新されるたびに新しいパッケージを作成できます。

  1. Mavenのsettings.xmlファイルとして機能するci_settings.xmlファイルを作成します。

  2. 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>
  3. pom.xmlファイルに以下が含まれていることを確認してください。この例に示すように、Mavenで定義済みのCI/CD変数を使用するるか、サーバーのホスト名とプロジェクトの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>
  4. .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
  5. これらのファイルをリポジトリにプッシュします。

次にdeployジョブが実行されると、ci_settings.xmlがユーザーのホームロケーションにコピーされます。この例では、次のようになります:

  • ジョブはDockerコンテナで実行されるため、ユーザーはrootです。
  • Mavenは設定されたCI/CD変数を使用します。

デフォルトブランチが更新されるたびにパッケージを作成できます。

  1. GradleでCIジョブトークンを使用して認証します。

  2. .gitlab-ci.ymlファイルにdeployジョブを追加します:

    deploy:
      image: gradle:6.5-jdk11
      script:
        - 'gradle publish'
      rules:
        - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
  3. ファイルをリポジトリにコミットします。

パイプラインが成功すると、Mavenパッケージが作成されます。

バージョン検証

バージョン文字列は、次の正規表現を使用して検証されます。

\A(?!.*\.\.)[\w+.-]+\z

この正規表現エディタで正規表現を試したり、バージョン文字列を試したりできます。

スナップショットとリリースデプロイメントに異なる設定を使用する

スナップショットとリリースに異なるURLまたは設定を使用するには:

  • pom.xmlファイルの<distributionManagement>セクションで、個別の<repository>要素と<snapshotRepository>要素を定義します。

便利なMavenコマンドラインオプション

GitLab CI/CDでタスクを実行する際に使用できるMavenコマンドラインオプションがいくつかあります。

  • ファイル転送の進捗状況により、CI logが読みにくくなることがあります。オプション-ntp,--no-transfer-progress3.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 deploy: パッケージをパッケージレジストリに公開します。
  • mvn install: Mavenプロジェクトで指定されたパッケージをインストールします。
  • mvn dependency:get: 特定のパッケージをインストールします。
  • gradle publish: パッケージをパッケージレジストリに公開します。
  • gradle build: このプロジェクトを組み立ててテストします。

トラブルシューティング

GitLabでMavenパッケージを使用しているときに、問題が発生する可能性があります。多くの一般的な問題を解決するには、次の手順を試してください:

  • 認証の確認 - 認証トークンが正しくて、期限切れになっていないことを確認します。
  • 権限の確認 - パッケージを公開またはインストールするために必要な権限があることを確認します。
  • Maven設定の検証 - settings.xmlファイルで正しい設定になっているか再確認します。
  • GitLab CI/CD logの確認 - CI/CDの問題については、ジョブログでエラーメッセージを注意深く調べます。
  • 正しいエンドポイントURLであることを確認 - プロジェクトまたはグループに対して正しいエンドポイントURLを使用していることを確認します。
  • mvnコマンドで-sオプションを使用 - 常に-sオプションを使用してMavenコマンドを実行します(例: mvn package -s settings.xml)。このオプションがないと、認証設定が適用されず、Mavenがパッケージを見つけられない場合があります。

キャッシュをクリアする

パフォーマンスを向上させるために、クライアントはパッケージに関連するファイルをキャッシュします。問題が発生した場合は、次のコマンドを使用してキャッシュをクリアしてください:

rm -rf ~/.m2/repository
rm -rf ~/.gradle/caches # Or replace ~/.gradle with your custom GRADLE_USER_HOME

ネットワークトレースlogを確認する

Mavenリポジトリで問題が発生している場合は、ネットワークトレースlogを確認してください。ネットワークトレースlogを確認すると、より詳細なエラーメッセージが表示されます。これは、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

これらのオプションを設定すると、すべてのネットワークリクエストがlogに記録され、大量の出力が生成されます。

Maven設定を確認する

settings.xmlファイルに関連するCI/CD内で問題が発生した場合は、追加のスクリプトタスクまたはジョブを追加して、有効な設定を確認してみてください。

ヘルププラグインは、環境変数を含むシステムプロパティも提供できます:

mvn-settings:
  script:
    - 'mvn help:effective-settings'

package:
  script:
    - 'mvn help:system'
    - 'mvn package'

パッケージの公開を試みるときの「401 Unauthorized」エラー

これは通常、認証の問題を示しています。以下を確認してください:

  • 認証トークンが有効で、期限切れになっていない。
  • 正しいトークンタイプ(パーソナルアクセストークン、デプロイトークン、またはCIジョブトークン)を使用している。
  • トークンに必要な権限(apiread_api、またはread_repository)がある。
  • Mavenプロジェクトの場合は、mvnコマンドで-sオプションを使用している(たとえば、mvn deploy -s settings.xml)。このオプションがないと、Mavenはsettings.xmlファイルからの認証設定を適用せず、Unauthorizedエラーが発生します。

「400 Bad Request」エラー(メッセージ「検証に失敗しました: バージョンが無効です」)

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.」は有効ではありません。

パッケージの公開を試みるときの403 Forbiddenエラー

メッセージAuthorization failedが表示される403 Forbiddenエラーは、通常、認証または権限の問題を示しています。以下を確認してください:

  • 正しいトークンタイプ(パーソナルアクセストークン、デプロイトークン、またはCI/CDジョブトークン)を使用している。詳細については、パッケージレジストリへの認証を参照してください。
  • トークンに必要な権限がある。デベロッパーロール以上のユーザーのみがパッケージを公開できます。詳細については、GitLabの権限を参照してください。
  • 公開しようとしているパッケージが、プッシュ保護ルールで保護されていない。パッケージ保護ルールの詳細については、パッケージを保護する方法を参照してください。

公開時の「アーティファクトはすでに存在します」エラー

このエラーは、すでに存在するパッケージバージョンを公開しようとすると発生します。解決するには、次のようにします:

  • 公開前にパッケージバージョンをインクリメントします。
  • SNAPSHOTバージョンを使用している場合は、設定でSNAPSHOTの上書きを許可していることを確認してください。

公開されたパッケージがUIに表示されない

パッケージを公開したばかりの場合は、表示されるまでに少し時間がかかることがあります。それでも表示されない場合は、次のようにします:

  • パッケージを表示するために必要な権限があることを確認します。
  • CI/CD logまたはMavenの出力内容を確認して、パッケージが正常に公開されたことを確認します。
  • 正しいプロジェクトまたはグループを検索していることを確認します。

Mavenリポジトリの依存関係の競合

依存関係の競合は、次のようにして解決できます:

  • pom.xmlでバージョンを明示的に定義します。
  • Mavenの依存関係管理セクションを使用してバージョンを制御します。
  • <exclusions>タグを使用して、競合する推移的依存関係を除外します。

「リクエストされたターゲットへの有効な認証パスが見つかりません」エラー

これは通常、SSL証明書の問題です。解決するには、次のようにします:

  • JDKがGitLabサーバーのSSL証明書を信頼していることを確認します。
  • 自己署名証明書を使用している場合は、JDKのトラストストアに追加します。
  • 最後の手段として、Maven設定でSSL検証を無効にすることができます。本番環境では推奨されません。

「プレフィックスのプラグインが見つかりません」パイプラインエラー

これは通常、Mavenがプラグインを見つけられないことを意味します。修正するには、次のようにします:

  • プラグインがpom.xmlで正しく定義されていることを確認します。
  • CI/CD設定が正しいMaven設定ファイルを使用していることを確認します。
  • パイプラインが必要なすべてのリポジトリにアクセスできることを確認します。