This project is a tiny ci server for compiling and testing Maven projects on GitHub. The server receives webhook push events from GitHub. The application then compile and test the Maven project. The build log is saved in local database. Commit status and url of build detail will be sent back to GitHub.
- Project Repo: https://github.com/DD2480-G12/a2-ci-server
- Frontend Repo: https://github.com/DD2480-G12/a2-frontend
- Build History: http://nichujie.xyz/
- JDK 17 or above
- Apache Maven 3.3+
- Docker & docker-compose (for deployment)
- Spring Boot: Web server
- SQLite: Data Storage & Persistence
- Docker: Fast Deployment & Runtime Isolation
Persistent storage of build data was implemented using a SQLite database file with the following schema:
CREATE TABLE builds (
uid INTEGER PRIMARY KEY,
commit_hash TEXT,
content TEXT,
timestamp TEXT
);
We integrate functionalities of GitHub Apps to communicate with GitHub. Please refer to this page on how to create an app and generate a private key.
Before running any commands, you need to place the private key under the parent directory of
the project directory, and name it as webapp.pem
. If you prefer to put it elsewhere, you can override the default settings
by exporting an environment variable:
export PEM_LOCATION=/my/custom/directory/webapp.pem
We clone and save the repositories of push events on local file system.
By default, they are saved in a directory called repos
under the parent directory of
the project directory. You can override this path using:
export REPO_DIR=/my/custom/repos
Start the application:
mvn spring-boot:run
Build the package:
mvn clean package
Test:
mvn test
Clone the repo and build the jar file first:
mvn clean package
Start app and expose port 8080
:
docker-compose -f docker-compose.yml up -d
Configure data directories in .env
file:
HOST_REPO_DIR=/home/ncj19991213/ci-repos # store cloned repo on host
HOST_PEM_LOCATION=/home/ncj19991213/webapp.pem # your GitHub app credential on host
HOST_DATA_DIR=/opt/ci-server-data # database & other data on host
The notification of the result of the CI test has been implemented by setting a status on the last commit in the supplied pull request. We have created a GitHub App which is connected to our repository and has permissions to create statuses. The CI server authenticates against this app and performs a POST request to the GitHub API to set statues. In order to authenticate, a private key file must exist locally.
The unit tests have been implemented by sending a POST request to GitHub and observing the response. One test case send valid API data and expects a valid response, another sends invalid API data and expects an invalid response.
POST /push-events
Accepts push events from GitHub webhooks
None
Request body implemented according to this, the CI server only supports the properties in the example below.
Request body example:
{
"ref":"refs/heads/mustafa/test-branch",
"after":"ea312d0e44d08a603935b8b926eea76e4ed0e266",
"repository": {
"name":"a2-ci-test",
"clone_url":"https://github.com/DD2480-G12/a2-ci-test.git",
"owner": {
"name":"DD2480-G12"
}
}
}
204 No Content: If the request is accepted by the server
GET /history
Returns the whole stored history of builds
None
200 OK: If the request is successful
Returns an array of BuildInfo, if the history is empty, an empty array will be returned.
BuildInfo
{
uid: Integer,
commitId: String,
content: String,
timestamp: String
}
GET /history/{id}
Returns the information for a specific build
id
: Integer, the uid of the desired build
400 Bad Request: If id
is not a number
404 Not Found: If build id
does not exist
200 OK: If a build log with the given id
exists
Returns a BuildInfo
BuildInfo
{
uid: Integer,
commitId: String,
content: String,
timestamp: String
}
We are working on forming a team that works as a cohesive unit. We don’t think we are all the way there yet, as we could coordinate more and discuss more what issues we should work on next and how we could help each other. We know each other sufficiently to work together, even though we of course could know each other much better if we had time for team building. The team mission is quite clear from the assignment, and it’s clear that the team is focused on achieving it.
- Server Setup
- Docker Deployment & Error Fixing
- Integration Test of Webhooks on GitHub
- Add target url to commit status
- Implemented the Github client (notifications)
- Implemented endpoint for push events from GitHub webhook
- Implemented Compile and Test stages
- Wrote implementation details and the way Compile and Test was unit tested
- Actively reviewed Pull Requests
- Partially implemented and researched sqlite database and spring
- Setup a basic front-end that connects and displays data from our back-end
- Build history endpoint
- Build info endpoint
- Made database wrapper