1+ name : Build and Deploy to GKE
2+
3+ on :
4+ push :
5+ branches :
6+ - main
7+
8+ env :
9+ PROJECT_ID : threadit-api
10+ CLUSTER_NAME : threadit-cluster
11+ ZONE : europe-west1-b
12+ GCS_KEY : gcs-key
13+ SERVICES : db community thread comment vote search popular
14+
15+ jobs :
16+ setup-build-publish-deploy :
17+ name : Setup, Build, Publish, and Deploy
18+ runs-on : ubuntu-latest
19+ environment : production
20+
21+ permissions :
22+ contents : read
23+ id-token : write
24+
25+ steps :
26+ - name : Checkout
27+ uses : actions/checkout@v4
28+
29+ - name : Authenticate to Google Cloud
30+ uses : google-github-actions/auth@v2
31+ with :
32+ credentials_json : ${{ secrets.GCP_SA_KEY }}
33+
34+ - name : Set up Google Cloud SDK
35+ uses : google-github-actions/setup-gcloud@v2
36+ with :
37+ project_id : ${{ env.PROJECT_ID }}
38+
39+ - name : Check if GKE cluster exists
40+ id : check-cluster
41+ run : |
42+ if gcloud container clusters describe $CLUSTER_NAME --zone $ZONE --project $PROJECT_ID; then
43+ echo "exists=true" >> $GITHUB_OUTPUT
44+ else
45+ echo "Cluster does not exist"
46+ echo "exists=false" >> $GITHUB_OUTPUT
47+ fi
48+
49+ - name : Set up GKE credentials
50+ if : steps.check-cluster.outputs.exists == 'true'
51+ uses : google-github-actions/get-gke-credentials@v2
52+ with :
53+ project_id : ${{ env.PROJECT_ID }}
54+ cluster_name : ${{ env.CLUSTER_NAME }}
55+ location : ${{ env.ZONE }}
56+
57+ - name : Cluster not created. Skip deployment
58+ if : steps.check-cluster.outputs.exists == 'false'
59+ run : |
60+ echo "Cluster doesn't exist — skipping deployment."
61+ exit 0
62+
63+ - name : Configure Docker for GCR
64+ run : |
65+ gcloud auth configure-docker --quiet
66+
67+ - name : Build and push images to GCR
68+ working-directory : code/kubernetes
69+ run : |
70+ for SERVICE in $SERVICES; do
71+ docker build -t gcr.io/$PROJECT_ID/${SERVICE}-service:latest -f services/${SERVICE}-service/Dockerfile .
72+ docker push gcr.io/$PROJECT_ID/${SERVICE}-service:latest
73+ done
74+
75+ docker build -t gcr.io/$PROJECT_ID/grpc-gateway:latest -f grpc-gateway/Dockerfile .
76+ docker push gcr.io/$PROJECT_ID/grpc-gateway:latest
77+
78+ - name : Deploy Traefik
79+ working-directory : code/kubernetes
80+ run : |
81+ helm repo add traefik https://traefik.github.io/charts
82+ helm repo update
83+ helm upgrade --install traefik traefik/traefik -n $CLUSTER_NAME -f traefik/values.yaml
84+
85+ kubectl apply -n $CLUSTER_NAME -f traefik/cors.yaml
86+ kubectl apply -n $CLUSTER_NAME -f traefik/strip-prefix.yaml
87+
88+ - name : Create Kubernetes secrets
89+ run : |
90+ BUCKET_SECRET=$(gcloud secrets versions access latest --secret=$GCS_KEY)
91+ MONGO_USER=$(gcloud secrets versions access latest --secret="mongo-user")
92+ MONGO_PASS=$(gcloud secrets versions access latest --secret="mongo-pass")
93+
94+ kubectl create secret generic "bucket-secret" \
95+ --from-literal="$GCS_KEY.json=$BUCKET_SECRET" \
96+ -n $CLUSTER_NAME --dry-run=client -o yaml | kubectl apply -f -
97+
98+ kubectl create secret generic "mongo-secret" \
99+ --from-literal="MONGO_INITDB_ROOT_USERNAME=$MONGO_USER" \
100+ --from-literal="MONGO_INITDB_ROOT_PASSWORD=$MONGO_PASS" \
101+ -n $CLUSTER_NAME --dry-run=client -o yaml | kubectl apply -f -
102+
103+ - name : Deploy configuration and Mongo
104+ working-directory : code/kubernetes
105+ run : |
106+ kubectl apply -n $CLUSTER_NAME -f config.yaml
107+ kubectl apply -n $CLUSTER_NAME -f mongo/
108+
109+ - name : Deploy services
110+ working-directory : code/kubernetes
111+ run : |
112+ for SERVICE in $SERVICES; do
113+ kubectl apply -n $CLUSTER_NAME -f services/${SERVICE}-service/
114+ done
115+
116+ kubectl apply -n $CLUSTER_NAME -f grpc-gateway/
0 commit comments