Merge pull request #31 from JuribaDev/JuribaDev-patch-1 #11
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 }}" |