@@ -2,14 +2,11 @@ name: CI
22
33on :
44 push :
5- branches : [ "main" ]
5+ branches : ["main"]
66
77permissions :
88 contents : read
99
10- env :
11- REGISTRY : ${{ secrets.OCIR_HOST }}
12-
1310jobs :
1411 build-and-push :
1512 runs-on : ubuntu-latest
@@ -18,34 +15,69 @@ jobs:
1815 - name : Checkout
1916 uses : actions/checkout@v4
2017
18+ # --------------------------
19+ # 0) Sanitize secrets (host/newlines)
20+ # --------------------------
21+ - name : Sanitize connection vars
22+ id : sanitize
23+ shell : bash
24+ run : |
25+ set -euo pipefail
26+
27+ # SSH host: remove CR/LF, strip http(s):// prefix
28+ SSH_HOST_CLEAN="$(printf '%s' "${{ secrets.SSH_HOST }}" | tr -d '\r\n' | sed -E 's#^https?://##')"
29+
30+ # OCIR vars: remove CR/LF
31+ OCIR_HOST_CLEAN="$(printf '%s' "${{ secrets.OCIR_HOST }}" | tr -d '\r\n')"
32+ OCIR_NS_CLEAN="$(printf '%s' "${{ secrets.OCIR_TENANCY_NAMESPACE }}" | tr -d '\r\n')"
33+ OCIR_REPO_CLEAN="$(printf '%s' "${{ secrets.OCIR_REPO }}" | tr -d '\r\n')"
34+ OCIR_USER_CLEAN="$(printf '%s' "${{ secrets.OCIR_USERNAME }}" | tr -d '\r\n')"
35+
36+ # Validate minimal formats (fail fast)
37+ if [[ -z "$SSH_HOST_CLEAN" ]]; then
38+ echo "SSH_HOST is empty after sanitizing" >&2
39+ exit 1
40+ fi
41+ if [[ "$SSH_HOST_CLEAN" == *"/"* ]]; then
42+ echo "SSH_HOST should be only an IP/hostname, got: $SSH_HOST_CLEAN" >&2
43+ exit 1
44+ fi
45+ if [[ -z "$OCIR_HOST_CLEAN" || -z "$OCIR_NS_CLEAN" || -z "$OCIR_REPO_CLEAN" || -z "$OCIR_USER_CLEAN" ]]; then
46+ echo "One of OCIR secrets is empty after sanitizing" >&2
47+ exit 1
48+ fi
49+
50+ echo "ssh_host=$SSH_HOST_CLEAN" >> "$GITHUB_OUTPUT"
51+ echo "ocir_host=$OCIR_HOST_CLEAN" >> "$GITHUB_OUTPUT"
52+ echo "ocir_ns=$OCIR_NS_CLEAN" >> "$GITHUB_OUTPUT"
53+ echo "ocir_repo=$OCIR_REPO_CLEAN" >> "$GITHUB_OUTPUT"
54+ echo "ocir_user=$OCIR_USER_CLEAN" >> "$GITHUB_OUTPUT"
55+
56+ # --------------------------
57+ # 1) Build JAR (Gradle)
58+ # --------------------------
2159 - name : Set up JDK
2260 uses : actions/setup-java@v4
2361 with :
2462 distribution : " temurin"
2563 java-version : " 17"
2664 cache : gradle
2765
28- - name : Build + Test(Gradle)
66+ - name : Build (Gradle)
67+ if : ${{ hashFiles('**/build.gradle*') != '' }}
2968 run : |
3069 chmod +x ./gradlew
3170 ./gradlew clean bootJar
3271 JAR=$(ls build/libs/*.jar | head -n 1)
3372 cp "$JAR" app.jar
3473
74+ # --------------------------
75+ # 2) Compute image name + tags
76+ # --------------------------
3577 - name : Compute image name (OCIR)
3678 id : img
3779 run : |
38- REG="$(printf '%s' "${{ secrets.OCIR_HOST }}" | tr -d '\r\n')"
39- NS="$(printf '%s' "${{ secrets.OCIR_TENANCY_NAMESPACE }}" | tr -d '\r\n')"
40- REPO="$(printf '%s' "${{ secrets.OCIR_REPO }}" | tr -d '\r\n')"
41- echo "name=${REG}/${NS}/${REPO}" >> "$GITHUB_OUTPUT"
42-
43- - name : Log in to OCIR
44- uses : docker/login-action@v3
45- with :
46- registry : ${{ secrets.OCIR_HOST }}
47- username : ${{ secrets.OCIR_USERNAME }}
48- password : ${{ secrets.OCIR_AUTH_TOKEN }}
80+ echo "name=${{ steps.sanitize.outputs.ocir_host }}/${{ steps.sanitize.outputs.ocir_ns }}/${{ steps.sanitize.outputs.ocir_repo }}" >> "$GITHUB_OUTPUT"
4981
5082 - name : Extract Docker metadata (tags, labels)
5183 id : meta
5688 type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}
5789 type=sha
5890
59- - name : Set up Docker Build
91+ - name : Set up Docker Buildx
6092 uses : docker/setup-buildx-action@v3
6193
94+ # --------------------------
95+ # 3) Login to OCIR + Build & Push
96+ # --------------------------
97+ - name : Log in to OCIR
98+ uses : docker/login-action@v3
99+ with :
100+ registry : ${{ steps.sanitize.outputs.ocir_host }}
101+ username : ${{ steps.sanitize.outputs.ocir_user }}
102+ password : ${{ secrets.OCIR_AUTH_TOKEN }}
103+
62104 - name : Build and push
63105 uses : docker/build-push-action@v6
64106 with :
@@ -70,23 +112,35 @@ jobs:
70112 cache-from : type=gha
71113 cache-to : type=gha,mode=max
72114
115+ # --------------------------
116+ # 4) Create .env (multiline safe)
117+ # --------------------------
73118 - name : Create .env file
74- run : echo "${{ secrets.ENV_FILE }}" > .env
119+ shell : bash
120+ run : |
121+ # ENV_FILE이 멀티라인이라면 echo 대신 printf가 안전합니다.
122+ printf "%s" "${{ secrets.ENV_FILE }}" > .env
75123
124+ # --------------------------
125+ # 5) Copy files to OCI Compute
126+ # --------------------------
76127 - name : Copy files to OCI Compute
77128 uses : appleboy/scp-action@master
78129 with :
79- host : ${{ secrets.SSH_HOST }}
130+ host : ${{ steps.sanitize.outputs.ssh_host }}
80131 username : ${{ secrets.SSH_USERNAME }}
81132 key : ${{ secrets.SSH_KEY }}
82133 port : 22
83134 source : " docker/*,.env,nginx/,deploy.sh"
84135 target : " /home/ubuntu/tinybite/"
85136
137+ # --------------------------
138+ # 6) Deploy to OCI Compute
139+ # --------------------------
86140 - name : Deploy to OCI Compute
87141 uses : appleboy/ssh-action@master
88142 with :
89- host : ${{ secrets.SSH_HOST }}
143+ host : ${{ steps.sanitize.outputs.ssh_host }}
90144 username : ${{ secrets.SSH_USERNAME }}
91145 key : ${{ secrets.SSH_KEY }}
92146 port : 22
@@ -95,13 +149,14 @@ jobs:
95149 cd /home/ubuntu/tinybite
96150 mv /home/ubuntu/tinybite/docker/* /home/ubuntu/tinybite/ || true
97151
98- echo "${{ secrets.OCIR_AUTH_TOKEN }}" | docker login "${{ secrets.OCIR_HOST }}" \
99- -u "${{ secrets.OCIR_USERNAME }}" --password-stdin
152+ # OCIR login (use sanitized host/user)
153+ echo "${{ secrets.OCIR_AUTH_TOKEN }}" | docker login "${{ steps.sanitize.outputs.ocir_host }}" \
154+ -u "${{ steps.sanitize.outputs.ocir_user }}" --password-stdin
100155
101- export APP_IMAGE="${{ secrets.OCIR_HOST }}/${{ secrets.OCIR_TENANCY_NAMESPACE }}/${{ secrets.OCIR_REPO }}:latest"
156+ export APP_IMAGE="${{ steps.img.outputs.name }}:latest"
102157
103158 docker compose -f docker-compose.blue.yml pull
104159 docker compose -f docker-compose.blue.yml down || true
105160 docker compose -f docker-compose.blue.yml up -d
106161
107- docker image prune -a - f
162+ docker image prune -f
0 commit comments