How to publish Maven packages to a single GitHub repository

Jakub Zalas - Feb 8 '21 - - Dev Community

image

A working example of this setup can be found in vlingo XOOM repositories: https://github.com/vlingo/xoom-platform/packages

Publishing to the current repository

Before we look at publishing to an external repository, let's review how straight forward it is to publish to the current one:



name: Build

on:
  release:
    types: [created]

jobs:
  publish:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2

      - name: Set up JDK 1.8
        uses: actions/setup-java@v1
        with:
          java-version: 1.8

      - name: Deploy to GitHub
        run: mvn --batch-mode -DuseGitHubPackages=true deploy
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


Enter fullscreen mode Exit fullscreen mode

GitHub packages repository will be automatically configured for us in Maven by the actions/setup-java action. All's left to do is to pass the GITHUB_TOKEN secret as an environment variable to the mvn deploy command.

Note: GITHUB_TOKEN secret is available on all GitHub action builds out of the box. The token's scope is limited to the current repository.

In the above example we also enabled the useGitHubPackages flag in order to load the Maven profile that configures distribution mangement:



<!-- pom.xml -->
<project ...>
  <!-- ... -->

  <profiles>
    <profile>
      <id>github</id>
      <activation>
        <property>
          <name>useGitHubPackages</name>
          <value>true</value>
        </property>
      </activation>
      <distributionManagement>
        <repository>
          <id>github</id>
          <name>GitHub Packages</name>
          <url>https://maven.pkg.github.com/vlingo/xoom-common</url>
        </repository>
      </distributionManagement>
    </profile>
  </profiles>
</project>


Enter fullscreen mode Exit fullscreen mode

The above example works for publishing vlingo/xoom-common from within the same repository.

Publishing to a shared repository

The setup from previous section works great if we only have a single repository to publish from. Once we start publishing from multiple GitHub repositories, we'll end up with one Maven repository per GitHub repository.

This is not always desired, especially if we develop a set of libraries that are usually installed together. In such a scenario, our clients would be forced to include in their pom.xml one Maven repository per library we provide.

The solution is to choose a dedicated repository for publishing our Maven packages and use it in distribution management for all the other repositories.

Maven configuration

For example, having libraries like xoom-common, xoom-actors, xoom-http, we could choose to publish all of them to a single repository xoom-platform:



<!-- pom.xml -->
<project ...>
  <!-- ... -->

  <profiles>
    <profile>
      <id>github</id>
      <activation>
        <property>
          <name>useGitHubPackages</name>
          <value>true</value>
        </property>
      </activation>
      <distributionManagement>
        <repository>
          <id>github</id>
          <name>GitHub Packages</name>
          <url>https://maven.pkg.github.com/vlingo/xoom-platform</url>
        </repository>
      </distributionManagement>
    </profile>
  </profiles>
</project>


Enter fullscreen mode Exit fullscreen mode

GitHub action

The GitHub action will remain very similar to the one we looked at in the beggining with one notable difference - the GITHUB_TOKEN:



name: Build

on:
  release:
    types: [created]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2

      - name: Set up JDK 1.8
        uses: actions/setup-java@v1
        with:
          java-version: 1.8

      - name: Deploy to GitHub
        run: mvn --batch-mode -DuseGitHubPackages=true deploy
        env:
          GITHUB_TOKEN: ${{ secrets.DEPLOY_GITHUB_TOKEN }}


Enter fullscreen mode Exit fullscreen mode

We can no longer use the token provided by default as its scope is limited to the current repository.

Instead, we'll need to create a Personal Access Token and pass it to the action as a secret (DEPLOY_GITHUB_TOKEN in the example above).

Creating a GitHub Personal Access Token

To make it work across repositories we'll need to define a new Personal Access Token in:

Select the write:packages scope and all the repo scopes should be automatically selected for us.

image

Defining a secret

Next, the token needs to be defined as a secret in our organisation or each of the repositories we need to publish packages from.

Give it a name (i.e. DEPLOY_GITHUB_TOKEN) and set its value to the Personal Access Token created in the previous step.

image

Repository secrets are defined in repository Settings > Secrets. There's a similar section for the organisation secrets.

. . . . . . . . . . . . .