diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml new file mode 100644 index 00000000..d9829413 --- /dev/null +++ b/.github/workflows/docker-image.yml @@ -0,0 +1,55 @@ +name: Docker Image CI + +on: + pull_request: + types: [opened, synchronize] + branches: + - main + + pull_request_target: + types: [closed] + +jobs: + build-test: + name: Build and Test Docker Image + runs-on: ubuntu-latest + if: github.event.action != 'closed' + + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Build Docker Image (Test) + run: | + docker build -t mattmcdou/ci-cd-test-image . + + push-image: + name: Push Docker Image on Merge + runs-on: ubuntu-latest + needs: build-test + if: github.event.pull_request.merged == true + + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Log in to Docker Hub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build Docker Image + run: | + docker build --no-cache -t mattmcdou/ci-cd-pipeline-automation-app:latest . + + - name: Tag & Push Versioned Image + run: | + VERSION=$(git rev-parse --short HEAD) + docker tag mattmcdou/ci-cd-pipeline-automation-app:latest mattmcdou/ci-cd-pipeline-automation-app:$VERSION + docker push mattmcdou/ci-cd-pipeline-automation-app:$VERSION + + - name: Push Latest Image + run: | + docker push mattmcdou/ci-cd-pipeline-automation-app:latest + diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..34cce40a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +# Use the correct gradle jdk image to avoid versioning issues +FROM gradle:7.6.4-jdk11 + +# Make the working directory +RUN mkdir /home/app +COPY . /home/app +WORKDIR /home/app + + +EXPOSE 8080 + +# Start the application, speed up the image build by excluding the daemon +CMD [ "gradle", "--no-daemon", "apprun"] \ No newline at end of file diff --git a/README-DEMO.md b/README-DEMO.md new file mode 100644 index 00000000..cef0ff62 --- /dev/null +++ b/README-DEMO.md @@ -0,0 +1,185 @@ +## Demo - demonstrates an application and tests + +This is an application by [Coveros](https://www.coveros.com/) to demonstrate good +software practices. As we say in agile... _Working software over comprehensive +documentation_ ... but that doesn't mean we can't have pretty good documentation too. + +#### Quick Start: + +* Install [Java](https://www.java.com/en/download/) if you don't already have it. +* Clone or [download](https://github.com/7ep/demo/archive/master.zip) this repo. (if you download, unzip the file to a directory.) +* On the command line in the top directory of this repo, run `gradlew apprun` +* Visit the application with your browser at http://localhost:8080/demo + +#### Summary: + +Demo consists of a simple web application and tests. Its goal is to provide +an environment suitable for demonstration and practice in valuable development +techniques. Some of the techniques exemplified are: +* [Unit](https://github.com/7ep/demo/blob/master/src/test/java/com/coveros/training/authentication/RegistrationUtilsTests.java) [tests](https://github.com/7ep/demo/blob/master/src/test/java/com/coveros/training/library/LibraryUtilsTests.java) developed by [TDD](https://en.wikipedia.org/wiki/Test-driven_development) using [Junit](https://junit.org/junit5/) as a driver and [Mockito](https://site.mockito.org/) for mocks, with coverage reports. +* [UI tests](https://github.com/7ep/demo/blob/master/src/ui_tests/behave/features/librarian_ui.feature) using [multiple frameworks](https://github.com/7ep/demo/tree/master/src/ui_tests) +* [BDD](https://en.wikipedia.org/wiki/Behavior-driven_development) [tests](https://github.com/7ep/demo/blob/master/src/bdd_test/resources/library/check_out_a_book.feature) using gherkin + * [Cucumber](https://docs.cucumber.io/) tests, with reports + * [Behave](https://behave.readthedocs.io/en/latest/) UI tests that use [Selenium](https://www.selenium.dev/) web driver. +* [Integration tests](https://github.com/7ep/demo/blob/master/src/integration_test/java/com/coveros/training/persistence/PersistenceLayerTests.java) that test the [H2 database](https://www.h2database.com/html/main.html) +* [Database versioning](https://github.com/7ep/demo/blob/master/src/main/resources/db/migration/V2__Rest_of_tables_for_auth_and_library.sql), with [Flyway](https://flywaydb.org/) +* Security analysis using [DependencyCheck](https://www.owasp.org/index.php/OWASP_Dependency_Check) +* Hot-swap code with [Gretty](https://github.com/gretty-gradle-plugin/gretty) +* Enhanced type system using [Checker Framework](https://checkerframework.org/) +* See its [architecture](https://github.com/7ep/demo/blob/master/docs/dev_notes/architecture.txt) + + +Its essential goals: +* Just works, any platform. +* As simple as possible +* Minimal system requirements +* Fast and easy to install and to run +* High test coverage +* Multiple business domains +* Easy to maintain and improve +* Well documented +* High performance +* Illustrates maximum number of techniques +* Easy to get up to speed + +#### Table of contents: +1. [Optional dependencies](#optional-dependencies) +1. [Chromedriver installation notes](#chromedriver-installation-notes) +1. [Python installation notes](#python-installation-notes) +1. [To build and run tests](#to-build-and-run-tests) +1. [To run the application](#to-run-the-web-application) +1. [To run API and UI tests](#to-run-api-and-ui-tests) +1. [Summary of relevant Gradle commands](#summary-of-relevant-gradle-commands) +1. [The whole shebang - CI/CD pipeline](#the-whole-shebang---a-cicd-pipeline) + +###### Optional Dependencies +If you want API testing and Selenium testing, you will need +to visit these links and download / install the applications found there. +* [Python](https://www.python.org/downloads/) +* [Chromedriver](http://chromedriver.chromium.org/downloads) +* [Chrome internet browser](https://www.google.com/chrome/) + +--- + +#### Chromedriver installation notes +make sure that the [Chromedriver](https://chromedriver.chromium.org/) executable is installed in one of the directories that is +on your path. To see your path, type the following in a command line: + +on Windows: + + echo %PATH% + +On Mac/Linux: + + echo $PATH + +If you run the command, `chromedriver` on the command line, you should get a result similar to this: + + Starting ChromeDriver ... + +#### Python installation notes +Python can be downloaded [here](https://www.python.org/downloads/) + +To run API tests and Selenium tests, an easy way to handle its +dependencies is to use *pipenv*. To get this installed, first download +[get-pip.py](https://bootstrap.pypa.io/get-pip.py), and run the following on the command line: + + python get-pip.py + +Then, + + pip install pipenv + +And in the demo directory, + + pipenv install + +#### To build and run tests: +On the command line, run the following: + +On Mac/Linux + + ./gradlew check + +On Windows + + gradlew check + +#### To run the web application: +On the command line, run the following: + +On Mac/Linux + + ./gradlew apprun + +On Windows + + gradlew apprun + +Then, head to http://localhost:8080/demo + + +#### To run API and UI tests: +Note: The app has to be [already running](#to-run-the-web-application) for these tests to pass, and you _need_ +to have installed [Python] and [Chromedriver]. + +In a new terminal, separate from the one where the server is running, run the following: + +On Mac/Linux + + ./gradlew runAllTests + +On Windows + + gradlew runAllTests + +#### Summary of relevant Gradle commands +* gradlew coveros - show a cheat sheet of commands for Demo +* gradlew apprun - runs the application +* gradlew check - runs all tests possible with only dependency being Java 8. No need for app to be running. +* gradlew runAllTests - runs the whole set of tests** +* gradlew clean - cleans build products and installs pre-push hook. (see the file in this directory, pre-push) +* gradlew runBehaveTests - runs the UI tests** +* gradlew runApiTests - runs the API tests** +* gradlew generateCucumberReport - runs cucumber and creates a nice-looking HTML report +* gradlew pitest - runs mutation testing (see http://pitest.org/) +* gradlew dependencyCheckAnalyze - analyzes security reports for the dependencies of + this project. See https://www.owasp.org/index.php/OWASP_Dependency_Check +* gradlew sonarqube - runs static analysis using SonarQube. Sonarqube must be running - check http://localhost:9000 +* gradlew integrate - runs the database integration tests +* gradlew startH2Console - Starts a console to examine the H2 database file. (user and + password are empty, URL to use is jdbc:h2:./build/db/training) +* gradlew ... taskTree - a utility that will show the task tree for a particular task + + + ** Requires the app to be running + (usually in another terminal) and all optional dependencies installed. + +#### The whole shebang - a CI/CD pipeline + +Details on building out a CI/CD pipeline are found in the "docs/ci_and_cd" directory. +For example, to set it all up on a [local Windows box](https://raw.githubusercontent.com/7ep/demo/master/docs/ci_and_cd/ci_and_cd_for_localhost.txt) + +###### Features of the pipeline: +* A fully functioning and documented demonstration CI/CD pipeline using Jenkins. +* BDD tests run with a report generated +* Static analysis quality-gating using SonarQube +* UI tests running on Chrome +* Performance testing with Jmeter +* Security analysis with OWASP's "DependencyCheck" +* Complex commands wrapped simply using Gradle +* Mutation testing with Pitest +* Javadocs built + + + +--- + +## Screenshots: +![Jenkins pipeline](https://c2.staticflickr.com/8/7889/33202009658_11422b7f20_b.jpg) + +![Zap attach proxy](https://c2.staticflickr.com/8/7905/33202009438_8f367e20ec_o.png) + +![SonarQube analysis](https://c2.staticflickr.com/8/7823/33202009548_e678128200_b.jpg) + +![Running performance tests](https://c2.staticflickr.com/8/7854/47077017751_7e045f68dd_b.jpg) diff --git a/README.md b/README.md index cef0ff62..8afe4446 100644 --- a/README.md +++ b/README.md @@ -1,185 +1,77 @@ -## Demo - demonstrates an application and tests - -This is an application by [Coveros](https://www.coveros.com/) to demonstrate good -software practices. As we say in agile... _Working software over comprehensive -documentation_ ... but that doesn't mean we can't have pretty good documentation too. - -#### Quick Start: - -* Install [Java](https://www.java.com/en/download/) if you don't already have it. -* Clone or [download](https://github.com/7ep/demo/archive/master.zip) this repo. (if you download, unzip the file to a directory.) -* On the command line in the top directory of this repo, run `gradlew apprun` -* Visit the application with your browser at http://localhost:8080/demo - -#### Summary: - -Demo consists of a simple web application and tests. Its goal is to provide -an environment suitable for demonstration and practice in valuable development -techniques. Some of the techniques exemplified are: -* [Unit](https://github.com/7ep/demo/blob/master/src/test/java/com/coveros/training/authentication/RegistrationUtilsTests.java) [tests](https://github.com/7ep/demo/blob/master/src/test/java/com/coveros/training/library/LibraryUtilsTests.java) developed by [TDD](https://en.wikipedia.org/wiki/Test-driven_development) using [Junit](https://junit.org/junit5/) as a driver and [Mockito](https://site.mockito.org/) for mocks, with coverage reports. -* [UI tests](https://github.com/7ep/demo/blob/master/src/ui_tests/behave/features/librarian_ui.feature) using [multiple frameworks](https://github.com/7ep/demo/tree/master/src/ui_tests) -* [BDD](https://en.wikipedia.org/wiki/Behavior-driven_development) [tests](https://github.com/7ep/demo/blob/master/src/bdd_test/resources/library/check_out_a_book.feature) using gherkin - * [Cucumber](https://docs.cucumber.io/) tests, with reports - * [Behave](https://behave.readthedocs.io/en/latest/) UI tests that use [Selenium](https://www.selenium.dev/) web driver. -* [Integration tests](https://github.com/7ep/demo/blob/master/src/integration_test/java/com/coveros/training/persistence/PersistenceLayerTests.java) that test the [H2 database](https://www.h2database.com/html/main.html) -* [Database versioning](https://github.com/7ep/demo/blob/master/src/main/resources/db/migration/V2__Rest_of_tables_for_auth_and_library.sql), with [Flyway](https://flywaydb.org/) -* Security analysis using [DependencyCheck](https://www.owasp.org/index.php/OWASP_Dependency_Check) -* Hot-swap code with [Gretty](https://github.com/gretty-gradle-plugin/gretty) -* Enhanced type system using [Checker Framework](https://checkerframework.org/) -* See its [architecture](https://github.com/7ep/demo/blob/master/docs/dev_notes/architecture.txt) - +# CI-CD-Pipeline-Automation -Its essential goals: -* Just works, any platform. -* As simple as possible -* Minimal system requirements -* Fast and easy to install and to run -* High test coverage -* Multiple business domains -* Easy to maintain and improve -* Well documented -* High performance -* Illustrates maximum number of techniques -* Easy to get up to speed - -#### Table of contents: -1. [Optional dependencies](#optional-dependencies) -1. [Chromedriver installation notes](#chromedriver-installation-notes) -1. [Python installation notes](#python-installation-notes) -1. [To build and run tests](#to-build-and-run-tests) -1. [To run the application](#to-run-the-web-application) -1. [To run API and UI tests](#to-run-api-and-ui-tests) -1. [Summary of relevant Gradle commands](#summary-of-relevant-gradle-commands) -1. [The whole shebang - CI/CD pipeline](#the-whole-shebang---a-cicd-pipeline) - -###### Optional Dependencies -If you want API testing and Selenium testing, you will need -to visit these links and download / install the applications found there. -* [Python](https://www.python.org/downloads/) -* [Chromedriver](http://chromedriver.chromium.org/downloads) -* [Chrome internet browser](https://www.google.com/chrome/) - ---- - -#### Chromedriver installation notes -make sure that the [Chromedriver](https://chromedriver.chromium.org/) executable is installed in one of the directories that is -on your path. To see your path, type the following in a command line: - -on Windows: - - echo %PATH% - -On Mac/Linux: - - echo $PATH - -If you run the command, `chromedriver` on the command line, you should get a result similar to this: - - Starting ChromeDriver ... - -#### Python installation notes -Python can be downloaded [here](https://www.python.org/downloads/) - -To run API tests and Selenium tests, an easy way to handle its -dependencies is to use *pipenv*. To get this installed, first download -[get-pip.py](https://bootstrap.pypa.io/get-pip.py), and run the following on the command line: - - python get-pip.py - -Then, - - pip install pipenv - -And in the demo directory, - - pipenv install - -#### To build and run tests: -On the command line, run the following: - -On Mac/Linux - - ./gradlew check - -On Windows - - gradlew check - -#### To run the web application: -On the command line, run the following: - -On Mac/Linux - - ./gradlew apprun - -On Windows - - gradlew apprun - -Then, head to http://localhost:8080/demo - - -#### To run API and UI tests: -Note: The app has to be [already running](#to-run-the-web-application) for these tests to pass, and you _need_ -to have installed [Python] and [Chromedriver]. - -In a new terminal, separate from the one where the server is running, run the following: +ENSF 400 - Course Project +Winter Semester 2025 -On Mac/Linux +Team members: - ./gradlew runAllTests +- Sachin Seizer +- Matthew McDougall +- Brendan SMILEY +- Luca Rios -On Windows - - gradlew runAllTests - -#### Summary of relevant Gradle commands -* gradlew coveros - show a cheat sheet of commands for Demo -* gradlew apprun - runs the application -* gradlew check - runs all tests possible with only dependency being Java 8. No need for app to be running. -* gradlew runAllTests - runs the whole set of tests** -* gradlew clean - cleans build products and installs pre-push hook. (see the file in this directory, pre-push) -* gradlew runBehaveTests - runs the UI tests** -* gradlew runApiTests - runs the API tests** -* gradlew generateCucumberReport - runs cucumber and creates a nice-looking HTML report -* gradlew pitest - runs mutation testing (see http://pitest.org/) -* gradlew dependencyCheckAnalyze - analyzes security reports for the dependencies of - this project. See https://www.owasp.org/index.php/OWASP_Dependency_Check -* gradlew sonarqube - runs static analysis using SonarQube. Sonarqube must be running - check http://localhost:9000 -* gradlew integrate - runs the database integration tests -* gradlew startH2Console - Starts a console to examine the H2 database file. (user and - password are empty, URL to use is jdbc:h2:./build/db/training) -* gradlew ... taskTree - a utility that will show the task tree for a particular task +## Project Initialization +1. Clone the repository - ** Requires the app to be running - (usually in another terminal) and all optional dependencies installed. - -#### The whole shebang - a CI/CD pipeline +2. Use Java JDK 11 -Details on building out a CI/CD pipeline are found in the "docs/ci_and_cd" directory. -For example, to set it all up on a [local Windows box](https://raw.githubusercontent.com/7ep/demo/master/docs/ci_and_cd/ci_and_cd_for_localhost.txt) +3. Ensure gretty is 3.0.6 not 3.0.4 +4. Follow the remainder of the instructions in the README.md -###### Features of the pipeline: -* A fully functioning and documented demonstration CI/CD pipeline using Jenkins. -* BDD tests run with a report generated -* Static analysis quality-gating using SonarQube -* UI tests running on Chrome -* Performance testing with Jmeter -* Security analysis with OWASP's "DependencyCheck" -* Complex commands wrapped simply using Gradle -* Mutation testing with Pitest -* Javadocs built +## GitHub Repository & Git Workflow (15%) +For our github workflow, we created rules to ensure branch protections. Those rules include not allowing collaborators to commit changes directly to main and requiring a reviewer for each pull request. +### Pull Request from @SuperSachinS ---- + -## Screenshots: -![Jenkins pipeline](https://c2.staticflickr.com/8/7889/33202009658_11422b7f20_b.jpg) +## Containerization (20%) -![Zap attach proxy](https://c2.staticflickr.com/8/7905/33202009438_8f367e20ec_o.png) +### Background/Development/Usage -![SonarQube analysis](https://c2.staticflickr.com/8/7823/33202009548_e678128200_b.jpg) +Below is the process taken to containerize the application: -![Running performance tests](https://c2.staticflickr.com/8/7854/47077017751_7e045f68dd_b.jpg) +1. Created a Dockerfile +2. Built the Docker image using `docker build --tag 'ensf400-g20' .` +3. Run the Docker image using `docker run -it -p 8080:8080 ensf400-g20` +4. An alternative way to run the Dockerfile: Run `docker compose up` to start the application and keep it running. +5. Access the application at `http://localhost:8080/demo` + +### Dockerfile + +The Dockerfile can be found [here](./Dockerfile) +As seen in the Dockerfile, we had to use the same versioning requirements that were needed to run the application locally. This meant using an exact gradle image with the correct version of gradle and java JDK. Afterwards the Dockerfile copies the project directory into the container and then runs the application using gradle instead of the gradle wrapper provided in the project. + +### Docker Compose + +The Docker Compose file can be found [here](./docker-compose.yml), this helps ensure that the containerization procedure will scale moving forward with the project. Additionally, we used the docker-compose.yml to ensure that the application did not immediately exit after starting up. + +### Docker Image on Docker Hub + +Our docker image can be found in a repository on docker hub [here](https://hub.docker.com/repository/docker/mattmcdou/ci-cd-pipeline-automation-app/tags/latest/sha256-cedc83a81df4c45f3a1312ecd1c3a48de0c5cf1e51c645d8446d645863fcfaca). + +use the following command to pull the image: + +```bash +docker pull mattmcdou/ci-cd-pipeline-automation-app:latest +``` + +use the following command to run the container, and keep it open: + +```bash +docker run -it -p 8080:8080 mattmcdou/ci-cd-pipeline-automation-app:latest +``` + +## CI/CD Pipeline Automation (40%) + +❗ TODO ❗ + +## Testing & Code Quality (10%) + +❗ TODO ❗ + +## Documentation & Demo (15%) + +❗ TODO ❗ diff --git a/build.gradle b/build.gradle index ff7b120e..06d04e4c 100644 --- a/build.gradle +++ b/build.gradle @@ -15,7 +15,7 @@ plugins { // gretty is a gradle plugin to make it easy to run a server and hotswap code at runtime. // https://plugins.gradle.org/plugin/org.gretty - id 'org.gretty' version '3.0.4' + id 'org.gretty' version '3.1.5' // provides access to a database versioning tool. id "org.flywaydb.flyway" version "6.0.8" diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..4e4d74b9 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,15 @@ +version: '3.8' + +services: + app: + build: . + container_name: my-gradle-app + ports: + - "8080:8080" + volumes: + - .:/home/app + working_dir: /home/app + command: ["./gradlew", "appRun"] + # so that the container doesn't immediately close after building + stdin_open: true + tty: true diff --git a/docs/BDD_video.mp4 b/docs/BDD_video.mp4 index 27c4646c..571239ed 100644 Binary files a/docs/BDD_video.mp4 and b/docs/BDD_video.mp4 differ diff --git a/report-media/PullRequest-Sachin.png b/report-media/PullRequest-Sachin.png new file mode 100644 index 00000000..cf551b06 Binary files /dev/null and b/report-media/PullRequest-Sachin.png differ