This project is a simple Continuous Integration (CI) server that:
- Listens for GitHub webhook events (pushes).
- Clones the repository and runs Maven build & tests.
- Reports build/test results back to GitHub commit status API.
📦 continuous-integration-server
|- src
| |- main
| | |- java
| | | |- ci
| | | | |- ContinuousIntegrationServer.java # Webhook listener
| | | | |- WebhookHandler.java # Parses webhook events
| | | | |- JobQueue.java # Manages queued build jobs
| | | | |- BuildWorker.java # Processes CI jobs asynchronously
| | | | |- BuildManager.java # Executes Git operations, builds and runs tests
| | | | |- StatusReporter.java # Sends commit status updates
|- test
| |- BuildManagerTest.java # Unit tests for BuildManager
| |- WebhookHandlerTest.java # Unit tests for WebhookHandler
|- pom.xml # Maven dependencies
|- README.md # Documentation
|- start.sh # Starts CI server
|- deploy_ngrok.sh # Deploys CI server with ngrok
This CI server listens for GitHub webhook events, processes builds, and updates commit statuses.
Follow these steps to set up and run it on your local machine.
Ensure you have installed:
- ✅ Java
- ✅ Maven (
mvn) - ✅ ngrok (for exposing the local server)
- ✅ GitHub Personal Access Token (PAT) with
repoandworkflowpermissions
- Go to GitHub → Developer Settings → Personal Access Tokens
- Click "Generate New Token", select:
- ✅
repo(Full control of repositories) - ✅
workflow(For updating commit statuses)
- ✅
- Click "Generate Token" and copy it immediately.
To avoid exposing your token, store it securely:
export GITHUB_TOKEN=your_github_token_hereTo verify
echo $GITHUB_TOKENRun:
mvn clean install
mvn exec:java -Dexec.mainClass="com.group21.ci.ContinuousIntegrationServer"The server will now listen on port 8080.
Since GitHub webhooks need a public URL, use ngrok to expose your local server:
ngrok http 8080It will generate an output like:
Forwarding https://xyz123.ngrok-free.app -> http://localhost:8080
Copy the https://xyz123.ngrok-free.app URL.
- Go to GitHub → Repository → Settings → Webhooks
- Click “Add Webhook”
- Set:
- Payload URL: https://xyz123.ngrok-free.app/webhook
- Content type: application/json
- Trigger: Select “Just the push event”
- Click “Add Webhook”.
🚨 Note: Every time ngrok http 8080 runs, the URL changes. You must update the webhook manually.
- Push an empty commit to trigger the CI server:
git commit --allow-empty -m "test: trigger webhook"
git push origin assessment🚨 Note: You should ignore "terget/" when commit, if you want to link your commit to an issue, please use issue (#15), which refers to testing the webhook.
- Check your CI server logs:
- If set up correctly, the webhook triggers the CI process.
- Your commit status updates on GitHub.
🔹 If the CI Server fails with a 401 Unauthorized error
Run:
echo $GITHUB_TOKENIf it’s empty, set it again:
export GITHUB_TOKEN=your_github_token_here🔹 If ngrok gives an ERR_NGROK_108 error
Run:
pkill -f ngrok
ngrok http 8080Since ngrok generates a new URL every time, instead of manually updating the webhook, use this script to automate it:
export NGROK_URL=$(curl -s http://127.0.0.1:4040/api/tunnels | jq -r '.tunnels[0].public_url')
curl -X PATCH -H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
-d "{\"config\": {\"url\": \"$NGROK_URL/webhook\", \"content_type\": \"json\"}}" \
https://api.github.com/repos/YOUR_GITHUB_USERNAME/YOUR_REPO_NAME/hooks/YOUR_WEBHOOK_ID- Biming Wen @WenBiming
- Xu Zuo @floralsea
- Gustav Nordström @GustavNordstrom
- Gustav Wallin @Muppsz
-
Biming Wen:
- Contributed to the new feature for p+, keeping build history
- Define
TestResulttable of relational database MySQL, holding records for each 'mvn test' - Implement Data Persistance Layer of the project, including
- classes TestResultEntity and TestStatus in package entity
- Classes TestResultDAO, HibernateUtil and HibernateTestUtil in package dao
- Unit tests and integral tests of TestResultDAO
-
Xu Zuo:
- Set up the initial structure based on the architecture provided by Biming Wen.
- Implemented and contributed to CI sever, BuildManager, BuildWorker, JobQueue, StatusReporter and WebhookHandler.
- Implemented unit test of BuildManager.
- Contributed to the new feature for p+, keeping build history.
-
Gustav Nordström:
- Implemented/contributed to the CI server being able to run tests
- Refactored parts of the code, mainly by removing unused or obsolete code
- Worked on documentation and keeping it updated
-
Gustav Wallin :
Regarding Essence, we believe we're currently in the collaborating stage, and while progress is being made, there are still areas for improvement. Overall, collaboration is functioning well, but to reach a higher level of success, communication and effectiveness need to be further improved.