3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[Gradle] GitHubの個人ユーザーがMaven Centralへライブラリを公開する方法

Last updated at Posted at 2025-12-12

はじめに

自作のJava/Kotlinライブラリを広く公開したい場合、Maven Centralへのデプロイが一般的な選択肢となります。本記事では、GitHubの個人アカウントを持つ開発者がMaven Centralへライブラリを公開するための手順を解説します。

本記事の内容は、筆者が公開している DB Tester(JUnit/Spock向けのデータベーステストフレームワーク)のリリース手順に基づいています。

前提条件

  • GitHubアカウント
  • GPGキーの基本的な知識
  • Gradleプロジェクト(Gradle 8.x以降推奨)

全体の流れ

  1. Central Portalでアカウント作成・名前空間の検証
  2. APIトークンの生成
  3. GPGキーの作成・公開
  4. Gradleプロジェクトの設定
  5. リリース実行

1. Central Portalアカウントの設定

アカウント作成

Central Portalにアクセスし、アカウントを作成します。

GitHubアカウントでのログインも可能です。

名前空間の検証

GitHubの個人ユーザーの場合、io.github.<username> 形式の名前空間を使用します。

GitHubアカウントでログインした場合io.github.<username> の名前空間は自動的に検証されます。手動での検証作業は不要です。

独自ドメインを使用する場合は、Central Portalの「Namespaces」からドメインを追加し、TXT DNSレコードによる検証が必要です。

2. APIトークンの生成

Maven Centralへのデプロイに必要な認証情報を生成します。

  1. Central Portalにログイン
  2. 「Account」→「Generate User Token」を選択
  3. 表示されるUsernameと**Password(Token)**を安全に保存

トークンは一度しか表示されません。紛失した場合は再生成が必要です。

3. GPGキーのセットアップ

Maven Centralでは、すべてのアーティファクトにGPG署名が必須です。

キーの生成

# GPGキーの生成(RSA 4096ビット推奨)
gpg --full-generate-key

# 選択肢:
# - (1) RSA and RSA
# - 4096 bits
# - 0 = key does not expire(または任意の有効期限)
# - 名前とメールアドレスを入力(GitHubアカウントと一致させる)

キーIDの確認

gpg --list-secret-keys --keyid-format=short

# 出力例:
# sec   rsa4096/ABCD1234 2024-01-01 [SC]
#       1234567890ABCDEF1234567890ABCDEF12345678
# uid           [ultimate] Your Name <your@email.com>

ABCD1234 がキーID(短縮形)です。

公開鍵のアップロード

Maven Centralが署名を検証できるよう、公開鍵をキーサーバーに登録します。

# 複数のキーサーバーに登録(推奨)
gpg --keyserver keyserver.ubuntu.com --send-keys ABCD1234
gpg --keyserver keys.openpgp.org --send-keys ABCD1234

署名のテスト

echo "test" | gpg --clearsign

パスフレーズを入力して署名が成功すれば準備完了です。

4. Gradleプロジェクトの設定

使用するプラグイン

本記事では以下のプラグインを使用します。

プラグイン 用途
gradle-maven-publish-plugin Maven Central公開の自動化
axion-release-plugin Gitタグベースのバージョン管理

プラグインの追加

settings.gradle.kts
pluginManagement {
    repositories {
        gradlePluginPortal()
    }
}
build.gradle.kts
plugins {
    alias(libs.plugins.axion.release)
    alias(libs.plugins.maven.publish)
}
gradle/libs.versions.toml
[versions]
axion-release = "1.18.20"
maven-publish = "0.30.0"

[plugins]
axion-release = { id = "pl.allegro.tech.build.axion-release", version.ref = "axion-release" }
maven-publish = { id = "com.vanniktech.maven.publish", version.ref = "maven-publish" }

バージョン管理の設定(axion-release-plugin)

Gitタグからバージョンを自動的に導出します。

build.gradle.kts
group = "io.github.<username>"

