danielflower / multi-module-maven-release-plugin

A maven release plugin that is fast, does not add extra commits, and works well with single or multiple modules
http://danielflower.github.io/multi-module-maven-release-plugin/index.html
MIT License
125 stars 64 forks source link

Authentication using github #2

Closed frizzlebit closed 9 years ago

frizzlebit commented 9 years ago

Thanks for your work on this project Daniel.

I am finding that I cannot release when using an SSH connection to a private enterprise GitHub installation. Authentication from the command line git client is established using public/private ssh keys. At first I thought that the passphrase on the key was this issue. However I removed the passphrase and still encountered the stack trace listed below:

[INFO] --- multi-module-maven-release-plugin:1.0.2:release (default-cli) @ serenity-build ---
[ERROR] 
[ERROR] 
[ERROR] 
[ERROR] ************************************
[ERROR] Could not execute the release plugin
[ERROR] ************************************

...

Caused by: com.jcraft.jsch.JSchException: Auth fail
    at com.jcraft.jsch.Session.connect(Session.java:512)
    at org.eclipse.jgit.transport.JschConfigSessionFactory.getSession(JschConfigSessionFactory.java:116)

Do you have any suggestions on how username/password is set for this plugin?

danielflower commented 9 years ago

Hi there. Can you paste the entire stacktrace please? I presume this is happening when checking for remote tags, but would like to make sure.

The library used to read from the remote repository is http://www.jcraft.com/jsch/ which seems pretty good at authenticating. It works for me on Windows with java 8 using SSH auth with a ~/.ssh/id_rsa key. Can you tell me anything more about your setup?

frizzlebit commented 9 years ago

Using CentOS 7 unix virtual machine.

Full stack trace in maven (with URI edited out):

[ERROR] org.eclipse.jgit.api.errors.TransportException: {{git URI}}: Auth fail
    at org.eclipse.jgit.api.LsRemoteCommand.execute(LsRemoteCommand.java:223)
    at org.eclipse.jgit.api.LsRemoteCommand.call(LsRemoteCommand.java:159)
    at com.github.danielflower.mavenplugins.release.LocalGitRepo.allRemoteTags(LocalGitRepo.java:172)
    at com.github.danielflower.mavenplugins.release.Reactor.getRemoteBuildNumbers(Reactor.java:99)
    at com.github.danielflower.mavenplugins.release.Reactor.fromProjects(Reactor.java:47)
    at com.github.danielflower.mavenplugins.release.ReleaseMojo.execute(ReleaseMojo.java:117)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:307)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:193)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:106)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:862)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:286)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:197)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
Caused by: org.eclipse.jgit.errors.TransportException: {{git URI}}: Auth fail
    at org.eclipse.jgit.transport.JschConfigSessionFactory.getSession(JschConfigSessionFactory.java:159)
    at org.eclipse.jgit.transport.SshTransport.getSession(SshTransport.java:136)
    at org.eclipse.jgit.transport.TransportGitSsh$SshFetchConnection.<init>(TransportGitSsh.java:262)
    at org.eclipse.jgit.transport.TransportGitSsh.openFetch(TransportGitSsh.java:161)
    at org.eclipse.jgit.api.LsRemoteCommand.execute(LsRemoteCommand.java:202)
    ... 27 more
Caused by: com.jcraft.jsch.JSchException: Auth fail
    at com.jcraft.jsch.Session.connect(Session.java:512)
    at org.eclipse.jgit.transport.JschConfigSessionFactory.getSession(JschConfigSessionFactory.java:116)
    ... 31 more
frizzlebit commented 9 years ago

Do you use PuTTY and Pageant on the windows setup? Perhaps I am missing the unix equivalent of Pageant to access the SHH key.

danielflower commented 9 years ago

No, just plain old git bash. I believe jsch just looks for keys in ~/.ssh/ but for some reason your's is not picking up the key. I won't be able to solve it without being able to reproduce it. Maybe you can try running with maven debug logging on by adding --debug to the command line?

frizzlebit commented 9 years ago

FWIW I think the error has to do with JGit and JSch and not your plugin. I feel like CentOS is very confused because I have regenerated keys using the same filename several times.

Does the plugin support http protocol? If so, how do I specify username and password?

danielflower commented 9 years ago

If we can see the logs from JSch, then we can probably see where it is trying to load keys from. Let me know if you want to pursue this - I might need to create a build with this extra logging.

As for HTTP, I haven't tried but apparently the version of JGit that the plugin uses supports specifying Git credentials in a .netrc file. I haven't tried this myself though.

stromnet commented 9 years ago

Hi,

I'm testing out this plugin (which seems to fit what I need), but I have similar problems towards our Gitlab installation:

[ERROR] org.eclipse.jgit.api.errors.TransportException: ssh://gitlab@git.example.com/some/repo.git: Auth fail
    at org.eclipse.jgit.api.LsRemoteCommand.execute(LsRemoteCommand.java:223)
    at org.eclipse.jgit.api.LsRemoteCommand.call(LsRemoteCommand.java:159)
    at com.github.danielflower.mavenplugins.release.LocalGitRepo.allRemoteTags(LocalGitRepo.java:172)
...
Caused by: com.jcraft.jsch.JSchException: Auth fail
    at com.jcraft.jsch.Session.connect(Session.java:512)

If I rename my SSH key to "id_rsa" (normally another name), I instead get this:

Caused by: com.jcraft.jsch.JSchException: USERAUTH fail
    at com.jcraft.jsch.UserAuthPublicKey.start(UserAuthPublicKey.java:119)
    at com.jcraft.jsch.Session.connect(Session.java:463)

If I remove the passphrase from the key, it works fine.

My GIT/SSH authentication is normally done using this key and ssh-agent on my host. Seems something like https://github.com/ymnk/jsch-agent-proxy is required for this?

Johan

stromnet commented 9 years ago

With the following piece of code I got it to work fine:

JschConfigSessionFactory f = new JschConfigSessionFactory() {

    @Override
    protected void configure(OpenSshConfig.Host host, Session sn) {
    }

    @Override
    protected JSch createDefaultJSch(FS fs) throws JSchException {
        Connector con = null;
        try {
            if (SSHAgentConnector.isConnectorAvailable()) {
                USocketFactory usf = new NCUSocketFactory();
                con = new SSHAgentConnector(usf);
            }
        } catch (AgentProxyException e) {
            System.out.println(e);
        }
        final JSch jsch = super.createDefaultJSch(fs);
        if (con != null) {
            JSch.setConfig("PreferredAuthentications", "publickey");

            IdentityRepository identityRepository = new RemoteIdentityRepository(con);
            jsch.setIdentityRepository(identityRepository);
        }

        return jsch;
    }

};
JschConfigSessionFactory.setInstance(f);

(credits to https://gist.github.com/quidryan/5449155)

As this is a static factory, this could probably be put in a standalone plugin or something, if it is not wanted in the multi-module-maven-release-plugin. I've never written any Maven plugins though, would it make sense to do so?

(when testing I just put it in a static{} section in LocalGitRepo.java)

danielflower commented 9 years ago

Hi there - thanks for that. I haven't used pass phrases with this plugin which explains why I've never seen this.

If this works, I think it definitely makes sense to just put it where you did - LocalGitRepo or similar sounds good to me. It would be really appreciated if you could make a pull request.

Cheers.

stromnet commented 9 years ago

Not sure if this code works for all cases, i.e. pageant (Windows/Putty), or how it works if 'nc' is not available [1]. It would add a few more dependencies to the main plugin too.

See https://github.com/ymnk/jsch-agent-proxy for details.

I commited my proof of concept hacky code, not usable for a pull request though: https://github.com/stromnet/multi-module-maven-release-plugin/commit/1c290c4b2617087c48af90f625fea35766bc80b2

[1] https://github.com/ymnk/jsch-agent-proxy#dependencies

danielflower commented 9 years ago

Well, all the tests pass with it on Windows. Although several dependencies were added, none of them appear to be large. Aside from the error handling (should it be a warning or should it throw?) I think it's okay to try. Maybe there could be a dedicated class for it - SSHAgent.init() or something.

Is there some other reason that you think it shouldn't be merged?

I'm happy to try a merge and release if you want to try it out.

I don't suppose you know how the original maven-release-plugin handled your case?

stromnet commented 9 years ago

Moving to a dedicated class would make sense, yes. I've got a few different ideas:

  1. Always call it, like my POC code does.
  2. Add a plugin config option where it can be turned on/off (default...on?).
  3. Move it to a separate plugin altogether, since the factory is static it would still affect this plugin. Most separated but might be over the top

Regarding maven-release-plugin, I'm not sure but I think it just calls the git binary? In which case it would automatically pick up the SSH-agent support.

stromnet commented 9 years ago

Pull request #7 uses approach 2, a config knob can turn it of.

danielflower commented 9 years ago

This was merged into 1.3.1

If it fixes the original problem, please let me know. Thanks!

frizzlebit commented 8 years ago

FWIW I can use the plugin within a private corporate installation of GitHub using your 1.3.1 version of the plugin if I explicitly pass -DdisableSshAgent.

I also found that using a reactor pom.xml in the root of the git repository with only <module/> entries for each child project and a parent pom.xml that is a sibling of other child projects is not a structure that will work with the plugin. Given that this way of setting things up is non-standard I am changing our structure.

Thanks again for contributing a useful solution for maven/git projects.

danielflower commented 8 years ago

Thanks for the update. By the way, it is possible to have a non-parent aggregator - in fact there is a test for it: https://github.com/danielflower/multi-module-maven-release-plugin/tree/master/test-projects/parent-as-sibling

I'm sure there are scenarios where it doesn't work though.