1- name : CI & Docker
1+ name : CI & Docker (GCP Cloud Run)
22
33on :
44 push :
55 branches :
66 - main
77 - lorenc-ci
8+ - lorenc-cicd
89 - paython-mcp
910 - feature/configure-chat-ui
1011 pull_request :
1112 branches :
1213 - main
1314
15+ # Avoid overlapping deploys for the same ref
16+ concurrency :
17+ group : mcp-cicd-${{ github.ref }}
18+ cancel-in-progress : true
19+
20+ # Common env values
21+ env :
22+ NODE_VERSION : 20
23+ REGION : ${{ secrets.GCP_REGION }}
24+ PROJECT_ID : ${{ secrets.GCP_PROJECT_ID }}
25+ AR_HOST : us-east1-docker.pkg.dev
26+
27+ BACKEND_IMAGE_NAME : mcp-backend
28+ FRONTEND_IMAGE_NAME : mcp-frontend
29+
30+ BACKEND_AR_REPO : mcp-backend
31+ FRONTEND_AR_REPO : mcp-frontend
32+
33+ BACKEND_SERVICE : mcp-backend
34+ FRONTEND_SERVICE : mcp-frontend
35+
1436jobs :
1537 build-test :
1638 runs-on : ubuntu-latest
17-
1839 steps :
1940 - name : Checkout repository
2041 uses : actions/checkout@v4
2142
22- - name : Use Node.js 20
43+ - name : Use Node.js
2344 uses : actions/setup-node@v4
2445 with :
25- node-version : 20
46+ node-version : ${{ env.NODE_VERSION }}
2647 cache : npm
2748
2849 - name : Install dependencies
@@ -35,18 +56,13 @@ jobs:
3556 cd server
3657 npm test --if-present
3758
38- # backend image
39- docker-image :
59+ build-backend :
4060 needs : build-test
4161 runs-on : ubuntu-latest
42-
4362 permissions :
4463 contents : read
4564 packages : write
4665
47- env :
48- IMAGE_NAME : mcp-backend
49-
5066 steps :
5167 - name : Checkout repository
5268 uses : actions/checkout@v4
@@ -58,40 +74,36 @@ jobs:
5874 OWNER_LC="$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')"
5975 echo "owner_lc=$OWNER_LC" >> "$GITHUB_OUTPUT"
6076
61- - name : Login to GitHub Container Registry
77+ - name : Login to GHCR
6278 uses : docker/login-action@v3
6379 with :
6480 registry : ghcr.io
6581 username : ${{ github.actor }}
6682 password : ${{ secrets.GITHUB_TOKEN }}
6783
68- - name : Build Docker image
84+ - name : Build backend image
85+ shell : bash
6986 run : |
70- IMAGE_ID ="ghcr.io/${{ steps.vars.outputs.owner_lc }}/${{ env.IMAGE_NAME }}"
87+ BACKEND_GHCR ="ghcr.io/${{ steps.vars.outputs.owner_lc }}/${{ env.BACKEND_IMAGE_NAME }}"
7188 VERSION="${{ github.sha }}"
7289
73- echo "IMAGE_ID=$IMAGE_ID " >> $GITHUB_ENV
74- echo "VERSION=$VERSION" >> $GITHUB_ENV
90+ echo "BACKEND_GHCR=$BACKEND_GHCR " >> " $GITHUB_ENV"
91+ echo "VERSION=$VERSION" >> " $GITHUB_ENV"
7592
76- docker build -t "$IMAGE_ID :$VERSION" -t "$IMAGE_ID :latest" .
93+ docker build -t "$BACKEND_GHCR :$VERSION" -t "$BACKEND_GHCR :latest" .
7794
78- - name : Push Docker image
95+ - name : Push backend image
7996 run : |
80- docker push "$IMAGE_ID :$VERSION"
81- docker push "$IMAGE_ID :latest"
97+ docker push "$BACKEND_GHCR :$VERSION"
98+ docker push "$BACKEND_GHCR :latest"
8299
83- # frontend image
84- frontend-docker-image :
100+ build-frontend :
85101 needs : build-test
86102 runs-on : ubuntu-latest
87-
88103 permissions :
89104 contents : read
90105 packages : write
91106
92- env :
93- IMAGE_NAME : mcp-frontend
94-
95107 steps :
96108 - name : Checkout repository
97109 uses : actions/checkout@v4
@@ -103,31 +115,31 @@ jobs:
103115 OWNER_LC="$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')"
104116 echo "owner_lc=$OWNER_LC" >> "$GITHUB_OUTPUT"
105117
106- - name : Login to GitHub Container Registry
118+ - name : Login to GHCR
107119 uses : docker/login-action@v3
108120 with :
109121 registry : ghcr.io
110122 username : ${{ github.actor }}
111123 password : ${{ secrets.GITHUB_TOKEN }}
112124
113- - name : Build frontend Docker image
125+ - name : Build frontend image
126+ shell : bash
114127 run : |
115- FRONTEND_IMAGE_ID ="ghcr.io/${{ steps.vars.outputs.owner_lc }}/${{ env.IMAGE_NAME }}"
116- FRONTEND_VERSION ="${{ github.sha }}"
128+ FRONTEND_GHCR ="ghcr.io/${{ steps.vars.outputs.owner_lc }}/${{ env.FRONTEND_IMAGE_NAME }}"
129+ VERSION ="${{ github.sha }}"
117130
118- echo "FRONTEND_IMAGE_ID=$FRONTEND_IMAGE_ID " >> $GITHUB_ENV
119- echo "FRONTEND_VERSION=$FRONTEND_VERSION " >> $GITHUB_ENV
131+ echo "FRONTEND_GHCR=$FRONTEND_GHCR " >> " $GITHUB_ENV"
132+ echo "VERSION=$VERSION " >> " $GITHUB_ENV"
120133
121- docker build -f Dockerfile.frontend -t "$FRONTEND_IMAGE_ID:$FRONTEND_VERSION " -t "$FRONTEND_IMAGE_ID :latest" .
134+ docker build -f Dockerfile.frontend -t "$FRONTEND_GHCR:$VERSION " -t "$FRONTEND_GHCR :latest" .
122135
123- - name : Push frontend Docker image
136+ - name : Push frontend image
124137 run : |
125- docker push "$FRONTEND_IMAGE_ID:$FRONTEND_VERSION "
126- docker push "$FRONTEND_IMAGE_ID :latest"
138+ docker push "$FRONTEND_GHCR:$VERSION "
139+ docker push "$FRONTEND_GHCR :latest"
127140
128- # backend cloud deployment
129- deploy-gcp :
130- needs : docker-image
141+ deploy-backend :
142+ needs : build-backend
131143 runs-on : ubuntu-latest
132144 permissions :
133145 contents : read
@@ -144,50 +156,59 @@ jobs:
144156 OWNER_LC="$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')"
145157 echo "owner_lc=$OWNER_LC" >> "$GITHUB_OUTPUT"
146158
159+ # NOTE: Using SA key json for now (works). Upgrade to OIDC/WIF later.
147160 - name : Authenticate to Google Cloud
148161 uses : google-github-actions/auth@v2
149162 with :
150163 credentials_json : ${{ secrets.GCP_SERVICE_ACCOUNT_KEY }}
151164
165+ - name : Debug GCP env
166+ run : |
167+ echo "PROJECT_ID=${{ env.PROJECT_ID }}"
168+ echo "REGION=${{ env.REGION }}"
169+
152170 - name : Set up gcloud
153171 uses : google-github-actions/setup-gcloud@v2
154172 with :
155- project_id : ${{ secrets.GCP_PROJECT_ID }}
173+ project_id : ${{ env.PROJECT_ID }}
156174
157175 - name : Configure Docker for Artifact Registry
158176 run : |
159- gcloud auth configure-docker us-east1-docker.pkg.dev --quiet
177+ gcloud auth configure-docker ${{ env.AR_HOST }} --quiet
160178
161- - name : Pull image from GHCR
179+ - name : Pull backend image from GHCR
180+ shell : bash
162181 run : |
163- IMAGE_ID ="ghcr.io/${{ steps.vars.outputs.owner_lc }}/mcp-backend "
182+ BACKEND_GHCR ="ghcr.io/${{ steps.vars.outputs.owner_lc }}/${{ env.BACKEND_IMAGE_NAME }} "
164183 VERSION="${{ github.sha }}"
165184
166- echo "IMAGE_ID=$IMAGE_ID " >> $GITHUB_ENV
167- echo "VERSION=$VERSION" >> $GITHUB_ENV
185+ echo "BACKEND_GHCR=$BACKEND_GHCR " >> " $GITHUB_ENV"
186+ echo "VERSION=$VERSION" >> " $GITHUB_ENV"
168187
169188 echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin
170- docker pull "$IMAGE_ID :$VERSION"
189+ docker pull "$BACKEND_GHCR :$VERSION"
171190
172- - name : Tag and push image to Artifact Registry
191+ - name : Tag & push backend image to Artifact Registry
192+ shell : bash
173193 run : |
174- AR_IMAGE="us-east1-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/mcp-backend/mcp-backend"
175- docker tag "$IMAGE_ID:$VERSION" "$AR_IMAGE:$VERSION"
176- docker push "$AR_IMAGE:$VERSION"
177- echo "AR_IMAGE=$AR_IMAGE" >> $GITHUB_ENV
194+ BACKEND_AR_IMAGE="${{ env.AR_HOST }}/${{ env.PROJECT_ID }}/${{ env.BACKEND_AR_REPO }}/${{ env.BACKEND_IMAGE_NAME }}"
195+ echo "BACKEND_AR_IMAGE=$BACKEND_AR_IMAGE" >> "$GITHUB_ENV"
196+
197+ docker tag "$BACKEND_GHCR:$VERSION" "$BACKEND_AR_IMAGE:$VERSION"
198+ docker push "$BACKEND_AR_IMAGE:$VERSION"
178199
179- - name : Deploy to Cloud Run
200+ - name : Deploy backend to Cloud Run
180201 run : |
181- gcloud run deploy mcp-backend \
182- --image "$AR_IMAGE:${{ github.sha }} " \
183- --region "${{ secrets.GCP_REGION }}" \
202+ gcloud run deploy "${{ env.BACKEND_SERVICE }}" \
203+ --image "$BACKEND_AR_IMAGE:$VERSION " \
204+ --region "${{ env.REGION }}" \
184205 --platform managed \
185206 --allow-unauthenticated \
186- --port 3000
207+ --port 3000 \
208+ --quiet
187209
188- # frontend cloud deployment
189- deploy-gcp-frontend :
190- needs : frontend-docker-image
210+ deploy-frontend :
211+ needs : build-frontend
191212 runs-on : ubuntu-latest
192213 permissions :
193214 contents : read
@@ -204,43 +225,53 @@ jobs:
204225 OWNER_LC="$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')"
205226 echo "owner_lc=$OWNER_LC" >> "$GITHUB_OUTPUT"
206227
228+ # NOTE: Using SA key json for now (works). Upgrade to OIDC/WIF later.
207229 - name : Authenticate to Google Cloud
208230 uses : google-github-actions/auth@v2
209231 with :
210232 credentials_json : ${{ secrets.GCP_SERVICE_ACCOUNT_KEY }}
211233
234+ - name : Debug GCP env
235+ run : |
236+ echo "PROJECT_ID=${{ env.PROJECT_ID }}"
237+ echo "REGION=${{ env.REGION }}"
238+
212239 - name : Set up gcloud
213240 uses : google-github-actions/setup-gcloud@v2
214241 with :
215- project_id : ${{ secrets.GCP_PROJECT_ID }}
242+ project_id : ${{ env.PROJECT_ID }}
216243
217244 - name : Configure Docker for Artifact Registry
218245 run : |
219- gcloud auth configure-docker us-east1-docker.pkg.dev --quiet
246+ gcloud auth configure-docker ${{ env.AR_HOST }} --quiet
220247
221248 - name : Pull frontend image from GHCR
249+ shell : bash
222250 run : |
223- FRONTEND_IMAGE_ID ="ghcr.io/${{ steps.vars.outputs.owner_lc }}/mcp-frontend "
224- FRONTEND_VERSION ="${{ github.sha }}"
251+ FRONTEND_GHCR ="ghcr.io/${{ steps.vars.outputs.owner_lc }}/${{ env.FRONTEND_IMAGE_NAME }} "
252+ VERSION ="${{ github.sha }}"
225253
226- echo "FRONTEND_IMAGE_ID=$FRONTEND_IMAGE_ID " >> $GITHUB_ENV
227- echo "FRONTEND_VERSION=$FRONTEND_VERSION " >> $GITHUB_ENV
254+ echo "FRONTEND_GHCR=$FRONTEND_GHCR " >> " $GITHUB_ENV"
255+ echo "VERSION=$VERSION " >> " $GITHUB_ENV"
228256
229257 echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin
230- docker pull "$FRONTEND_IMAGE_ID:$FRONTEND_VERSION "
258+ docker pull "$FRONTEND_GHCR:$VERSION "
231259
232260 - name : Tag & push frontend image to Artifact Registry
261+ shell : bash
233262 run : |
234- AR_FRONTEND_IMAGE="us-east1-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/mcp-frontend/mcp-frontend"
235- docker tag "$FRONTEND_IMAGE_ID:$FRONTEND_VERSION" "$AR_FRONTEND_IMAGE:$FRONTEND_VERSION"
236- docker push "$AR_FRONTEND_IMAGE:$FRONTEND_VERSION"
237- echo "AR_FRONTEND_IMAGE=$AR_FRONTEND_IMAGE" >> $GITHUB_ENV
263+ FRONTEND_AR_IMAGE="${{ env.AR_HOST }}/${{ env.PROJECT_ID }}/${{ env.FRONTEND_AR_REPO }}/${{ env.FRONTEND_IMAGE_NAME }}"
264+ echo "FRONTEND_AR_IMAGE=$FRONTEND_AR_IMAGE" >> "$GITHUB_ENV"
265+
266+ docker tag "$FRONTEND_GHCR:$VERSION" "$FRONTEND_AR_IMAGE:$VERSION"
267+ docker push "$FRONTEND_AR_IMAGE:$VERSION"
238268
239269 - name : Deploy frontend to Cloud Run
240270 run : |
241- gcloud run deploy mcp-frontend \
242- --image "$AR_FRONTEND_IMAGE:${{ github.sha }} " \
243- --region "${{ secrets.GCP_REGION }}" \
271+ gcloud run deploy "${{ env.FRONTEND_SERVICE }}" \
272+ --image "$FRONTEND_AR_IMAGE:$VERSION " \
273+ --region "${{ env.REGION }}" \
244274 --platform managed \
245275 --allow-unauthenticated \
246- --port 80
276+ --port 80 \
277+ --quiet
0 commit comments