scmVersion {
    useHighestVersion = true
    tag {
        prefix = "v"
        versionSeparator = ""
    }
    versionCreator("simple")
    repository {
        pushTagsOnly = true
    }
    checks {
        uncommittedChanges = false
        aheadOfRemote = false
    }
}

version = scmVersion.version

バージョンの動作:

  • タグ v1.2.0 → バージョン 1.2.0
  • タグ後のコミット → バージョン 1.2.1-SNAPSHOT
# 現在のバージョンを確認
./gradlew currentVersion

Maven公開設定(gradle-maven-publish-plugin)

build.gradle.kts
mavenPublishing {
    publishToMavenCentral()
    signAllPublications()

    pom {
        name = "Your Library Name"
        description = "A brief description of your library"
        url = "https://github.com/<username>/<repository>"
        inceptionYear = "2024"

        licenses {
            license {
                name = "MIT License"
                url = "https://opensource.org/licenses/MIT"
            }
        }

        developers {
            developer {
                id = "<username>"
                name = "Your Name"
                email = "your@email.com"
            }
        }

        scm {
            connection = "scm:git:git://github.com/<username>/<repository>.git"
            developerConnection = "scm:git:ssh://github.com/<username>/<repository>.git"
            url = "https://github.com/<username>/<repository>"
        }
    }
}

Maven Centralでは、POMにnamedescriptionurllicensesdevelopersscmの記載が必須です。これらが不足している場合、公開時にバリデーションエラーが発生します。

認証情報の設定

~/.gradle/gradle.properties に認証情報を追加します。

~/.gradle/gradle.properties
# Maven Central Portal認証情報
mavenCentralUsername=your-username-from-central-portal
mavenCentralPassword=your-token-from-central-portal

# GPG署名設定(GPGエージェント使用)
signing.gnupg.keyName=ABCD1234
signing.gnupg.passphrase=your-gpg-passphrase
CI環境での設定(環境変数)

CI環境では環境変数で認証情報を渡します。

export ORG_GRADLE_PROJECT_mavenCentralUsername="your-username"
export ORG_GRADLE_PROJECT_mavenCentralPassword="your-token"
export ORG_GRADLE_PROJECT_signingInMemoryKeyId="ABCD1234"
export ORG_GRADLE_PROJECT_signingInMemoryKeyPassword="your-passphrase"
export ORG_GRADLE_PROJECT_signingInMemoryKey="$(gpg --armor --export-secret-keys ABCD1234)"

5. リリースの実行

ローカルリリース

# 1. テストの実行
./gradlew clean build

# 2. ローカルMavenリポジトリで確認(任意)
./gradlew publishToMavenLocal -Prelease.forceVersion=1.0.0

# 3. Gitタグの作成
git tag v1.0.0

# 4. バージョン確認
./gradlew currentVersion  # 1.0.0 と表示されること

# 5. Maven Centralへ公開
./gradlew publishAndReleaseToMavenCentral --no-configuration-cache

# 6. タグをプッシュ(公開成功後)
git push origin v1.0.0

# 7. GitHub Releaseの作成
gh release create v1.0.0 --title "Release 1.0.0" --generate-notes

--no-configuration-cache オプションは、gradle-maven-publish-pluginの制約により必須です。

GitHub Actionsによる自動リリース(推奨)

継続的なリリースには、GitHub Actionsワークフローの構築をお勧めします。

GitHub Actions設定例
.github/workflows/release.yml
name: Release

on:
  workflow_dispatch:
    inputs:
      version:
        description: 'Release version (e.g., 1.2.0)'
        required: true
        type: string
      dry-run:
        description: 'Dry-run mode'
        required: false
        type: boolean
        default: true

env:
  JAVA_VERSION: '21'

