Skip to content

The goal of this project is to master the core of continuous integration. To achieve this goal, a small continuous integration CI server is to be implemented. This CI server will only contain the core features of continuous integration.

License

Notifications You must be signed in to change notification settings

joss2002/Continuous_Integration

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Host CI-server locally

Prerequisites

  • Java 8
  • Java JDK 17
  • Maven 3.9
  • Git
Run the server
  1. Clone the repository
git clone https://github.com/joss2002/Continuous_Integration.git
  1. Navigate to the repository and build the project with Maven
mvn clean compile
  1. Run the CI-server

Without commit status notifications:

mvn exec:java

With commit status notifications:

To set the status of commits, a github access token with commit status permission is required.

mvn exec:java -Dexec.mainClass=ci_server.Main -Dexec.args="<GITHUB ACCESS TOKEN>"
Test the server

Option 1: Use curl

curl http://localhost:8080/
Expected output
StatusCode        : 200
StatusDescription : OK
Content           : CI job done (placeholder)

Option 2: Open browser at http://localhost:8080/

Expected output
CI job done (placeholder)

Note: 8080 is the default port number.

Perform local push event successfully

  1. Run the server, see Run the server.
Bash
  1. Load local JSON payload test file
json=$(cat ./src/test/resources/githubPush.json)
  1. Post JSON payload to the CI-server
curl http://localhost:8080/webhook \
  -H "Content-Type: application/json" \
  -d "$json"
Expected output

Client side

HTTP/1.1 200 OK
Content-Length: 25
Date: Tue, 10 Feb 2026 12:27:04 GMT
Server: Jetty(9.4.50.v20221201)

Push received: e5f6g7h8

Server side

Received push on branch : main
After SHA               : e5f6g7h8
Repository URL          : https://github.com/user/repo.git
Pusher name             : name

Head commit message     : Update README
PowerShell
  1. Load local JSON payload test file
$json = Get-Content -Raw "./src/test/resources/githubPush.json"
  1. Post JSON payload to the CI-server
Invoke-WebRequest -Uri http://localhost:8080/webhook `
  -Method POST `
  -Body $json `
  -ContentType "application/json"
Expected output

Client side

StatusCode        : 200
StatusDescription : OK
Content           : {80, 117, 115, 104...}
RawContent        : HTTP/1.1 200 OK
                    Content-Length: 25
                    Date: Tue, 10 Feb 2026 12:27:04 GMT
                    Server: Jetty(9.4.50.v20221201)

                    Push received: e5f6g7h8

Server side

Received push on branch : main
After SHA               : e5f6g7h8
Repository URL          : https://github.com/user/repo.git
Pusher name             : name

Head commit message     : Update README

Test invalid payload

Bash

Post invalid JSON to the CI-server

curl -X POST http://localhost:8080/webhook \
  -H "Content-Type: application/json" \
  -d '{Invalid JSON}'
Expected output
Invalid payload: Invalid GitHub push payload
PowerShell

Post invalid JSON to the CI-server

Invoke-WebRequest `
  -Uri http://localhost:8080/webhook `
  -Method POST `
  -Body '{Invalid JSON}' `
  -ContentType "application/json"
Expected output
Invoke-WebRequest : Invalid payload: Invalid GitHub push payload
At line:1 char:1
+ Invoke-WebRequest -Uri http://localhost:8080/webhook -Method POST -Bo ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebExc
   eption
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

Compilation (P1)

Implementation

When the CI server receives a GitHub push webhook on /webhook, it triggers compilation of the pushed branch. The Compiler class in se.ciserver.build performs the following steps:

  1. Creates a temporary directory
  2. Clones the specific branch using git clone --branch <branch> --single-branch <url>
  3. Checks out the exact commit SHA with git checkout <sha>
  4. Runs mvn clean compile in the cloned project
  5. Captures and prints the build output to the server console
  6. Cleans up the temporary directory

The compilation result (success/failure) is returned in the HTTP response and printed to the server console.

Unit testing

Compilation is unit-tested in src/test/java/MainTest.java with the following tests:

  • compilationResultStoresSuccess() — verifies that a successful CompilationResult stores success=true and the build output.
  • compilationResultStoresFailure() — verifies that a failed CompilationResult stores success=false and the build output.
  • compilerHandlesCloneFailure() — subclasses Compiler to override createProcessBuilder() with a failing command, verifying that a clone failure returns success=false without throwing an exception.
  • compilerReturnsSuccessWhenAllStepsPass() — subclasses Compiler to override createProcessBuilder() with a succeeding command, verifying the full pipeline returns success=true.
  • ciServerHandleCompilationOnPush() — starts a local Jetty server, sends a valid push payload to /webhook, and verifies the response is 200 and contains the compilation result with the commit SHA.

To run the tests, see Perform unit tests.


Perform unit tests

  1. Build the project with Maven
mvn clean compile
  1. Run the junit unit tests
mvn test
  1. Verify all tests pass in the output
Tests run: 9, Failures: 0, Errors: 0, Skipped: 0

BUILD SUCCESS

Connect the server to a webhook with ngrok

  1. Run the server, see Run the server.

  2. In a separate terminal, start ngrok to expose port 8080:

