Skip to content

Conversation

@clarkbw
Copy link
Contributor

@clarkbw clarkbw commented Nov 16, 2019

Hello!

I wasn't sure about best practices as I'm working up this PR to enable publishing for Maven.

Problem

Publishing via Apache Maven requires a settings.xml file. (see docs) which can have 2 locations:

  • The Maven install: ${maven.home}/conf/settings.xml
  • A user’s install: ${user.home}/.m2/settings.xml

Where the user install would override any config from the default Maven install.

Option 1 (my plan)

So my plan is to create the file $HOME/.m2/settings.xml with the following contents.

<settings>
    <servers>
    <server>
        <username>clarkbw</username>
        <password>$GITHUB_TOKEN</password>
    </server>
    </servers>
</settings>

Where the username and password come from new config options passed into this action.

steps:
- uses: actions/checkout@master
- uses: actions/setup-java@v1
  with:
    java-version: '4.0.0'
    architecture: x64
    username: clarkbw
    password: $GITHUB_TOKEN
- run: mvn publish

Option 2

There is an alternate method people use where you create reference variables in the settings file and then pass your options in on the command line.

settings.xml file looks like this:

<settings>
    <servers>
    <server>
        <username>${repo.login}</username>
        <password>${repo.pwd}</password>
    </server>
    </servers>
</settings>
<settings>

In this setup there are no new config options, instead you pass in a set of command line options such that the CLI looks like this: mvn -Drepo.login=clarkbw -Drepo.pwd=$GITHUB_TOKEN publish

I don't like this because we end up requiring these new magic repo.login and repo.pwd command line options instead of some new YAML config options.

Additional notes

Alternate Apache Maven Home

It is possible to create an alternate Apache Maven home. If the M2_HOME env variable is set I could (possibly, assuming it is writable) write the file $M2_HOME/conf/settings.xml but it usually isn't user writable and can have other useful defaults we'd lose.

Maven Options for option 2
It looks like it is possible to write / append to the MAVEN_OPTS env variable with the -Drepo.login=clarkbw -Drepo.pwd=$GITHUB_TOKEN CL options such that the user isn't required to specify them on the command line. However this actually is passed over to the JVM and could have some unintended consequences.

Question

What are the best practices for writing the $HOME/.m2/settings.xml file?

I essentially did something like this:

const dir = path.join(os.homedir(), '.m2');
io.mkdirP(dir);
const settings = path.join(dir, 'settings.xml');
fs.writeFileSync(settings, XML);

Is writing to the $HOME directory ok? Are there better env variables to use?

@giltene
Copy link
Contributor

giltene commented Nov 21, 2019

Something about putting maven-specific things into a generic setup-java action seems wrong. Can you elaborate on what is wrong with the "option 2" solution to the problem? That one seems to work without needing anything to change in setup-java, and without introducing username/password options to the action that have no actual use within it (just to propagate them to later users). If we really need that, perhaps it should be in a separate setup-username-and-password action?

@konradpabjan
Copy link
Contributor

Initially I was thinking this should go into a separate action but we want packaging to work on work out of the box, and Maven is the de-facto package ecosystem for Java. This can also be configured to work with Gradle since they use the same registry.

In option 1, you would also need to update action.yml to specify the input parameters and provide them with descriptions and set them as not-required. Having username and password as extra input is fine as long as it's optional and doesn't break existing workflows. I'm leaning towards this approach since it's easier to use and doesn't require an extra CLI step to be run before setup-java. It has to be optional though.

Could you update README.md with some example of YAML of how this could be used

Bryan Clark added 20 commits November 28, 2019 13:35
username and password are required from within the auth module now.  Update the tests to ensure this is the case.
author Bryan Clark <clarkbw@github.com> 1573862473 -0800
committer Bryan Clark <clarkbw@github.com> 1574976093 -0800

Adding maven auth support

ignore vscode directory

move required parameters to auth module

username and password are required from within the auth module now.  Update the tests to ensure this is the case.

Add generated auth and setup-java

Move auth to the bottom of setup

Support ids

generated and pretty files

use server-id instead of ambigous id

Use console.log where appropriate

Adding maven auth support

ignore vscode directory

move required parameters to auth module

username and password are required from within the auth module now.  Update the tests to ensure this is the case.

Add generated auth and setup-java

Move auth to the bottom of setup

generated and pretty files

use server-id instead of ambigous id
Update gitattributes and remove lib files
@clarkbw
Copy link
Contributor Author

clarkbw commented Nov 29, 2019

Ok, I've finished my updates.

You can see a successful run of this here: https://github.com/pied-piper-inc/fib-apache-maven/commit/0048dcb399de48db4bf184e7c1b1aa24f7eabeeb/checks?check_suite_id=333934912

I might add 1 additional note to the README about publishing to other registries.

Copy link

@JLLeitschuh JLLeitschuh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Use the m2-home to specify a new location for the settings.xml file
@clarkbw
Copy link
Contributor Author

clarkbw commented Dec 10, 2019

Ok, as noted in the new docs https://github.com/clarkbw/setup-java/tree/maven-auth#apache-maven-within-a-shared-runner You can now specify an alternate location when using a shared runner but in your mvn deploy you need to specify the location of the settings file.

In the first pass at the docs I kept the .m2 directory but realized later it is confusing to tack that on when a user has specified a directory.

@clarkbw
Copy link
Contributor Author

clarkbw commented Dec 10, 2019

Updated the docs with suggestions from above, new examples seen here: https://github.com/clarkbw/setup-java/tree/maven-auth#apache-maven-with-a-settings-path

