Skip to content

Commit f26565a

Browse files
committed
chore: build ci/cd pipeline
1 parent 208062c commit f26565a

File tree

8 files changed

+301
-4
lines changed

8 files changed

+301
-4
lines changed

.github/workflows/CICD_DEVELOP.yml

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
name: CI/CD FOR DEVELOP
2+
3+
on:
4+
push:
5+
branches:
6+
- develop
7+
8+
env:
9+
DOCKERHUB_REPOSITORY: fontory-server
10+
11+
jobs:
12+
CI:
13+
name: Continuous Integration
14+
runs-on: ubuntu-latest
15+
permissions:
16+
contents: read
17+
18+
steps:
19+
- name: Get short SHA
20+
id: slug
21+
run: echo "sha7=$(echo ${GITHUB_SHA} | cut -c1-7)" >> $GITHUB_OUTPUT
22+
23+
- name: Discord Webhook Action
24+
uses: tsickert/[email protected]
25+
with:
26+
webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }}
27+
content: |
28+
New Commit[${{ steps.slug.outputs.sha7 }}] detected on branch ${{ github.ref_name }}
29+
Commit Link: https://github.com/${{ github.repository }}/commit/${{ github.sha }}
30+
GitHub Action Link: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
31+
32+
- name: Checkout
33+
uses: actions/checkout@v4
34+
35+
- name: Set up JDK 17
36+
uses: actions/setup-java@v4
37+
with:
38+
java-version: '17'
39+
distribution: 'temurin'
40+
41+
- name: Setup MySQL
42+
uses: mirromutth/[email protected]
43+
with:
44+
mysql database: 'TESTDB'
45+
mysql user: 'fontory'
46+
mysql password: 'fontoryPW'
47+
48+
- name: Setup Redis
49+
uses: supercharge/[email protected]
50+
with:
51+
redis-version: 6
52+
53+
- name: Setup Gradle
54+
uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0
55+
56+
- name: Generate application.properties
57+
run: |
58+
echo "commit.hash=${{ steps.slug.outputs.sha7 }}" >> ./src/main/resources/application-prod.properties
59+
echo "spring.datasource.url=jdbc:mysql://${{ secrets.DATASOURCE_DB_URL }}:3306/FONTORY?characterEncoding=UTF-8&serverTimezone=Asia/Seoul" >> ./src/main/resources/application-prod.properties
60+
echo "spring.datasource.username=${{ secrets.DATASOURCE_DB_USERNAME }}" >> ./src/main/resources/application-prod.properties
61+
echo "spring.datasource.password=${{ secrets.DATASOURCE_DB_PASSWORD }}" >> ./src/main/resources/application-prod.properties
62+
63+
- name: Build with Gradle Wrapper
64+
run: ./gradlew build
65+
66+
- name: Upload jar file to Artifact
67+
uses: actions/upload-artifact@v4
68+
with:
69+
name: jar_files
70+
path: build/libs/*.jar
71+
72+
- name: Upload Dockerfile to Artifact
73+
uses: actions/upload-artifact@v4
74+
with:
75+
name: Dockerfile
76+
path: ./Dockerfile
77+
78+
CD_Delivery:
79+
name: Delivery
80+
needs: CI
81+
runs-on: ubuntu-latest
82+
83+
permissions:
84+
contents: read
85+
86+
steps:
87+
- name: Download jar file from Artifact
88+
uses: actions/download-artifact@v4
89+
with:
90+
name: jar_files
91+
path: build/libs
92+
93+
- name: Download Dockerfile file from Artifact
94+
uses: actions/download-artifact@v4
95+
with:
96+
name: Dockerfile
97+
path: ./
98+
99+
- name: Log in to Docker Hub
100+
uses: docker/login-action@v3
101+
with:
102+
username: ${{ secrets.DOCKER_USERNAME }}
103+
password: ${{ secrets.DOCKER_PASSWORD }}
104+
105+
- name: Get short SHA
106+
id: slug
107+
run: echo "sha7=$(echo ${GITHUB_SHA} | cut -c1-7)" >> $GITHUB_OUTPUT
108+
109+
- name: Build, tag, and push image to DockerHub
110+
id: build-image
111+
env:
112+
USERNAME: ${{ secrets.DOCKER_USERNAME }}
113+
IMAGE_TAG: ${{ steps.slug.outputs.sha7 }}
114+
115+
run: |
116+
docker build -t $USERNAME/$DOCKERHUB_REPOSITORY:$IMAGE_TAG -t $USERNAME/$DOCKERHUB_REPOSITORY:latest .
117+
docker push $USERNAME/$DOCKERHUB_REPOSITORY --all-tags
118+
echo "image=$USERNAME/$DOCKERHUB_REPOSITORY:$IMAGE_TAG&latest" >> $GITHUB_OUTPUT
119+
120+
CD_Deploy:
121+
name: Deploy
122+
needs: CD_Delivery
123+
runs-on: ubuntu-latest
124+
125+
steps:
126+
- name: Get short SHA
127+
id: slug
128+
run: echo "sha7=$(echo ${GITHUB_SHA} | cut -c1-7)" >> $GITHUB_OUTPUT
129+
130+
- name: Executing remote ssh commands
131+
uses: appleboy/[email protected] # ssh 접속하는 오픈소스
132+
with:
133+
host: ${{ secrets.REMOTE_IP }} # 인스턴스 IP
134+
username: ${{ secrets.REMOTE_USER }} # 우분투 아이디
135+
key: ${{ secrets.REMOTE_PRIVATE_KEY }} # ec2 instance pem key
136+
port: ${{ secrets.REMOTE_SSH_PORT }} # 접속포트
137+
script: | # 실행할 스크립트
138+
cd /home/ubuntu/cicd/scripts
139+
./rolling-update.sh
140+
141+
- name: Discord Webhook Action
142+
uses: tsickert/[email protected]
143+
with:
144+
webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }}
145+
content: |
146+
:o: Server successfully updated!
147+
Commit: [${{ github.sha }}]
148+
Branch: ${{ github.ref_name }}
149+
Commit Link: https://github.com/${{ github.repository }}/commit/${{ github.sha }}
150+
GitHub Action Link: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
151+
152+
failure_notification:
153+
name: Failure Notification
154+
runs-on: ubuntu-latest
155+
if: failure()
156+
157+
steps:
158+
- name: Discord Webhook Action on Failure
159+
uses: tsickert/[email protected]
160+
with:
161+
webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }}
162+
content: |
163+
:x: A job failed in the CI/CD pipeline!
164+
Commit: [${{ github.sha }}]
165+
Branch: ${{ github.ref_name }}
166+
Commit Link: https://github.com/${{ github.repository }}/commit/${{ github.sha }}
167+
GitHub Action Link: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
168+
Please check the logs for more details.

.github/workflows/CI_TEST.yml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: CI TEST
2+
3+
on:
4+
push:
5+
branches-ignore:
6+
- main
7+
- develop
8+
9+
jobs:
10+
CI:
11+
name: Continuous Integration
12+
runs-on: ubuntu-latest
13+
permissions:
14+
contents: read
15+
16+
steps:
17+
- name: Checkout
18+
uses: actions/checkout@v4
19+
20+
- name: Set up JDK 17
21+
uses: actions/setup-java@v4
22+
with:
23+
java-version: '17'
24+
distribution: 'temurin'
25+
26+
- name: Setup MySQL
27+
uses: mirromutth/[email protected]
28+
with:
29+
mysql database: 'TESTDB'
30+
mysql user: 'fontory'
31+
mysql password: 'fontoryPW'
32+
33+
- name: Setup Redis
34+
uses: supercharge/[email protected]
35+
with:
36+
redis-version: 6
37+
38+
- name: Setup Gradle
39+
uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0
40+
41+
- name: Get short SHA
42+
id: slug
43+
run: echo "sha7=$(echo ${GITHUB_SHA} | cut -c1-7)" >> $GITHUB_OUTPUT
44+
45+
- name: Generate application.properties
46+
run: |
47+
# add properties
48+
49+
- name: Build with Gradle Wrapper
50+
run: ./gradlew build
51+

Dockerfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
FROM openjdk:17-alpine
2+
ARG JAR_FILE=build/libs/*.jar
3+
COPY ${JAR_FILE} app.jar
4+
ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=prod", "/app.jar"]

build.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,16 @@ test {
2929

3030
dependencies {
3131
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
32-
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
33-
implementation 'org.springframework.boot:spring-boot-starter-security'
32+
// implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
33+
// implementation 'org.springframework.boot:spring-boot-starter-security'
3434
implementation 'org.springframework.boot:spring-boot-starter-web'
3535
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
3636
compileOnly 'org.projectlombok:lombok'
3737
developmentOnly 'org.springframework.boot:spring-boot-devtools'
3838
runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'
3939
annotationProcessor 'org.projectlombok:lombok'
4040
testImplementation 'org.springframework.boot:spring-boot-starter-test'
41-
testImplementation 'org.springframework.security:spring-security-test'
41+
// testImplementation 'org.springframework.security:spring-security-test'
4242
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
4343
}
4444

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.fontory.fontorybe.common.controller;
2+
3+
import org.springframework.beans.factory.annotation.Value;
4+
import org.springframework.stereotype.Controller;
5+
import org.springframework.web.bind.annotation.GetMapping;
6+
import org.springframework.web.bind.annotation.ResponseBody;
7+
8+
@Controller
9+
public class HealthCheck {
10+
11+
@Value("${commit.hash}")
12+
public String commitHash;
13+
14+
@ResponseBody
15+
@GetMapping("/health-check")
16+
public String healthCheck() { return commitHash; }
17+
}

src/main/resources/application.properties

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@ spring.jpa.show-sql=true
66
spring.jpa.properties.hibernate.format_sql=true
77

88
spring.data.redis.host=localhost
9-
spring.data.redis.port=6379
9+
spring.data.redis.port=6379
10+
11+
commit.hash=local
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package org.fontory.fontorybe.port;
2+
3+
import org.junit.jupiter.api.Test;
4+
import org.springframework.beans.factory.annotation.Autowired;
5+
import org.springframework.boot.test.context.SpringBootTest;
6+
7+
import javax.sql.DataSource;
8+
import java.sql.Connection;
9+
import java.sql.SQLException;
10+
11+
import static org.assertj.core.api.Assertions.assertThat;
12+
import static org.assertj.core.api.Fail.fail;
13+
14+
@SpringBootTest
15+
public class DBConnectivityTest {
16+
17+
@Autowired
18+
private DataSource dataSource;
19+
20+
@Test
21+
void testDatabaseConnectivity() {
22+
try (Connection conn = dataSource.getConnection()) {
23+
assertThat(conn).isNotNull();
24+
} catch (SQLException e) {
25+
fail("DB 연결 실패: " + e.getMessage());
26+
}
27+
}
28+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package org.fontory.fontorybe.port;
2+
3+
import org.junit.jupiter.api.Test;
4+
import org.springframework.beans.factory.annotation.Autowired;
5+
import org.springframework.boot.test.context.SpringBootTest;
6+
import org.springframework.data.redis.core.RedisTemplate;
7+
8+
import static org.assertj.core.api.Assertions.assertThat;
9+
10+
@SpringBootTest
11+
public class RedisConnectivityTest {
12+
13+
@Autowired
14+
private RedisTemplate<String, String> redisTemplate;
15+
16+
@Test
17+
void testRedisConnectivity() {
18+
final String key = "key";
19+
final String value = "value";
20+
21+
redisTemplate.opsForValue().set(key, value);
22+
23+
String storedValue = redisTemplate.opsForValue().get(key);
24+
25+
assertThat(storedValue).isEqualTo(value);
26+
}
27+
}

0 commit comments

Comments
 (0)