ngrok http 8080
  1. Copy the forwarding URL (e.g. https://xxxx.ngrok-free.app) from the ngrok output.

  2. In your GitHub repository, go to Settings > Webhooks > Add webhook and set:

    • Payload URL: https://xxxx.ngrok-free.app/webhook
    • Content type: application/json
    • Events: Select "Just the push event"
  3. Push a commit to the repository and observe the compilation output in the server console.


Automated Test Execution via Github Push Events

When a push is made to the git repository, Github sends a HTTP POST request (Webhook) to the running server. From the request and its payload, the branch to which the push was made can be extracted. Upon parsing the payload, the server checks out to the target branch, pulls the latest changes and runs the project's test suite.

The automated test logic is handled by the TestRunner class which is responsible for executing the following:

Functionality
  1. Checkout the pushed branch using Git.

  2. Running the test suite using mvn test

  3. Capturing the output and exit status

  4. Returning the test logs, displayed both in server terminal and in the HTTP response.

Test the functionality
  1. Run the server, see Run the server.

  2. Configure Webhook from server to repository.

  3. Expose server to Github using ngrok.

  4. Observe response upon a Github push event in terminal or HTTP response.

Notification Implementation and Testing

Notifications are implemented by setting the status of commits using github's REST api. A post request containing the status is sent to the url of the push's last commit.

The notification implementation is tested by running a test server and sending the status post request to it instead, which checks that its contents are correct.

Unit testing of test execution logic

To avoid using real Git and Maven commands during unit testing, the TestRunner class uses a command hook mechanism that intercepts command execution. When this hook mechanism is set, command are captured rather than executed and the expected behaviour could be asserted within the unit test.

Statements of contributions

Name Contribution
Josefine "joss2002" Nyholm
  • Added initial Maven file-tree structure, including a basic pom.xml with JDK 17 support.
  • Added skeleton for CI-server in src/main/java/se/ciserver/ContinuousIntegrationServer.java.
    • Added related dependencies, plugins; jetty-server, exec-maven-plugin
    • Added additional documentation.
  • Added GitHub push event JSON payload component.
    • Added required Webhook payload object parameters and classes for push within src/main/java/se/ciserver/github including files; PushParser.java, Push.java, Pusher.java, Commit.java, Author.java and Repository.java.
    • Added additional Exception extension in InvalidPayloadException.java specified for invalid payloads.
    • Integrated the push parsing JSON payload functionality in the ContinuousIntegrationServer.java handler() to allow the CI-server to receive JSON payloads and present the relevant variables; ref, after, repository.clone_url, pusher.name, head_commit.message.
    • Added unit tests in src/test/java/MainTest.java for PushParser.java push parsing JSON payload functionality and local testing of the ContinuousIntegrationServer.java CI-server handling of push parsing JSON payloads. This, as well as an additional file src/main/java/se/ciserver/TestUtils.java including test utilities such as reading filed. Supporting the unit tests a test JSON file src/main/test/resources/githubPush.java was added to represent a typical push event payload.
    • Added additional dependencies in pom.xml for jackson-databind and junit
    • Added additional documentation in README.md.
Avid "HotFazz" Fayaz
  • Added webhook-triggered compilation (P1) in src/main/java/se/ciserver/build/Compiler.java.
    • Clones the pushed branch, checks out the exact commit, and runs mvn clean compile.
    • Added CompilationResult.java to hold build outcome and output.
    • Integrated compilation into ContinuousIntegrationServer.java webhook handler.
    • Added unit tests in MainTest.java for CompilationResult and Compiler failure handling.
    • Added documentation in README.md for compilation implementation and unit testing.
Albin "zzimbaa" Blomqvist
  • Implemented automated test execution triggered by GitHub push webhooks.
  • Added TestRunner.java in src/main/java/se/ciserver/ to handle CI test execution.
    • Dynamically checks out the pushed branch using git checkout and updates it with git pull.
    • Executes Maven test suite using mvn test.
    • Captures test output via ProcessBuilder and write logs to both terminal and HTTP response indicating test success or failure.
    • Determines build success/failure based on process exit code.
    • Added unit test for runTests method to verify correct correct branch checkout and pull commands using command hook.
  • Integrated the test execution logic into ContinuousIntegrationServer.java so that tests are triggered automatically upon receiving a GitHub push webhook event.
  • Verified webhook-based test execution using ngrok for local tunneling and GitHub webhook deliveries.
  • Added documentation in README.md describing how to trigger automated tests via GitHub push events.
Erik Olsson "erik-ol"
  • Added GitHub commit status setter component.
    • Added ContinuousIntegrationServer() startHttpClient() and setCommitStatus() to ContinuousIntegrationServer.java
    • Extended ContinuousIntegrationServer.java handler() to set commit status of recieved pushes.
    • Added unit tests in src/test/java/MainTest.java for setCommitStatus() sending post request functionality and failing due to invalid url.
    • Implemented github access token handling
    • Added additional dependencies in pom.xml for jetty-client
    • Added documentation for commit status implementation and testing in README.md.
Albin "zzimbaa" Blomqvist
  • Implemented automated test execution triggered by GitHub push webhooks.
  • Added TestRunner.java in src/main/java/se/ciserver/ to handle CI test execution.
    • Dynamically checks out the pushed branch using git checkout and updates it with git pull.
    • Executes Maven test suite using mvn test.
    • Captures test output via ProcessBuilder and write logs to both terminal and HTTP response indicating test success or failure.
    • Determines build success/failure based on process exit code.
    • Added unit test for runTests method to verify correct correct branch checkout and pull commands using command hook.
  • Integrated the test execution logic into ContinuousIntegrationServer.java so that tests are triggered automatically upon receiving a GitHub push webhook event.
  • Verified webhook-based test execution using ngrok for local tunneling and GitHub webhook deliveries.
  • Added documentation in README.md describing how to trigger automated tests through GitHub push events.

About

The goal of this project is to master the core of continuous integration. To achieve this goal, a small continuous integration CI server is to be implemented. This CI server will only contain the core features of continuous integration.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •  

Languages