diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..27c66393a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,61 @@ +name: CI/CD Pipeline + +on: + push: + branches: [ "main", "master" ] + pull_request: + branches: [ "main", "master" ] + +jobs: + build-test-deploy: + runs-on: ubuntu-latest + + steps: + - name: Check out repository code + uses: actions/checkout@v4 + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + cache: gradle + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + #(build) + #build and package + - name: Build and Package (JAR) + run: ./gradlew clean assemble + + #(test) + #run tests and generate coverage report + - name: Run Tests and Generate Coverage Report + run: ./gradlew test jacocoTestReport + + #upload jacoco test coverage artifact + - name: Upload Jacoco Test Coverage Artifact + uses: actions/upload-artifact@v4 + with: + name: Code-Coverage-Report + path: build/reports/jacoco/test/html/ + + #upload standard unit test results + - name: Upload Standard Unit Test Results + if: always() # Upload reports even if tests fail + uses: actions/upload-artifact@v4 + with: + name: Unit-Test-Results + path: build/reports/tests/test/ + + #(deploy) + #build docker image + - name: Build Docker Image (Deployment Staging) + run: docker build -t spring-music-app:latest . + + - name: Run and Verify Docker Container + run: | + docker run -d -p 8085:8085 --name spring-music-container spring-music-app:latest + sleep 10 + # Verify the container is actually running + docker ps | grep spring-music-container diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..127ea2df3 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +# Use an official lightweight Java 17 Runtime as the base image +FROM eclipse-temurin:17-jre-alpine + +# Set the working directory inside the container +WORKDIR /app + +# Copy the built JAR file into the container +COPY build/libs/spring-music-1.0.jar app.jar + +# Expose port 8080, which is the default port the Spring Boot app runs on +EXPOSE 8085 + +# Define the command to run the application when the container starts +ENTRYPOINT ["java", "-jar", "app.jar", "--server.port=8085"] diff --git a/build.gradle b/build.gradle index 92e1bf8a5..3f6e250a4 100644 --- a/build.gradle +++ b/build.gradle @@ -4,6 +4,11 @@ plugins { id 'java' id 'eclipse-wtp' id 'idea' + id 'jacoco' +} + +jacoco { + toolVersion = "0.8.11" } group = 'org.cloudfoundry.samples.music' @@ -75,3 +80,32 @@ jar { tasks.named("bootBuildImage") { builder = "paketobuildpacks/builder-jammy-base:latest" } + +test { + testLogging { + events 'passed', 'skipped', 'failed' + } + finalizedBy jacocoTestReport +} + +jacocoTestReport { + dependsOn test + afterEvaluate { + classDirectories.setFrom(files(classDirectories.files.collect { + fileTree(dir: it, exclude: [ + 'org/cloudfoundry/samples/music/config/**', + 'org/cloudfoundry/samples/music/Application.class', + 'org/cloudfoundry/samples/music/repositories/redis/**', + 'org/cloudfoundry/samples/music/repositories/jpa/**', + 'org/cloudfoundry/samples/music/repositories/mongodb/**', + 'org/cloudfoundry/samples/music/repositories/AlbumRepositoryPopulator.class', + 'org/cloudfoundry/samples/music/web/ErrorController.class', + 'org/cloudfoundry/samples/music/web/InfoController.class' + ]) + })) + } + reports { + xml.required = true + html.required = true + } +} diff --git a/scc tan chi hong.docx b/scc tan chi hong.docx new file mode 100644 index 000000000..5e6b2741a Binary files /dev/null and b/scc tan chi hong.docx differ diff --git a/src/main/resources/static/templates/albums.html b/src/main/resources/static/templates/albums.html index 77baee53f..ac8eeb42d 100644 --- a/src/main/resources/static/templates/albums.html +++ b/src/main/resources/static/templates/albums.html @@ -1,6 +1,6 @@