Skip to content

Merge pull request #31 from JuribaDev/JuribaDev-patch-1 #11

Merge pull request #31 from JuribaDev/JuribaDev-patch-1

Merge pull request #31 from JuribaDev/JuribaDev-patch-1 #11

Workflow file for this run

name: Build and Deploy Docker Images
on:
push:
branches:
- main
- dev
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: 'read'
id-token: 'write'
env:
LOCATION: me-central1
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Authenticate to Google Cloud
uses: google-github-actions/auth@v2
with:
credentials_json: '${{ secrets.GCP_CREDENTIALS }}'
- name: Set up Google Cloud SDK
uses: google-github-actions/setup-gcloud@v2
with:
project_id: ${{ secrets.GCP_PROJECT_ID }}
- name: Configure Docker for Artifact Registry
run: |
gcloud auth configure-docker ${LOCATION}-docker.pkg.dev
- name: Build and push Docker image for client
run: |
docker build \
--build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') \
--build-arg GITHUB_SHA=${{ github.sha }} \
--build-arg GITHUB_REF_NAME=${{ github.ref_name }} \
-f apps/client/Dockerfile \
-t ${LOCATION}-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/${{ secrets.REPO_NAME }}/client:${{ github.sha }} \
-t ${LOCATION}-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/${{ secrets.REPO_NAME }}/client:${{ github.ref_name }} \
.
docker push ${LOCATION}-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/${{ secrets.REPO_NAME }}/client:${{ github.sha }}
docker push ${LOCATION}-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/${{ secrets.REPO_NAME }}/client:${{ github.ref_name }}
- name: Build and push Docker image for server
run: |
docker build \
--build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') \
--build-arg GITHUB_SHA=${{ github.sha }} \
--build-arg GITHUB_REF_NAME=${{ github.ref_name }} \
-f apps/server/Dockerfile \
-t ${LOCATION}-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/${{ secrets.REPO_NAME }}/server:${{ github.sha }} \
-t ${LOCATION}-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/${{ secrets.REPO_NAME }}/server:${{ github.ref_name }} \
.
docker push ${LOCATION}-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/${{ secrets.REPO_NAME }}/server:${{ github.sha }}
docker push ${LOCATION}-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/${{ secrets.REPO_NAME }}/server:${{ github.ref_name }}
- name: Install kubectl
run: gcloud components install kubectl
- name: Deploy to GKE
run: |
gcloud container clusters get-credentials ${{ secrets.GKE_CLUSTER }} --zone ${LOCATION} --project ${{ secrets.GCP_PROJECT_ID }}
# Create Namespace if Not Exists
if ! kubectl get namespace ${{ secrets.ENVIRONMENT_NAMESPACE }} &> /dev/null; then
echo "Namespace does not exist. Creating it."
kubectl create namespace ${{ secrets.ENVIRONMENT_NAMESPACE }}
else
echo "Namespace already exists."
fi
# Update Kubernetes manifests with secrets and environment variables
sed -i 's|ENVIRONMENT_NAMESPACE|'${{ secrets.ENVIRONMENT_NAMESPACE }}'|g' k8s/*.yaml
sed -i 's|MONGODB_URI_SECRET|'${{ secrets.MONGODB_URI_SECRET }}'|g' k8s/*.yaml
sed -i 's|JWT_KEY_SECRET|'${{ secrets.JWT_KEY_SECRET }}'|g' k8s/*.yaml
sed -i 's|JWT_EXPIRATION|'${{ secrets.JWT_EXPIRATION }}'|g' k8s/*.yaml
sed -i 's|LOCATION|'${LOCATION}'|g' k8s/*.yaml
sed -i 's|PROJECT_ID|'${{ secrets.GCP_PROJECT_ID }}'|g' k8s/*.yaml
sed -i 's|REPO_NAME|'${{ secrets.REPO_NAME }}'|g' k8s/*.yaml
sed -i 's|TAG|'${{ github.sha }}'|g' k8s/*.yaml
sed -i 's|STATIC_IP_PLACEHOLDER|'${{ secrets.STATIC_IP }}'|g' k8s/*.yaml
# Apply Kubernetes manifests
kubectl apply -f k8s/
- name: Setup TLS and Wait for Deployments
run: |
# Install cert-manager if not already installed
if ! kubectl get namespace cert-manager &> /dev/null; then
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.12.0/cert-manager.yaml
echo "Waiting for cert-manager to be ready..."
kubectl wait --for=condition=ready pod -l app.kubernetes.io/instance=cert-manager -n cert-manager --timeout=300s
else
echo "cert-manager is already installed."
fi
# Create ClusterIssuer if it doesn't exist
if ! kubectl get clusterissuer letsencrypt-prod &> /dev/null; then
cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: ${{ secrets.LETSENCRYPT_EMAIL }}
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
EOF
echo "ClusterIssuer created."
else
echo "ClusterIssuer already exists."
fi
# Wait for deployments to be ready
echo "Waiting for server deployment to be ready..."
kubectl rollout status deployment/server-deployment --timeout=300s
echo "Waiting for client deployment to be ready..."
kubectl rollout status deployment/client-deployment --timeout=300s
- name: Wait for TLS Certificate
run: |
echo "Waiting for TLS certificate to be issued..."
max_attempts=20
attempt=0
while [ $attempt -lt $max_attempts ]; do
status=$(kubectl get certificate rnd-platform-tls -o jsonpath="{.status.conditions[?(@.type=='Ready')].status}" 2>/dev/null)
if [ "$status" = "True" ]; then
echo "TLS certificate issued successfully!"
break
elif [ "$status" = "False" ]; then
reason=$(kubectl get certificate rnd-platform-tls -o jsonpath="{.status.conditions[?(@.type=='Ready')].reason}")
echo "Certificate is not ready. Reason: $reason"
else
echo "Certificate status unknown. It may still be processing."
fi
attempt=$((attempt+1))
if [ $attempt -eq $max_attempts ]; then
echo "Maximum attempts reached. Certificate may not be ready."
exit 1
fi
echo "Waiting before next check..."
sleep 30
done
- name: Output Access URL
run: |
echo "Application is accessible at https://${{ secrets.STATIC_IP }}"