@konradpabjan
Copy link
Contributor

konradpabjan commented Dec 12, 2019

Looks good to me!. @chrispat could you take one more look before I merge the changes in. Also getting some extra 👀 from my team before merging in.


const id = core.getInput('server-id', {required: false});
const username = core.getInput('username', {required: false});
const password = core.getInput('password', {required: false});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might want to set password as a secret to protect users from accidental password leakage (in case they're populating this input without a SECRET already). This will enable masking for logs.

core.setSecret(password);

See https://github.com/actions/toolkit/tree/master/packages/core#setting-a-secret

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If they are storing the password in the file unencrypted it makes no difference if it is masked in the logs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And... someone only now shared with me that we can use env variables within the settings.xml file. https://stackoverflow.com/a/31251518

So a generic settings file like so might work and we won't need to save the token into it.

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

package.json Outdated
"format": "prettier --write **/*.ts",
"format-check": "prettier --check **/*.ts",
"release": "ncc build && git add -f dist/",
"release": "ncc build lib/setup-java.js && git add -f dist/index.js",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why have ncc build the javascript files? It can handle typescript

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch! The .ts source file can be used. See the following example: https://github.com/zeit/ncc/blob/bfefbbce9f5bdf5ba9514fd1eb0c133aa3ba3d32/examples/typescript/package.json#L8

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated this. Please double check as I'm new to ncc

Copy link
Contributor

@konradpabjan konradpabjan Dec 20, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What you have is works and I tested it out. There are quite a few ways to configure ncc in package.json. Relatively new to ncc as well 😁

Might change it up a little bit to align it with some of our other actions that also use ncc like actions/cache but I'll handle that myself in another PR. Let's merge these changes in!

Copy link
Contributor

@brcrista brcrista left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a few small comments, but LGTM.

Bryan Clark and others added 2 commits December 18, 2019 11:05
Co-Authored-By: Chris Patterson <chrispat@github.com>
Copy link
Contributor Author

@clarkbw clarkbw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going to try out this system I wasn't aware of before that can use env variables. #29 (comment)

@clarkbw
Copy link
Contributor Author

clarkbw commented Dec 20, 2019

Ok, everything is updated again now.

The new code is using env variables in the settings.xml file. You can now have a very simple setup-java where you pass the $GITHUB_TOKEN to deploy and everything else works (assuming github is the ID you use in your pom.xml file).

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

    - name: Build with Maven
      run: mvn -B package --file pom.xml

    - name: Publish to GitHub Packages Apache Maven
      run: mvn deploy
      env:
        GITHUB_TOKEN: ${{ github.token }} # GITHUB_TOKEN is the default env for the password

The new settings.xml file generated no longer contains passwords. We still need to allow people to configure the ID of the server as that corresponds to their pom.xml. The id defaults to github, username defaults to $GITHUB_ACTOR, and password defaults to $GITHUB_TOKEN.

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

Each of these environment variable names are configurable. I did this so the default above can be very simple and when using an alternative like Maven people don't try to set the GITHUB_ACTOR env. Another option would have been to use something like $MAVEN_USER and $MAVEN_PASSWORD env variables that aren't configurable but that requires more env configuration in the simplest case. I'm happy to drop this if consensus is against the configuration.

@ccleve
Copy link

ccleve commented Dec 20, 2019

I'm the person who posted about Github documentation problems on Hacker News a few hours ago. Thank you for your response.

I'll write more tomorrow, but what we really need is a complete, working example of a canonical Hello World Java/Maven app that can be built on Actions and deployed on Packages. I suggest creating a new Github project that does this. I should be able to fork it and run it in my own account without modification. You may want to create more than one such project to handle different situations.

Put copious notes right in the POM, settings, and .yml explaining exactly what is going on.

Mention this and similar projects (for npm, Gradle, etc.) prominently right in the written documentation. The docs can be a walkthrough of the sample app, with an explanation of what is going on and why.

Then provide reference docs. Have a doc that shows, in detail, what all of the options are in the action .yml. You also need a reference on all the environment variables that are available. I hadn't heard of GITHUB_ACTOR until I saw it above. Where is that documented?

Having app(s) like this will give us a place to post issues and bugs.

Be sure to read these:
https://stackoverflow.com/questions/59147676/error-code-400-when-trying-to-maven-deploy-to-github-packages-using-github-act
https://stackoverflow.com/questions/59313581/how-to-install-a-package-hosted-by-github-packages-with-github-actions?noredirect=1#comment105020411_59313581

Also, I suggest not putting settings.xml in the normal ~/.m2 dir. Put it in the root of the project, and then call "mvn --settings settings.xml deploy". That keeps everything in one place without the need to copy settings around.

If you find that getting the maven-deploy-plugin is too much of a pain, I suggest abandoning it and writing your own Maven plugin. A maven-github-packages plugin would avoid all of this configuration hell. All configuration could go right in the plugin config without the need for anything external. No settings.xml, no repositories, no distributionManagement.

@konradpabjan
Copy link
Contributor

konradpabjan commented Dec 20, 2019

Thanks @clarkbw for the hard work on this PR! Looks good to me so I'll be merging this into master. 🎉

I'll hold off till Monday after the code freeze (2nd) before merging this into releases/v1 and at that point anyone using actions/setup-java@v1 will be able to use this. I want to do some extra testing before getting the changes hit everyone.

@konradpabjan konradpabjan merged commit d8ada52 into actions:master Dec 20, 2019
tdfacer pushed a commit to ifit/setup-java that referenced this pull request Oct 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants