Your own full blown Gerrit plugin

36
Your own full blown Gerrit plugin. 2014 Dariusz Łuksza Dariusz Łuksza, CollabNet [email protected] @dluksza

description

Gerrit at Eclipse Foundation have really long history. Initially only EGit and JGit projects could use this tool, but starting from February 2012 Gerrit become fist class citizen in Eclipse ecosystem. Every Eclipse Foundation's project can immediately start using its powerful code review capabilities. Capabilities that together with TDD and CI create safety net against bugs for software development. For quite long time Gerrit features set was pretty closed and adding new functionality required upstream code base changes. That means either you ended up in port and rebase nightmare or contributed your changes back to community... where they could not have been accepted because they solve your domain's problem not something that is vital for the community edition. Plugin support in Gerrit was initially introduced in version 2.5. Since then amount of available extension points substantially increased. In this presentation we will understand Gerrit plugins architecture. We will discuss extensions and plugins especially differences between them and which one to choose when. We will see how to combine everything together (including WEB UI) to get your first full blown Gerrit plugin.

Transcript of Your own full blown Gerrit plugin

Page 1: Your own full blown Gerrit plugin

Your own full blown Gerrit plugin.

2014 Dariusz Łuksza

Dariusz Łuksza, [email protected]

@dluksza

Page 2: Your own full blown Gerrit plugin

2014 Dariusz Łuksza

Preconditions

● Basic concept of Dependeny Injection (or have open mind to grasp it during presentation)

● POSIX compatibe operating system (Linux or Mac... or Windows with cygwin, sshd is required)

● Being familiar with JavaScript● Maven

Page 3: Your own full blown Gerrit plugin

2014 Dariusz Łuksza

How Gerrit and Jenkins Gerrit Trigger plugin works?

Trigger buldPush

Retrigger build

Post comments

Send email

developer

Page 4: Your own full blown Gerrit plugin

2014 Dariusz Łuksza

What we will build?1

2

3

Plus maven configuration to build and deploy plugin in running Gerrit instance.

Page 5: Your own full blown Gerrit plugin

2014 Dariusz Łuksza

What it requires?

● REST endpoint – to schedule a build and receive confirmation

● UI Action – part of Gerrit Web UI that will show button on change screen and popups

● Capabilities – so that only members of given groups can retrigger builds

● Two HTTP calls from Gerrit to CI server – this is implementation detail, how we actually retrigger build

Page 6: Your own full blown Gerrit plugin

Initialize project

2014 Dariusz Łuksza

Page 7: Your own full blown Gerrit plugin

2014 Dariusz Łuksza

Add archetype catalog

Window → Preferences → Maven → Archetypes

First of all you need to add remote archetype catalog to Eclipse... don't know why repo1.maven.org is not on the default list.

Page 8: Your own full blown Gerrit plugin

2014 Dariusz Łuksza

Create project from archetype

Ctrl + n → Maven → Maven Project → Next x2

Fill out those addional archetype properties

Page 9: Your own full blown Gerrit plugin

2014 Dariusz Łuksza

Default project structure

You can also provide documentation for plugin ;)

Page 10: Your own full blown Gerrit plugin

Automated plugin deployment

2014 Dariusz Łuksza

Page 11: Your own full blown Gerrit plugin

2014 Dariusz Łuksza

How to intall plugin in gerrit?● Copy jar file to $gerrit_home/plugins directory

– Works fine in local development environment but could be not compatible with integration tests

or● Use Gerrit ssh command to install it remotley

– Plugin jar file must be on server file system

– Use scp command to copy plugin jar file, then gerrit ssh command to install it

– Requires additional setting in $gerrit_site/etc/gerrit.config:[plugins]

allowRemoteAdmin = true

Page 12: Your own full blown Gerrit plugin

2014 Dariusz Łuksza

How to deploy plugin from command line?

$ scp [email protected] /path/to/plugin/file.jar /tmp/

$ ssh -p 4918 [email protected] gerrit plugin install /tmp/jar.file

First operation require SSHD running on the server and system account.

Second, require account in Gerrit (this is different then one used in first step) and membership in Gerrit Administrators group*.

* or Administrate Server capability

Page 13: Your own full blown Gerrit plugin

2014 Dariusz Łuksza

Deploy from Maven? Yes, we can!

Those lines goes on and on... On last slide you will find link to repository that contains this pom.xml file

Page 14: Your own full blown Gerrit plugin

2014 Dariusz Łuksza

And missing Maven profile setting

systemUser name is used in scp command

deployUser should be member of Gerrit Administrators group*.Plus have SSH public key in Gerrit of local system user.

* or have Administrate Server capability

Page 15: Your own full blown Gerrit plugin

2014 Dariusz Łuksza

And we are good to go!Now you can simply type `mvn verify` to deploy newest plugin version in running Gerrit

Our two commands being executed

Page 16: Your own full blown Gerrit plugin

Configure your plugin

2014 Dariusz Łuksza

Page 17: Your own full blown Gerrit plugin

2014 Dariusz Łuksza

Configure plugin in gerrit.config

