diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..9da0d1b --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,121 @@ +name: CI + +on: + pull_request: + push: + branches: + - main + +permissions: + contents: read + packages: write + pull-requests: write + +jobs: + build: + runs-on: ubuntu-24.04 + name: Build + + steps: + - uses: actions/checkout@v4 + + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'temurin' + cache: gradle + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Build project + run: ./gradlew bootJar + + test: + runs-on: ubuntu-24.04 + name: Test + needs: build + + steps: + - uses: actions/checkout@v4 + + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'temurin' + cache: gradle + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Run tests + run: ./gradlew test + + - name: Run tests with coverage + run: ./gradlew jacocoTestReport + + - name: Jacoco Report to PR + id: jacoco + uses: madrapps/jacoco-report@v1.7.1 + with: + paths: ${{ github.workspace }}/build/reports/jacoco/test/jacocoTestReport.xml + token: ${{ secrets.GITHUB_TOKEN }} + + min-coverage-overall: 40 + min-coverage-changed-files: 60 + title: Code Coverage + update-comment: true + + lint: + runs-on: ubuntu-24.04 + name: Style + needs: build + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'temurin' + cache: gradle + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Run static code analysis + run: ./gradlew checkstyleMain + + package: + runs-on: ubuntu-24.04 + name: Package + needs: [test, lint] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GTHB_TOKEN }} + + - name: Build and push Docker image + uses: docker/build-push-action@v6 + with: + context: . + file: ./docker/fintech.Dockerfile + push: true + tags: ghcr.io/alexandergarifullin/fintech:latest \ No newline at end of file diff --git a/build.gradle b/build.gradle index 4bb30ee..65c3864 100644 --- a/build.gradle +++ b/build.gradle @@ -2,6 +2,8 @@ plugins { id 'java' id 'org.springframework.boot' version '3.3.4' id 'io.spring.dependency-management' version '1.1.6' + id 'jacoco' + id 'checkstyle' } group = 'com.cf' @@ -17,6 +19,11 @@ repositories { mavenCentral() } +checkstyle { + toolVersion = '10.3' + configFile = file("${rootDir}/config/checkstyle/checkstyle.xml") +} + dependencies { // spring implementation 'org.springframework.boot:spring-boot-starter-web' @@ -32,9 +39,25 @@ dependencies { // test testImplementation 'org.springframework.boot:spring-boot-starter-test' - testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + testImplementation 'org.testcontainers:junit-jupiter:1.20.1' + testImplementation 'org.wiremock:wiremock-standalone:3.9.1' + testImplementation 'org.wiremock.integrations.testcontainers:wiremock-testcontainers-module:1.0-alpha-14' + testImplementation 'org.testcontainers:postgresql:1.20.3' + testImplementation 'org.liquibase:liquibase-core:4.29.2' } tasks.named('test') { useJUnitPlatform() } + +tasks.test { + jvmArgs '-XX:+EnableDynamicAgentLoading' + systemProperty "spring.profiles.active", "test" +} + +jacocoTestReport { + reports { + html.required = true + xml.required = true + } +} \ No newline at end of file diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml new file mode 100644 index 0000000..b690f74 --- /dev/null +++ b/config/checkstyle/checkstyle.xml @@ -0,0 +1,412 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 0000000..b16eff8 --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,27 @@ +version: "3.9" +services: + db: + image: postgres:17 + ports: + - "5432:5432" + environment: + - POSTGRES_USER=postgres + - POSTGRES_PASSWORD=123 + - POSTGRES_DB=CodeforcesLocalDB + volumes: + - db_data:/var/lib/postgresql/data + app: + build: . + ports: + - "8080:8080" + depends_on: + - db + environment: + - POSTGRES_CONTAINER_NAME=db + - POSTGRES_PORT=5432 + - POSTGRES_USER=postgres + - POSTGRES_PASSWORD=123 + - POSTGRES_DB=CodeforcesLocalDB + - SPRING_PROFILES_ACTIVE=prod +volumes: + db_data: \ No newline at end of file diff --git a/docker/fintech.Dockerfile b/docker/fintech.Dockerfile new file mode 100644 index 0000000..ac685e4 --- /dev/null +++ b/docker/fintech.Dockerfile @@ -0,0 +1,22 @@ +FROM openjdk:21-jdk-slim AS builder +WORKDIR /app + +COPY ./gradlew ./gradlew +COPY ./gradle ./gradle +COPY ./build.gradle ./build.gradle +COPY ./settings.gradle ./settings.gradle +COPY ./src ./src + +RUN chmod +x ./gradlew + +RUN ./gradlew bootJar --no-daemon + +FROM openjdk:21-jdk-slim + +WORKDIR /app + +COPY --from=builder /app/build/libs/*.jar app.jar + +EXPOSE 8080 + +CMD ["java", "-jar", "app.jar"] \ No newline at end of file diff --git a/src/main/java/com/cf/cfteam/repositories/jpa/codeforces/CfUserRepository.java b/src/main/java/com/cf/cfteam/repositories/jpa/codeforces/CfUserRepository.java index c415c70..f389a6a 100644 --- a/src/main/java/com/cf/cfteam/repositories/jpa/codeforces/CfUserRepository.java +++ b/src/main/java/com/cf/cfteam/repositories/jpa/codeforces/CfUserRepository.java @@ -3,5 +3,5 @@ import com.cf.cfteam.models.entities.codeforces.CfUser; import org.springframework.data.jpa.repository.JpaRepository; -public interface CfUserRepository extends JpaRepository { +public interface CfUserRepository extends JpaRepository { } diff --git a/src/main/resources/db/changelog/db.changelog-test.yaml b/src/main/resources/db/changelog/db.changelog-test.yaml new file mode 100644 index 0000000..59a4c39 --- /dev/null +++ b/src/main/resources/db/changelog/db.changelog-test.yaml @@ -0,0 +1,5 @@ +databaseChangeLog: + - include: + file: db/changelog/security-changelog.sql + - include: + file: db/changelog/codeforces-changelog.sql \ No newline at end of file diff --git a/src/test/java/com/cf/cfteam/CfteamApplicationTests.java b/src/test/java/com/cf/cfteam/CfteamApplicationTests.java deleted file mode 100644 index 87363cd..0000000 --- a/src/test/java/com/cf/cfteam/CfteamApplicationTests.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.cf.cfteam; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class CfteamApplicationTests { - - @Test - void contextLoads() { - } - -} diff --git a/src/test/resources/application-test.yml b/src/test/resources/application-test.yml new file mode 100644 index 0000000..7fbe184 --- /dev/null +++ b/src/test/resources/application-test.yml @@ -0,0 +1,3 @@ +liquibase: + change-log: classpath:db/changelog/db.changelog-test.yaml + enabled: true \ No newline at end of file