Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GSoC Milestone 4] Improving Documentation #1556

Open
wants to merge 67 commits into
base: gsoc-2023-project
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
8241e60
migrating hooks to events
harsh-ps-2003 Jul 30, 2023
e002ced
migrating build actions
harsh-ps-2003 Jul 30, 2023
c164fe5
migrating pushtrigger
harsh-ps-2003 Jul 30, 2023
115d36a
fixing causedata
harsh-ps-2003 Jul 30, 2023
b6b8d93
migrating resolvers
harsh-ps-2003 Jul 30, 2023
64288b6
migrating events
harsh-ps-2003 Jul 30, 2023
bdddb49
patching tests
harsh-ps-2003 Jul 30, 2023
78759c0
cleaning up the codebase
harsh-ps-2003 Aug 2, 2023
219207f
removing unused imports
harsh-ps-2003 Aug 2, 2023
323e5c7
improving documentation
harsh-ps-2003 Aug 2, 2023
1bd88de
Patch for remaining bugs
krisstern Aug 5, 2023
b3635ef
Update MergeRequestState state for 'opened' and 'reopened' to ALL
krisstern Aug 6, 2023
340c333
Remove residual RESTEasy dependencies in Spotbugs and Dependabot
krisstern Aug 7, 2023
ae3797f
fixes type mismatch
harsh-ps-2003 Aug 9, 2023
dc36b0f
Patch type bugs
krisstern Aug 9, 2023
a34da7a
Patch GitLabConnectionConfigTest tests
krisstern Aug 14, 2023
2cedef4
Fix punctuations
krisstern Aug 14, 2023
8e71676
Patch GitLabAcceptMergeRequestPublisherTest tests
krisstern Aug 15, 2023
547c502
Approach GitLabConnectionConfigTest test differently
krisstern Aug 15, 2023
e0b5d25
Make patches for tests
krisstern Aug 16, 2023
d659b09
patching some tests
harsh-ps-2003 Aug 15, 2023
15a670b
fixing SSL test
harsh-ps-2003 Aug 15, 2023
d78f19f
fix PushHookTriggerHandlerGitLabServerTest
harsh-ps-2003 Aug 15, 2023
04d0f8d
minor test patches
harsh-ps-2003 Aug 15, 2023
ecf82c2
Make patches for tests
krisstern Aug 16, 2023
21ccd87
Patch for tests
krisstern Aug 16, 2023
933fe64
patch some tests
harsh-ps-2003 Aug 16, 2023
f985887
fix noteBuildAction
harsh-ps-2003 Aug 16, 2023
6bef894
Fix GitLabConnectionConfigAsCodeTest tests
krisstern Aug 17, 2023
5fab476
Fix some GitLabCommitStatusPublisherTest tests
krisstern Aug 17, 2023
4fc7d6f
patching some tests
harsh-ps-2003 Aug 17, 2023
a2e17ba
patching some tests
harsh-ps-2003 Aug 18, 2023
fed179b
removing ActionResolverTest
harsh-ps-2003 Aug 19, 2023
71d2deb
Fix runningWithDotInProjectId test in GitLabCommitStatusPublisherTest
krisstern Aug 20, 2023
166d4eb
Patch canceled_v4 test in GitLabCommitStatusPublisherTest
krisstern Aug 20, 2023
87d0c6b
Fix User-Agent version
krisstern Aug 20, 2023
115aacb
Patch more tests in GitLabCommitStatusPublisherTest
krisstern Aug 20, 2023
10c6a38
Make all tests pass in GitLabCommitStatusPublisherTest
krisstern Aug 20, 2023
9c99235
Apply spotless styling changes
krisstern Aug 20, 2023
3dcddd1
Make tests pass in MergeRequestBuildActionTest
krisstern Aug 20, 2023
146dc78
Make tests pass in NoteBuildActionTest
krisstern Aug 20, 2023
a06fe0c
Make tests in PipelineBuildActionTest pass
krisstern Aug 20, 2023
70b929d
minor test patches
harsh-ps-2003 Aug 20, 2023
56362f9
some minor test patches
harsh-ps-2003 Aug 20, 2023
200a042
patching pushBuildActionTest
harsh-ps-2003 Aug 20, 2023
c9ca9f3
fixing stackoverflow in mergerequesthooktriggerhandlerimpltest
harsh-ps-2003 Aug 20, 2023
b3a7340
Make tests pass in PushBuildActionTest
krisstern Aug 20, 2023
d15e33c
Make tests pass in GitLabCommitStatusStepTest
krisstern Aug 21, 2023
1217be4
Add notes to tests in GitLabCommitStatusStepTest
krisstern Aug 21, 2023
62e261d
Make tests pass in PendingBuildsHandlerTest
krisstern Aug 21, 2023
3bbd268
making mergerequesthooktriggerhandlerimpl pass
harsh-ps-2003 Aug 21, 2023
a761b58
make gitlabconnectionconfigtest pass
harsh-ps-2003 Aug 21, 2023
7735dde
make pushHookTriggerHandlerImplTest pass
harsh-ps-2003 Aug 21, 2023
521bd63
Make tests pass in CommitStatusUpdaterTest and debug
krisstern Aug 22, 2023
2e1fd04
Make tests pass in MergeRequestHookTriggerHandlerImplTest and debug
krisstern Aug 22, 2023
078ee3a
Fix spotless issues
krisstern Aug 22, 2023
905e22e
Fix spotbugs issues
krisstern Aug 22, 2023
c388139
increase test timeout
harsh-ps-2003 Aug 22, 2023
5e7b601
enabling proxy
harsh-ps-2003 Aug 23, 2023
16f00a3
enabling tests
harsh-ps-2003 Aug 23, 2023
ad21af7
Merge branch 'milestone2' into mileston5
harsh-ps-2003 Aug 23, 2023
7b2ffba
Merge branch 'milestone3' into mileston5
harsh-ps-2003 Aug 23, 2023
1006b28
increasing proxy test timeout
harsh-ps-2003 Aug 23, 2023
8860af7
making gitlabconnectionconfigtest pass
harsh-ps-2003 Aug 23, 2023
c8310cc
fixing spotless issue
harsh-ps-2003 Aug 23, 2023
6732d13
fixing spotbugs issues
harsh-ps-2003 Aug 23, 2023
2ec3f4b
Merge branch 'milestone3' into mileston5
harsh-ps-2003 Aug 23, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ updates:
# Provided by the web container, so aligned with Jetty
- dependency-name: "javax.servlet:javax.servlet-api"
# Newer versions require code changes
- dependency-name: "org.jboss.resteasy:resteasy-client"
versions: [">=4.0.0"]
# N/A
- package-ecosystem: "github-actions"
directory: "/"
schedule:
Expand Down
148 changes: 132 additions & 16 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,132 @@
# GitLab Plugin Contribution Guide
## Understanding the Plugin