● Add:[plugin "RetriggerMe"]

jenkinsUrl = http://localhost:9090/

selfName = localhost 8080to $gerrit_site/etc/gerrit.config and restart Gerrit

● From now on, our plugin must be installed under `RetriggerMe` name. Otherwise it will not see this configuration.

Page 18: Your own full blown Gerrit plugin

2014 Dariusz Łuksza

Let's start from plugin configuration!

pluginName will contain name under which our plugin was installed in Gerrit, annotation here is very important. That value is dynamically bound in plugin context during installation process.

Extract `jenkinsUrl` and `selfName` from $gerrit_site/etc/gerrit.config file

Don't forget about @Inject

Page 19: Your own full blown Gerrit plugin

Communicate with outside world via REST

endpoints

2014 Dariusz Łuksza

Page 20: Your own full blown Gerrit plugin

2014 Dariusz Łuksza

Let's communicate with outside world! - REST end points

Will be automatically serialized to JSON before sending to client.

Inject our configuration provider

Implement proper interface

Page 21: Your own full blown Gerrit plugin

2014 Dariusz Łuksza

Let's communicate with outside world! - REST end points

Inform Gerrit that we want to have our REST enpoint to be registered in `change` context, with name `retrigger`. This is another part of Gerrit's Guice magic ;)

Page 22: Your own full blown Gerrit plugin

2014 Dariusz Łuksza

Let's communicate with outside world! - REST end points

Install our child Guice module in main plugin module.

Page 23: Your own full blown Gerrit plugin

2014 Dariusz Łuksza

Let's communicate with outside world! - REST end points

Let's test it:

$ mvn verify

$ curl -X POST –digest \ http://admin:tJESZhrTpZGm@localhost:8080/a/changes/2/RetriggerMe~retrigger

)]}'

{

"jenkins_url": "http://localhost:9090/"

}

Generated HTTP password for admin user

Name under which plugin was installed

REST endpoint name

Response

Context name

Response always starts with magic “)]}'” prefix. This is preventing from JavaScript injection, this is a security feature of Gerrit.

Page 24: Your own full blown Gerrit plugin

Extend Web UI

2014 Dariusz Łuksza

Page 25: Your own full blown Gerrit plugin

2014 Dariusz Łuksza

Add button on Web UI

Add UiAction interface

Page 26: Your own full blown Gerrit plugin

2014 Dariusz Łuksza

Add button on Web UI

Handle button `onclick` action

Gerrit's JavaScript magic ;)

Context name

Our REST endpoint name

Page 27: Your own full blown Gerrit plugin

2014 Dariusz Łuksza

Communicate back to server

Callback function

Call associated REST endpoint

Note object fields naming convention (underscores)

Page 28: Your own full blown Gerrit plugin

2014 Dariusz Łuksza

Handle data from client and trigger build

Input datastructure, remember about name convention, camelCase in Java, underscores_in_java_script

Gerrit will automatically deserialize JSON to Java object

Page 29: Your own full blown Gerrit plugin

Extend Gerrit permission system

2014 Dariusz Łuksza

Page 30: Your own full blown Gerrit plugin

2014 Dariusz Łuksza

Protect retrigger button with plugin own capability

Extend CapabilityDefinition class

Page 31: Your own full blown Gerrit plugin

2014 Dariusz Łuksza

Protect retrigger button with plugin own capability

Grant our plugin capability to users group

Configuring capabilities requires changes in All-Projects access rights.

Page 32: Your own full blown Gerrit plugin

2014 Dariusz Łuksza

Protect retrigger button with plugin own capability

Bind it in plugin main module

Page 33: Your own full blown Gerrit plugin

2014 Dariusz Łuksza

Protect retrigger button with plugin own capability

Anotate our UiAction with @RequiresCapability

And that is it! Only members of groups with `retrigger` capability will see `Retrigger Me!` button in Web UI.

Page 34: Your own full blown Gerrit plugin

Debugging?

2014 Dariusz Łuksza

Page 35: Your own full blown Gerrit plugin

2014 Dariusz Łuksza

How to debug?

● Modify $gerrit_site/etc/gerrit.config:

[container] javaOptions = -Xdebug -Xrunjdwp:transport=dt_socket,address=8998,server=y,suspend=n

● Use 'Remote debug' from Eclipse :)

Page 36: Your own full blown Gerrit plugin

2014 Dariusz Łuksza

Dariusz Łuksza, [email protected]

@dluksza

Thank you!

Questions?Links:● Gerrit documentation:

https://gerrit-documentation.storage.googleapis.com/Documentation/2.9/index.htmlPlugins development part:https://gerrit-documentation.storage.googleapis.com/Documentation/2.9/dev-plugins.htmlJavaScript API part:https://gerrit-documentation.storage.googleapis.com/Documentation/2.9/js-api.html

● RetriggerMe source:https://github.com/dluksza/gerrit-retriggerme

● Presentation:http://www.slideshare.net/dluksza/gerrit-plugins

● Create Gerrit Web UI plugins using AngularJS:https://github.com/dluksza/angular-gerrit