diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..66368d49 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,58 @@ +name: CI + +on: + push: + branches: '**' + pull_request: + branches: [ master ] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + distribution: 'adopt' + java-version: '17' + + - name: Build with Gradle + run: gradle build + + - name: Upload Build Artifacts + uses: actions/upload-artifact@v3 + with: + name: build-artifacts + path: build/libs/sample-java-project-V1.jar # Adjusted to the correct JAR file name + + - name: Run Unit Test + run: gradle test + + - name: Upload Test Reports + uses: actions/upload-artifact@v3 + with: + name: test-reports + path: build/reports/tests/test/* + + - name: Generate code coverage report + run: gradle jacocoTestReport + + - name: Upload code coverage report + uses: actions/upload-artifact@v3 + with: + name: code-coverage-report + path: build/reports/jacoco/test/html/** + + - name: Build Docker image + run: docker build -t sample-java-project . + + - name: Run Docker container + run: docker run -d -p 8080:8080 --name sample-java-project-container sample-java-project + + - name: Verify Docker container is running + run: docker ps + diff --git a/.gradle/7.1.1/dependencies-accessors/dependencies-accessors.lock b/.gradle/7.1.1/dependencies-accessors/dependencies-accessors.lock new file mode 100644 index 00000000..3f7bbdcd Binary files /dev/null and b/.gradle/7.1.1/dependencies-accessors/dependencies-accessors.lock differ diff --git a/.gradle/7.1.1/dependencies-accessors/gc.properties b/.gradle/7.1.1/dependencies-accessors/gc.properties new file mode 100644 index 00000000..e69de29b diff --git a/.gradle/7.1.1/executionHistory/executionHistory.bin b/.gradle/7.1.1/executionHistory/executionHistory.bin new file mode 100644 index 00000000..51e23ba4 Binary files /dev/null and b/.gradle/7.1.1/executionHistory/executionHistory.bin differ diff --git a/.gradle/7.1.1/executionHistory/executionHistory.lock b/.gradle/7.1.1/executionHistory/executionHistory.lock new file mode 100644 index 00000000..897ddca9 Binary files /dev/null and b/.gradle/7.1.1/executionHistory/executionHistory.lock differ diff --git a/.gradle/7.1.1/fileChanges/last-build.bin b/.gradle/7.1.1/fileChanges/last-build.bin new file mode 100644 index 00000000..f76dd238 Binary files /dev/null and b/.gradle/7.1.1/fileChanges/last-build.bin differ diff --git a/.gradle/7.1.1/fileHashes/fileHashes.bin b/.gradle/7.1.1/fileHashes/fileHashes.bin new file mode 100644 index 00000000..e0e0cb22 Binary files /dev/null and b/.gradle/7.1.1/fileHashes/fileHashes.bin differ diff --git a/.gradle/7.1.1/fileHashes/fileHashes.lock b/.gradle/7.1.1/fileHashes/fileHashes.lock new file mode 100644 index 00000000..bef1f16b Binary files /dev/null and b/.gradle/7.1.1/fileHashes/fileHashes.lock differ diff --git a/.gradle/7.1.1/fileHashes/resourceHashesCache.bin b/.gradle/7.1.1/fileHashes/resourceHashesCache.bin new file mode 100644 index 00000000..254f59f1 Binary files /dev/null and b/.gradle/7.1.1/fileHashes/resourceHashesCache.bin differ diff --git a/.gradle/7.1.1/gc.properties b/.gradle/7.1.1/gc.properties new file mode 100644 index 00000000..e69de29b diff --git a/.gradle/8.7/checksums/checksums.lock b/.gradle/8.7/checksums/checksums.lock new file mode 100644 index 00000000..9895d62e Binary files /dev/null and b/.gradle/8.7/checksums/checksums.lock differ diff --git a/.gradle/8.7/checksums/sha1-checksums.bin b/.gradle/8.7/checksums/sha1-checksums.bin new file mode 100644 index 00000000..ec53be84 Binary files /dev/null and b/.gradle/8.7/checksums/sha1-checksums.bin differ diff --git a/.gradle/8.7/dependencies-accessors/gc.properties b/.gradle/8.7/dependencies-accessors/gc.properties new file mode 100644 index 00000000..e69de29b diff --git a/.gradle/8.7/expanded/expanded.lock b/.gradle/8.7/expanded/expanded.lock new file mode 100644 index 00000000..f7ac117f Binary files /dev/null and b/.gradle/8.7/expanded/expanded.lock differ diff --git a/.gradle/8.7/fileChanges/last-build.bin b/.gradle/8.7/fileChanges/last-build.bin new file mode 100644 index 00000000..f76dd238 Binary files /dev/null and b/.gradle/8.7/fileChanges/last-build.bin differ diff --git a/.gradle/8.7/fileHashes/fileHashes.bin b/.gradle/8.7/fileHashes/fileHashes.bin new file mode 100644 index 00000000..9b79a98f Binary files /dev/null and b/.gradle/8.7/fileHashes/fileHashes.bin differ diff --git a/.gradle/8.7/fileHashes/fileHashes.lock b/.gradle/8.7/fileHashes/fileHashes.lock new file mode 100644 index 00000000..afb7eb84 Binary files /dev/null and b/.gradle/8.7/fileHashes/fileHashes.lock differ diff --git a/.gradle/8.7/gc.properties b/.gradle/8.7/gc.properties new file mode 100644 index 00000000..e69de29b diff --git a/.gradle/8.8/checksums/checksums.lock b/.gradle/8.8/checksums/checksums.lock new file mode 100644 index 00000000..8cd45698 Binary files /dev/null and b/.gradle/8.8/checksums/checksums.lock differ diff --git a/.gradle/8.8/checksums/md5-checksums.bin b/.gradle/8.8/checksums/md5-checksums.bin new file mode 100644 index 00000000..a8fe227b Binary files /dev/null and b/.gradle/8.8/checksums/md5-checksums.bin differ diff --git a/.gradle/8.8/checksums/sha1-checksums.bin b/.gradle/8.8/checksums/sha1-checksums.bin new file mode 100644 index 00000000..027f3a58 Binary files /dev/null and b/.gradle/8.8/checksums/sha1-checksums.bin differ diff --git a/.gradle/8.8/dependencies-accessors/gc.properties b/.gradle/8.8/dependencies-accessors/gc.properties new file mode 100644 index 00000000..e69de29b diff --git a/.gradle/8.8/fileChanges/last-build.bin b/.gradle/8.8/fileChanges/last-build.bin new file mode 100644 index 00000000..f76dd238 Binary files /dev/null and b/.gradle/8.8/fileChanges/last-build.bin differ diff --git a/.gradle/8.8/fileHashes/fileHashes.bin b/.gradle/8.8/fileHashes/fileHashes.bin new file mode 100644 index 00000000..95bc6f30 Binary files /dev/null and b/.gradle/8.8/fileHashes/fileHashes.bin differ diff --git a/.gradle/8.8/fileHashes/fileHashes.lock b/.gradle/8.8/fileHashes/fileHashes.lock new file mode 100644 index 00000000..27c8362b Binary files /dev/null and b/.gradle/8.8/fileHashes/fileHashes.lock differ diff --git a/.gradle/8.8/gc.properties b/.gradle/8.8/gc.properties new file mode 100644 index 00000000..e69de29b diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock new file mode 100644 index 00000000..504e7a57 Binary files /dev/null and b/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/.gradle/buildOutputCleanup/outputFiles.bin b/.gradle/buildOutputCleanup/outputFiles.bin new file mode 100644 index 00000000..8e8273f5 Binary files /dev/null and b/.gradle/buildOutputCleanup/outputFiles.bin differ diff --git a/.gradle/checksums/checksums.lock b/.gradle/checksums/checksums.lock new file mode 100644 index 00000000..db305f4b Binary files /dev/null and b/.gradle/checksums/checksums.lock differ diff --git a/.gradle/checksums/md5-checksums.bin b/.gradle/checksums/md5-checksums.bin new file mode 100644 index 00000000..350060a8 Binary files /dev/null and b/.gradle/checksums/md5-checksums.bin differ diff --git a/.gradle/checksums/sha1-checksums.bin b/.gradle/checksums/sha1-checksums.bin new file mode 100644 index 00000000..0533331f Binary files /dev/null and b/.gradle/checksums/sha1-checksums.bin differ diff --git a/.gradle/nb-cache/sample-java-project-1679043201/project-info.ser b/.gradle/nb-cache/sample-java-project-1679043201/project-info.ser new file mode 100644 index 00000000..c676d311 Binary files /dev/null and b/.gradle/nb-cache/sample-java-project-1679043201/project-info.ser differ diff --git a/.gradle/nb-cache/subprojects.ser b/.gradle/nb-cache/subprojects.ser new file mode 100644 index 00000000..7da7a31c Binary files /dev/null and b/.gradle/nb-cache/subprojects.ser differ diff --git a/.gradle/nb-cache/trust/F408E4CA12EA168DE724C1DAA09E6DA0A37FBC06D92F880DD6083151C5D6EAEB b/.gradle/nb-cache/trust/F408E4CA12EA168DE724C1DAA09E6DA0A37FBC06D92F880DD6083151C5D6EAEB new file mode 100644 index 00000000..5a527029 --- /dev/null +++ b/.gradle/nb-cache/trust/F408E4CA12EA168DE724C1DAA09E6DA0A37FBC06D92F880DD6083151C5D6EAEB @@ -0,0 +1 @@ +1B39AD23E1EB7E69EEE2B0998A2A14CEED0D7DBBC876C8CE3D93C2BE9F8723E0 diff --git a/.gradle/vcs-1/gc.properties b/.gradle/vcs-1/gc.properties new file mode 100644 index 00000000..e69de29b diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..be1bcf92 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,11 @@ +# Use OpenJDK 11 runtime as base image +FROM openjdk:11-jre-slim + +# Set the working directory +WORKDIR /app + +# Copy the jar file into the container +COPY build/libs/sample-java-project-V1.jar /app/sample-java-project.jar + +# Run the jar file +CMD ["java", "-jar", "/app/sample-java-project.jar"] diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 00000000..a0fab20b --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,44 @@ +pipeline { + agent any + stages { + stage('Checkout') { + steps { + echo 'Checking out source code' + git branch: 'master', url: 'https://github.com/yyxxxy/sample-java-project.git' + } + } + stage('Build') { + steps { + echo 'Running Gradle build' + // powershell 'gradle --no-daemon clean build' + powershell 'gradle clean build' + } + } + stage('Test') { + steps { + echo 'Running Gradle tests' + // powershell 'gradle --no-daemon test' + powershell 'gradle test' + } + } + stage('Deploy') { + steps { + powershell 'java -jar build/libs/sample-java-project-V1.jar --name yu' + } + } + } + post { + always { + echo 'Cleaning up workspace' + deleteDir() // Clean up the workspace after the build + } + success { + echo 'Build succeeded!!!' + // You could add notification steps here + } + failure { + echo 'Build failed!' + // You could add notification steps here + } + } +} diff --git a/build.gradle b/build.gradle new file mode 100644 index 00000000..a2aad4de --- /dev/null +++ b/build.gradle @@ -0,0 +1,94 @@ +apply plugin: 'java' +apply plugin:'jacoco' +jacoco { + toolVersion = "0.8.6" +} +java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 +} +group = 'com.example' +version = 'V1' + +repositories { + mavenCentral() +} + +dependencies { + implementation 'com.beust:jcommander:1.81' // JCommander dependency + implementation 'org.projectlombok:lombok:1.18.26' // Lombok dependency + annotationProcessor 'org.projectlombok:lombok:1.18.26' // Lombok annotation processor + testImplementation 'junit:junit:4.13.2' +} + +test { + // Specify the directory containing test classes + testClassesDirs = sourceSets.test.output.classesDirs + + // Optionally configure test options + testLogging { + // Configure which events to log during test execution + events 'passed', 'skipped', 'failed' + } + finalizedBy jacocoTestReport +} + +jar { + manifest { + attributes( + 'Main-Class': 'com.example.SampleJavaProject' // Main class to run + ) + } + from { + configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } + } + with copySpec { + from sourceSets.main.output // Include compiled classes + into '' + } + duplicatesStrategy = DuplicatesStrategy.EXCLUDE // Handle duplicate files by excluding duplicates + archiveBaseName.set('sample-java-project') // Name of the JAR file + archiveVersion.set('V1') // Version of the JAR file + destinationDirectory.set(file("$buildDir/libs")) // Output directory for the JAR file +} + +// jar { +// manifest { +// attributes 'Main-Class': 'com.example.SampleJavaProject' +// } + +// from sourceSets.main.output // Include compiled classes in the JAR +// archiveBaseName = 'sample-java-project' // Name of the JAR file +// destinationDirectory = file('build/libs') // Output directory for the JAR file +// } + +jacocoTestReport { + dependsOn test + reports { + xml.required = true + html.required = true + xml.destination = file("$buildDir/reports/jacoco/xml") + html.destination = file("$buildDir/reports/jacoco/html") + } +} + +task buildReport { + group = 'Reporting' + description = 'Generates a summary report of the build, including test and coverage results.' + + doLast { + println '--- Build Summary ---' + println "Build Version: ${version}" + println "Source Compatibility: ${sourceCompatibility}" + println "Target Compatibility: ${targetCompatibility}" + println 'Test Results:' + println "HTML: file:///${buildDir}/reports/tests/index.html" + println "JUnit XML: file:///${buildDir}/test-results/test/TESTS-TestSuites.xml" + println 'Coverage Report:' + println "HTML: file:///${buildDir}/reports/jacoco/html/index.html" + println "XML: file:///${buildDir}/reports/jacoco/xml/jacocoTestReport.xml" + } +} + +// Ensure the custom report runs after the build +build.finalizedBy(buildReport) diff --git a/cypress.config.js b/cypress.config.js new file mode 100644 index 00000000..97f47c41 --- /dev/null +++ b/cypress.config.js @@ -0,0 +1,9 @@ +const { defineConfig } = require("cypress"); + +module.exports = defineConfig({ + e2e: { + setupNodeEvents(on, config) { + // implement node event listeners here + }, + }, +}); diff --git a/cypress/e2e/1-getting-started/todo.cy.js b/cypress/e2e/1-getting-started/todo.cy.js new file mode 100644 index 00000000..4768ff92 --- /dev/null +++ b/cypress/e2e/1-getting-started/todo.cy.js @@ -0,0 +1,143 @@ +/// + +// Welcome to Cypress! +// +// This spec file contains a variety of sample tests +// for a todo list app that are designed to demonstrate +// the power of writing tests in Cypress. +// +// To learn more about how Cypress works and +// what makes it such an awesome testing tool, +// please read our getting started guide: +// https://on.cypress.io/introduction-to-cypress + +describe('example to-do app', () => { + beforeEach(() => { + // Cypress starts out with a blank slate for each test + // so we must tell it to visit our website with the `cy.visit()` command. + // Since we want to visit the same URL at the start of all our tests, + // we include it in our beforeEach function so that it runs before each test + cy.visit('https://example.cypress.io/todo') + }) + + it('displays two todo items by default', () => { + // We use the `cy.get()` command to get all elements that match the selector. + // Then, we use `should` to assert that there are two matched items, + // which are the two default items. + cy.get('.todo-list li').should('have.length', 2) + + // We can go even further and check that the default todos each contain + // the correct text. We use the `first` and `last` functions + // to get just the first and last matched elements individually, + // and then perform an assertion with `should`. + cy.get('.todo-list li').first().should('have.text', 'Pay electric bill') + cy.get('.todo-list li').last().should('have.text', 'Walk the dog') + }) + + it('can add new todo items', () => { + // We'll store our item text in a variable so we can reuse it + const newItem = 'Feed the cat' + + // Let's get the input element and use the `type` command to + // input our new list item. After typing the content of our item, + // we need to type the enter key as well in order to submit the input. + // This input has a data-test attribute so we'll use that to select the + // element in accordance with best practices: + // https://on.cypress.io/selecting-elements + cy.get('[data-test=new-todo]').type(`${newItem}{enter}`) + + // Now that we've typed our new item, let's check that it actually was added to the list. + // Since it's the newest item, it should exist as the last element in the list. + // In addition, with the two default items, we should have a total of 3 elements in the list. + // Since assertions yield the element that was asserted on, + // we can chain both of these assertions together into a single statement. + cy.get('.todo-list li') + .should('have.length', 3) + .last() + .should('have.text', newItem) + }) + + it('can check off an item as completed', () => { + // In addition to using the `get` command to get an element by selector, + // we can also use the `contains` command to get an element by its contents. + // However, this will yield the