The plugin is using the [GitLab4J-API](https://github.com/gitlab4j/gitlab4j-api) under the hood to interact with GitLab.

Here are some basics you should be aware of while traversing the codebase :

1. `org.kohusuke.Stapler` is a web framework used by Jenkins to handle HTTP requests and route them to appropriate handlers or actions. The Stapler Dispatcher is responsible for receiving incoming HTTP requests, parsing the request URL, and determining the appropriate action or handler to process the request. Stapler Dispatcher operations refer to the internal processes performed by the Dispatcher to handle HTTP requests. This includes URL parsing, routing, resolving paths to actions or handlers, invoking methods, and generating responses.

2. In the plugin, Jelly script files are used to define the user interface of some parts of the system. These Jelly files describe what configuration options should be presented to the user and how they should be laid out. This allows Jenkins to generate the configuration pages for each plugin dynamically based on these scripts. `StandardListBoxModel` is a class provided by the CloudBees Credentials Plugin, which is used to generate a drop-down list of credentials for a user to choose from. It allows users to select credentials that have already been created in Jenkins, rather than manually entering them every time. `hudson.util.ListBoxModel` is a utility class for generating a list of options in a drop-down list. It provides a set of common methods for adding options to the list.

3. `@ExportedBean` is a Jenkins-specific annotation that marks a class as exportable via a remote API. It is used to make the class's properties and methods accessible to external systems that interact with Jenkins, such as clients that use the Jenkins REST API.

4. `hudson.triggers.SCMTrigger` is a class in the Jenkins core library that provides the functionality for periodically polling a source code management (SCM) system for changes, and triggering builds when changes are detected.

5. In Jenkins, the use of raw HTML is typically not allowed for security reasons, as it can be used to inject malicious code or perform cross-site scripting (XSS) attacks. Instead, Jenkins provides a safe way to display formatted text using the MarkupFormatter API. The `EscapedMarkupFormatter` is one implementation of this API that escapes any potentially harmful characters in the input string, making it safe to display in the Jenkins UI. It replaces special characters like <, >, &, and " with their corresponding HTML entities so that they are not interpreted as HTML tags or attributes.

6. `hudson.util.Secret` is a class in the Jenkins API that provides a way to securely store sensitive information such as passwords, access tokens, or API keys.

7. The `@DataBoundConstructor` annotation is used in Jenkins plugin development to indicate a constructor that should be used for data binding when the plugin is loaded. In Jenkins, data binding is the process of taking user input from the web UI and converting it into an object that can be used by the plugin code. This allows for easier configuration of the plugin and enables users to store plugin configuration data in Jenkins.

8. `hudson.security.ACL` stands for Access Control List, and it is a model for defining who has access to what resources. `Jenkins.ACL` is used to define security policies and access controls in Jenkins. It defines a set of rules that dictate who has access to which resources, based on their identity, group membership, or other attributes. ACL defines the concept of "authenticated" users, who are users that have successfully authenticated themselves to Jenkins using a valid username and password or other authentication method.

9. `hudson.model.Item` and `hudson.model.ItemGroup` are used to represent different types of resources in Jenkins, such as jobs, pipelines, folders, and organizations. These resources can have different levels of access control applied to them, and ACL is used to define these access controls.

10. Backward compatibility is required in the plugin to ensure that the configuration data saved by previous versions of the plugin can still be loaded and used by the current version. The `readResolve()` method is called when the configuration is loaded, and it sets a default value for the `useAuthenticatedEndpoint` field if it is null. This ensures that configuration data saved by previous versions of the plugin that did not include this field will still work correctly with the current version. Without this backward compatibility, users who upgrade to the latest version of the plugin may experience configuration issues or data loss.

11. In Jenkins, `load()` is a method used to load configuration data for a plugin from disk. By calling `load()` in the constructor, the plugin ensures that any saved configuration is loaded into the new instance of the class.

Some basic Maven commands you should know :

`mvn compile` - This command is responsible for compiling the source code.
`mvn clean install` - This command cleans the project by removing any previously generated files and then installs the project's artifacts (e.g., JAR, WAR) into the local Maven repository. It also resolves dependencies and compiles the source code. This is typically used to build and package the project for local development or testing.
`mvn clean install -DskipTests` - Similar to the previous command, but it skips running the unit tests during the build process.
`mvn clean install -DskipITs` - Similar to the previous command, but it skips running the integration tests (ITs) during the build process.

`mvn clean test` - This command cleans the project, compiles the source code, and then runs the unit tests. It's useful when you want to execute the unit tests without installing the project artifacts in the local repository.
`mvn clean test -DskipITs` - Similar to the previous command, but it skips running the integration tests while executing the unit tests.
`mvn clean test -Dtest=<name of the test>` - This command is used to run a specific unit test by specifying its name. It's handy when you want to focus on a specific test case during development or debugging.

`mvn clean verify`- This command cleans the project, compiles the source code, runs the unit tests and integration tests, and performs additional verification steps spotless. It's often used before deploying the application to a testing or staging environment. This creates a `.hpi` file for deployment.

For learning more about Maven [refer](https://maven.apache.org/guides/index.html).

`mvn hpi:hpi` - This command is specific to Jenkins plugins development. It packages the Jenkins plugin (hpi) file, which can then be deployed to a Jenkins instance for testing.

> Note : If Jenkins or GitLab are running locally you can use [ngrok](https://ngrok.com) to expose the url to the internet. Another benefit of using ngrok is that you can visit `localhost:4040` to see the payload and other webhook related details. This can be specifically useful when writing tests for the plugin incase the JSON sent by GitLab has changed.

> Manual Uninstall : Incase the plugin has some major problem which is not letting you to uninstall the plugin you can manually uninstall the plugin by going inside you Jenkins filesystem (Files section in docker desktop if using docker instance of Jenkins) and navigating to `/var/jenkins_home/plugins/gitlab-plugin/` where you will find `gitlab-plugin.jpi` file. Just delete it and restart your Jenkins controller.

## Testing With Docker

See [this](https://github.com/jenkinsci/gitlab-plugin/tree/master/src/docker/README.md)

## Debugging

When testing with a Docker Jenkins instance, the Intellij's debugger can be setup in the following way to debug the codebase:
* From the main menu, select Run -> Edit Configurations.
* In the Run/Debug Configurations dialog, click the Add New Configuration button `+` and select Remote JVM Debug.
* Enter any relevant name, the Host (the address of the machine where the host app will run. If running it on the same machine, it needs to be localhost. If the program is running on another machine, specify its address here) and the Port (by default use 50000). The Command Line argument will be automatically setup.
* Enter Apply!

The functional tests in the GitLab Plugin's codebase can also be debugged in the following way :
* From the main menu, select Run -> Edit Configurations.
* In the Run/Debug Configurations dialog, click the Add New Configuration button `+` and select JUnit.
* Change the working directory to gitlab plugin's folder.
* Enter the required test class to be debugged.
* Enter Apply!

Now start your Jenkins instance and debugger and you should get something like this - `Connected to the target VM, address: 'localhost:50000', transport: 'socket'`.

Breakpoints can now be set up to halt the debugger at the required break point to understand the flow of the program.
## Logging

To enable debug logging in the plugin:

1. Go to Jenkins -> Manage Jenkins -> System Log
2. Add new log recorder
3. Enter 'GitLab plugin' or whatever you want for the name
4. On the next page, enter 'com.dabsquared.gitlabjenkins' for Logger, set log level to FINEST, and save
5. Then click on your GitLab plugin log, click 'Clear this log' if necessary, and then use GitLab to trigger some actions
6. Refresh the log page and you should see output.

> Note : You can also view your detailed Jenkins logs when using Jenkins Docker instance by simply going to Logs section of your Jenkins container in your Docker Desktop.

To enable Stapler Dispatcher operations you can goto Manage Jenkins -> Script Console and use this script - `System.setProperty('org.kohsuke.stapler.Dispatcher.TRACE', 'true') and click on Run to execute the script.

Once you have set the `org.kohsuke.stapler.Dispatcher.TRACE`` property to `true`, you can view the detailed logging in the Jenkins log files. Here's how you can access the log files:

1. Go to Jenkins -> Manage Jenkins -> System Log
2. Add new log recorder
3. Enter 'Stapler Dispatcher' or whatever you want for the name
4. On the next page, enter 'org.kohsuke.stapler.Dispatcher' for Logger, set log level to FINEST/ALL, and save
5. Then click on your Stapler Dispatcher log, and you should see the logs. If not then please refresh the page.
## Interactive Testing

For testing the development version of the plugin you can manually install the plugin in your Jenkins controller using its .hpi file.

> Note : The `.hpi` and '.jpi' file extensions are different. You deploy the `.hpi` file in your Jenkins controller and its stored as `.jpi` file in the Jenkins filesystem.

The .hpi can be generated using `mvn hpi:hpi` which will be stored in `/target/`. To install it manually in your Jenkins instance follow :
* Goto Manage Jenkins -> Plugins -> Advanced settings.
* In the Deploy Plugin section choose the generated gitlab-plugin.hpi file and deploy.

## Testing the Proxy Server Interactively

To hide the local Jenkins instance behind a proxy server, we can use [Ngnix Proxy Manager](https://nginxproxymanager.com/guide/#quick-setup) to setup a docker instance of Ngnix Proxy Manager which will manage the Ngnix Proxy server in the same container.

Here is how you can create a proxy host in the Proxy Manager :
1. Once you have signed in with default credentials in your Ngnix Proxy Manager docker instance, goto Hosts -> Add Proxy Host.
2. Enter a public Domain name of Ngnix Proxy Server (this should be the domain name that GitLab will use to send requests to your Jenkins server. If you're using ngrok - `ngrok http 80`), its IP Address (this should be the IP address of your Jenkins server from the perspective of the Ngnix Proxy Manager. If they are running in different Docker containers on the same Docker network, you can use the Jenkins container's name as the hostname otherwise simply use `host.docker.internal`) and the Port its listening from (This should be the port that your Jenkins server is listening on, by default - 8080/50000).
3. Enter Save!

By default this setup would provide you with Unauthenticated Proxy Server, to enable Authorization follow these steps :
1. Goto `Access Lists` tab in Ngnix Proxy Manager.
2. Add the Access List with a suitlabe Name and Authorization credentials.
3. Enter Save!
4. Goto the Proxy Host you setup earlier and edit it with new Access List which should be available in the drop down.
5. Enter Save!

Now in your GitLab's WebHook Settings use the url of
the proxy server (the url provided by ngrok) instead of Jenkins url.

With this setup, GitLab will send webhook requests to your Nginx proxy server, which will then forward those requests to Jenkins based on the proxy host configuration you set up in Nginx Proxy Manager. This way, Nginx acts as an intermediary (reverse proxy) between GitLab and Jenkins, hiding the actual IP address and details of your Jenkins server from external access.

## Testing in Production

For testing out the changes in actual production environment you have to setup actual Jenkins instance and actual GitLab Server.

## Contributing to the Plugin

Plugin source code is hosted on [GitHub](https://github.com/jenkinsci/gitlab-plugin).
Expand All @@ -18,24 +147,11 @@ Before submitting your change make sure that:
* imports are organised
* you updated the help docs
* you updated the README
* you have used spotbugs to see if you haven't introduced any new warnings
* you have used spotbugs to see if you haven't introduced any new warnings. if you have then you can use `mvn spotbugs:gui` to see the errors and warnings clearly.
* you can run `mvn spotless:apply` to confirm that the code formatting is as expected

## Testing With Docker

See https://github.com/jenkinsci/gitlab-plugin/tree/master/src/docker/README.md

## Using IntelliJ's Debugger

When testing with a Docker Jenkins instance, the debugger can be setup in the following way:
* From the main menu, select Run -> Edit Configurations.
* In the Run/Debug Configurations dialog, click the Add New Configuration button `+` and select Remote JVM Debug.
* Enter any relevant name, the Host (the address of the machine where the host app will run. If running it on the same machine, it needs to be localhost. If the program is running on another machine, specify its address here) and the Port (by default use 50000). The Command Line argument will be automatically setup.
* Enter Apply.

Now start your Jenkins instance and debugger and you should get something like this - `Connected to the target VM, address: 'localhost:50000', transport: 'socket'`.
Breakpoints can now be set up to halt the debugger at the required break point to understand the flow of the program.

## Release Workflow

To perform a full plugin release, maintainers can run ``mvn release:prepare release:perform`` To release a snapshot, e.g. with a bug fix for users to test, just run ``mvn deploy``

For information related to manual release refer [this](https://www.jenkins.io/doc/developer/publishing/releasing-manually).
Loading