diff --git a/.github/workflows/pull-request-ci.yml b/.github/workflows/pull-request-ci.yml new file mode 100644 index 0000000..e024d20 --- /dev/null +++ b/.github/workflows/pull-request-ci.yml @@ -0,0 +1,112 @@ +name: Pull Request CI + +on: + pull_request: + branches: [ "main", "dev" ] + +permissions: + checks: write + pull-requests: write + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: 리포지토리 체크아웃 + uses: actions/checkout@v2 + + - name: JDK 17 버전 설치 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + + - name: Gradle 캐싱 + uses: actions/cache@v4 + id: cache-gradle + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: "${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}" + restore-keys: | + ${{ runner.os }}-gradle- + + - name: Docker Compose 설치 + run: | + sudo apt-get update + sudo apt-get install -y docker-compose + + - name: 테스트 인프라 환경 구축 + run: | + docker-compose -f ./docker/docker-compose.yml up -d + for i in {1..15}; do + docker exec mysql8-local mysqladmin ping -h 127.0.0.1 --silent && \ + nc -zv 127.0.0.1 6379 && \ + echo "테스트 인프라 환경 구축 완료." && exit 0 + echo "인프라 실행 대기중... ($i)" + sleep 1 + done + echo "테스트 인프라 환경 구축에 실패." && exit 1 + + - name: Gradle 실행 권한 설정 + run: chmod +x ./gradlew + + - name: 테스트 실행 + run: | + ./gradlew --info test + + - name: 테스트 결과 + uses: EnricoMi/publish-unit-test-result-action@v2 + if: always() + with: + junit_files: "build/test-results/test/**/*.xml" + + discord-web-hook: + runs-on: ubuntu-latest + needs: test + if: always() + + steps: + - name: 디스코드 알림 발송 + env: + DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }} + PR_BODY: ${{ github.event.pull_request.body }} + run: | + REPO="${{ github.repository }}" + PR_ACTION="${{ github.event.action }}" + PR_NUMBER="${{ github.event.pull_request.number }}" + PR_TITLE="${{ github.event.pull_request.title }}" + PR_URL="${{ github.event.pull_request.html_url }}" + SENDER_NAME="${{ github.event.sender.login }}" + SENDER_AVATAR="${{ github.event.sender.avatar_url }}" + TEST_RESULT_EMOJI=$([[ "${{ needs.test.result }}" == "success" ]] && echo "✅" || echo "❌") + + JSON_PAYLOAD=$(jq -n \ + --arg content "**${TEST_RESULT_EMOJI} WOOCO BE PULL REQUEST (<@&${{ secrets.DISCORD_MENTION_ID }}>)**" \ + --arg title "[${REPO}] ${PR_ACTION}: (#${PR_NUMBER}) ${PR_TITLE}" \ + --arg description "${PR_BODY}" \ + --arg url "${PR_URL}" \ + --arg username "${SENDER_NAME}" \ + --arg avatar_url "${SENDER_AVATAR}" \ + --argjson color 1376000 \ + '{ + content: $content, + embeds: [ + { + title: $title, + description: $description, + url: $url, + color: $color + } + ], + username: $username, + avatar_url: $avatar_url + }' + ) + + curl -X POST \ + -H "Content-Type: application/json" \ + -d "${JSON_PAYLOAD}" \ + "$DISCORD_WEBHOOK_URL" diff --git a/src/test/kotlin/kr/wooco/woocobe/support/MysqlCleaner.kt b/src/test/kotlin/kr/wooco/woocobe/support/MysqlCleaner.kt index 58f0958..9aa0787 100644 --- a/src/test/kotlin/kr/wooco/woocobe/support/MysqlCleaner.kt +++ b/src/test/kotlin/kr/wooco/woocobe/support/MysqlCleaner.kt @@ -29,13 +29,13 @@ class MysqlCleaner : TestListener { try { jdbcTemplate.dataSource?.connection!!.use { connection -> val metaData: DatabaseMetaData = connection.metaData - val tables = - metaData.getTables(null, null, null, arrayOf("TABLE")) - .use { resultSet -> - generateSequence { - resultSet.takeIf { it.next() }?.getString("TABLE_NAME") - }.toList() - } + val tables = metaData + .getTables(null, null, null, arrayOf("TABLE")) + .use { resultSet -> + generateSequence { + resultSet.takeIf { it.next() }?.getString("TABLE_NAME") + }.toList() + } return tables.filter { EXCLUDED_TABLES.contains(it).not() } } } catch (e: SQLException) { @@ -47,12 +47,14 @@ class MysqlCleaner : TestListener { tables: List, jdbcTemplate: JdbcTemplate, ) { - tables.forEach { table -> - jdbcTemplate.execute("TRUNCATE TABLE $table") - } + jdbcTemplate.execute("SET FOREIGN_KEY_CHECKS = 0") + tables.forEach { table -> jdbcTemplate.execute("TRUNCATE TABLE $table") } + jdbcTemplate.execute("SET FOREIGN_KEY_CHECKS = 1") } companion object { - private val EXCLUDED_TABLES = setOf("flyway_schema_history") + private val EXCLUDED_TABLES = setOf( + "flyway_schema_history", + ) } } diff --git a/src/test/resources/application-test.yml b/src/test/resources/application-test.yml index 2032a27..9c4dbb8 100644 --- a/src/test/resources/application-test.yml +++ b/src/test/resources/application-test.yml @@ -3,10 +3,19 @@ server: shutdown: graceful spring: + cookie: + path: / + max-age: 9876543210 + same-site: Lax + domain: localhost + secure: false + http-only: true + jpa: hibernate: - ddl-auto: update + ddl-auto: create-drop open-in-view: false + show-sql: true datasource: url: jdbc:mysql://localhost:3306/wooco-test-database?serverTimezone=Asia/Seoul&characterEncoding=UTF-8