jobs:
  validate:
    runs-on: ubuntu-latest
    outputs:
      version: ${{ steps.version.outputs.version }}
      tag: ${{ steps.version.outputs.tag }}
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Validate version format
        run: |
          VERSION="${{ github.event.inputs.version }}"
          if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
            echo "::error::Invalid version format"
            exit 1
          fi

      - name: Check tag does not exist
        run: |
          TAG="v${{ github.event.inputs.version }}"
          if git rev-parse "$TAG" >/dev/null 2>&1; then
            echo "::error::Tag $TAG already exists"
            exit 1
          fi

      - id: version
        run: |
          echo "version=${{ github.event.inputs.version }}" >> "$GITHUB_OUTPUT"
          echo "tag=v${{ github.event.inputs.version }}" >> "$GITHUB_OUTPUT"

  release:
    needs: validate
    runs-on: ubuntu-latest
    if: ${{ !inputs.dry-run }}
    environment: maven-central
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: ${{ env.JAVA_VERSION }}
          cache: 'gradle'

      - name: Create local tag
        run: git tag ${{ needs.validate.outputs.tag }}

      - name: Build
        run: ./gradlew clean build

      - name: Publish to Maven Central
        run: ./gradlew publishAndReleaseToMavenCentral --no-configuration-cache
        env:
          ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.MAVEN_CENTRAL_USERNAME }}
          ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.MAVEN_CENTRAL_TOKEN }}
          ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.GPG_PRIVATE_KEY }}
          ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.GPG_PASSPHRASE }}

      - name: Push tag
        run: git push origin ${{ needs.validate.outputs.tag }}

      - name: Create GitHub Release
        uses: softprops/action-gh-release@v2
        with:
          tag_name: ${{ needs.validate.outputs.tag }}
          name: Release ${{ needs.validate.outputs.version }}
          generate_release_notes: true

必要なシークレット:

シークレット 説明
GPG_PRIVATE_KEY gpg --armor --export-secret-keys KEY_ID の出力
GPG_PASSPHRASE GPGキーのパスフレーズ
MAVEN_CENTRAL_USERNAME Central Portalのユーザー名
MAVEN_CENTRAL_TOKEN Central Portalのトークン

GitHub Environment:

  1. リポジトリの「Settings」→「Environments」→「New environment」
  2. 名前: maven-central
  3. 「Required reviewers」を設定(誤操作防止)

6. 公開の確認

Maven Central

公開後、10〜30分程度で以下のURLで確認できます。

https://central.sonatype.com/artifact/io.github.<username>/<artifact-id>

依存関係として使用

build.gradle.kts
dependencies {
    implementation("io.github.<username>:<artifact-id>:1.0.0")
}

トラブルシューティング

GPG署名エラー: "Inappropriate ioctl for device"

TTYがない環境(CI等)でGPGがパスフレーズを要求できない場合に発生します。

解決策: インメモリ署名を使用

~/.gradle/gradle.properties
signing.keyId=ABCD1234
signing.password=your-gpg-passphrase
signing.secretKeyRingFile=/path/to/secring.gpg

または環境変数:

export ORG_GRADLE_PROJECT_signingInMemoryKey="$(gpg --armor --export-secret-keys ABCD1234)"
export ORG_GRADLE_PROJECT_signingInMemoryKeyPassword="your-passphrase"
POMバリデーションエラー

Maven Centralでは以下の要素が必須です:

  • name
  • description
  • url
  • licenses
  • developers
  • scm

gradle-maven-publish-pluginは自動的にこれらを検証し、不足があればエラーを報告します。

# ローカルで検証
./gradlew publishToMavenLocal -Prelease.forceVersion=1.0.0 --info
Configuration Cacheエラー

gradle-maven-publish-pluginはConfiguration Cacheと互換性がありません。

# 正しい使用方法
./gradlew publishAndReleaseToMavenCentral --no-configuration-cache

まとめ

GitHubの個人ユーザーがMaven Centralへライブラリを公開する手順を解説しました。

ポイント:

  1. Central Portal: GitHubログインで名前空間が自動検証される
  2. gradle-maven-publish-plugin: Maven Central公開を大幅に簡素化
  3. axion-release-plugin: Gitタグベースの宣言的なバージョン管理
  4. GitHub Actions: 継続的リリースの自動化

一度環境を整えれば、./gradlew publishAndReleaseToMavenCentral のワンコマンドで公開が完了します。

参考資料

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?