18

I would like to deploy to a GitHub Package Registry from a GitHub Action of a public repo.

I have a yml file for a workflow:

name: My CI

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v1
    - name: Install dependencies
      run: lein deps
    - name: Run tests
      run: lein test
    - name: Generate pom
      run: lein pom
    - name: Deploy
      run: mvn deploy

I use Leiningen to build the project and generate a POM file. Then I would like to use Maven to deploy the artifact to the GitHub Package Registry.

This fails on the Deploy command (I have replaced personal information with ...):

[WARNING] Could not transfer metadata ... from/to github (https://maven.pkg.github.com/.../...): Not authorized
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  19.343 s
[INFO] Finished at: 2019-08-29T13:08:42Z
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy (default-deploy) on project ...: Failed to retrieve remote metadata .../maven-metadata.xml: Could not transfer metadata ... from/to github (https://maven.pkg.github.com/.../...): Not authorized -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
##[error]Process completed with exit code 1.

I see that authentication failed. I have also tried with this step with the same results:

run: mvn deploy -Dserver.username=... -Dserver.password=${{ secrets.GITHUB_TOKEN }} -DskipTests

I do not want to supply username/password or token as this is a public repository. Is there a way to publish anyway?

Thanks!

lmsurprenant
  • 1,723
  • 2
  • 14
  • 28
erdos
  • 3,135
  • 2
  • 16
  • 27
  • Does it work to specify `env: GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}` and then use `$GITHUB_TOKEN` in the command line? I'm not in the GitHub Actions beta yet so I can't test this for myself. – rmunn Aug 30 '19 at 02:47

5 Answers5

12

To make it work, you need to do two things:

  1. Add the following to your pom.xml:
<distributionManagement>
   <repository>
     <id>github</id>
     <name>GitHub OWNER Apache Maven Packages</name>
     <url>https://maven.pkg.github.com/OWNER/REPOSITORY</url>
   </repository>
</distributionManagement>

source: https://help.github.com/en/articles/configuring-apache-maven-for-use-with-github-package-registry#publishing-a-package

  1. Setup a Maven settings file with the username/password from within your build action. In my case I did something like this:
name: Java CI

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v1
    - name: Set up JDK 1.8
      uses: actions/setup-java@v1
      with:
        java-version: 1.8
    - name: Deploy to Github Package Registry
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      run: |
        mkdir ~/.m2
        echo "<settings><servers><server><id>github</id><username>OWNER</username><password>${GITHUB_TOKEN}</password></server></servers></settings>" > ~/.m2/settings.xml
        mvn deploy

Unfortunately, I don't think you can pass the username/password as arguments to Maven and so you need to set up the settings file instead. source: Is it possible to pass a password in Maven Deploy in the command line?

Lastly, I confirm that this only works for non-SNAPSHOT artifacts. When I try deploying a SNAPSHOT version it fails with a 400 error as described.

lmsurprenant
  • 1,723
  • 2
  • 14
  • 28
12

TL;DR: Just commit the following to .github/workflows/mavenpublish.yml and create a release via the GitHub web page to trigger the process:

name: Maven Package

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 Package Registry
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          mkdir -p ~/.m2
          echo "<settings><servers><server><id>gh</id><username>$(echo "$GITHUB_REPOSITORY" | awk -F / '{print $1}')</username><password>\${env.GITHUB_TOKEN}</password></server></servers></settings>" > ~/.m2/settings.xml
          REPO="gh::default::https://maven.pkg.github.com/${GITHUB_REPOSITORY}"
          mvn deploy -DaltReleaseDeploymentRepository="${REPO}" -DaltSnapshotDeploymentRepository="${REPO}"

Some more info:

I have built the same thing before for Jenkins and can tell you that you don't need to create a settings.xml nor adapt your pom.xml in your repo.

You can even avoid writing your GitHub Token into the settings.xml (which is more secure).

Also, you don't need to manually add your repo and username, these can be read from the environment.

If you want it to build on push, just change the lines behind on: to [push].

Here`s a real-life example.

schnatterer
  • 7,525
  • 7
  • 61
  • 80
  • What does `gh::default::` do in the repo URL? – Frans Oct 19 '20 at 17:16
  • The format of the `altReleaseDeploymentRepository` system property is as follows: `id::layout::url`. That is, `gh` is the `id` of the repo (matching the `` in the `settings.xml`) and `default` is the layout. See http://maven.apache.org/plugins/maven-deploy-plugin/deploy-mojo.html#altDeploymentRepository – schnatterer Oct 20 '20 at 06:43
6

There is an easier way in 2020.

First, add distribution configuration to your pom.xml:

<distributionManagement>
 <repository>
  <id>github</id>
  <name>GitHub OWNER Apache Maven Packages</name>
  <url>https://maven.pkg.github.com/OWNER/REPOSITORY</url>
 </repository>
</distributionManagement>

The id must be github.

Second, use actions/setup-java@v1 in action

steps:
  - uses: actions/checkout@v2

  - uses: actions/setup-java@v1
    with:
      java-version: 1.8

  - name: Publish to GitHub Packages
    env:
      GITHUB_TOKEN: ${{ github.token }}
    run: mvn deploy
Liam
  • 565
  • 5
  • 10
  • 1
    Absolutely right. You can also change the `repository` `id` to something different than `github` - you only need to add another configuration parameter beneath the `java-version` named `server-id: yourOtherIdHere` inside the `actions/setup-java@v1` section. – jonashackt Jan 12 '21 at 17:52
5

I had a similar issue for my project. Every time I ran mvn deploy, it failed with:

Could not transfer metadata ... from/to github (https://maven.pkg.github.com/.../...): 400

However, on a whim, I changed the version number of my project from 0.0.3-SNAPSHOT to 0.0.4 and after that, it worked.

Maybe it will work for you too.

tawalaya
  • 51
  • 1
  • 5
  • Does not work in my project at all. No matter if I deploy SNAPSHOT or non-SNAPSHOT versions: https://github.com/m-m-m/base To me it seems as if github actions with github packages are kind of alpha status. I have sent a request to github support and did not get any feedback since 3 weeks. – Jörg Dec 02 '19 at 00:25
4

Well, According to:

I think you could simply do like this:

  1. Add below to your workflow
- name: Deploy to Github Package Registry
    env:
      GITHUB_USERNAME: x-access-token
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    run:
      mvn --settings settings.xml deploy
  1. And then add settings.xml to your project
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                      http://maven.apache.org/xsd/settings-1.0.0.xsd">

    <activeProfiles>
        <activeProfile>github</activeProfile>
    </activeProfiles>

    <profiles>
        <profile>
            <id>github</id>
            <repositories>
                <repository>
                    <id>central</id>
                    <url>https://repo1.maven.org/maven2</url>
                    <releases>
                        <enabled>true</enabled>
                    </releases>
                    <snapshots>
                        <enabled>true</enabled>
                    </snapshots>
                </repository>
                <repository>
                    <id>github</id>
                    <name>GitHub OWNER Apache Maven Packages</name>
                    <url>https://maven.pkg.github.com/OWNER </url>
                </repository>
            </repositories>
        </profile>
    </profiles>

    <servers>
        <server>
            <id>github</id>
            <username>${env.GITHUB_USERNAME}</username>
            <password>${env.GITHUB_TOKEN}</password>
        </server>
    </servers>
</settings>

It works for me, I hope this will help.

Yur Ree
  • 41
  • 3