stages: [build, deploy] variables: IMAGE_REPO: "$CI_REGISTRY_IMAGE" TAG: "${CI_COMMIT_REF_SLUG}-${CI_COMMIT_SHORT_SHA}" RELEASE: "open-meteo-service-gitlab" NAMESPACE: "sandbox" CHART_PATH: "./open-meteo-service" VALUES_FILE: "./values.yaml" build: stage: build tags: [homelab] script: - whoami - set -euo pipefail - unset DOCKER_HOST DOCKER_TLS_VERIFY DOCKER_CERT_PATH || true - export DOCKER_HOST=unix:///var/run/docker.sock - docker login "$CI_REGISTRY" -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" - docker build -t "$IMAGE_REPO:$TAG" . - docker push "$IMAGE_REPO:$TAG" - docker tag "$IMAGE_REPO:$TAG" "$IMAGE_REPO:latest" - docker push "$IMAGE_REPO:latest" - echo "Built and pushed $IMAGE_REPO:$TAG and $IMAGE_REPO:latest" deploy: stage: deploy tags: [homelab] rules: - if: '$CI_COMMIT_MESSAGE =~ /^ci: bump image tag/' when: never - when: on_success script: |- set -euo pipefail # Configure kubectl for k3s cluster export KUBECONFIG=/tmp/k3s.yaml echo "Configured kubectl to use k3s cluster" kubectl cluster-info || echo "Warning: Could not connect to cluster yet" # Update values.yaml with the new tag using sed sed -i "s/^ tag: .*/ tag: \"${TAG}\"/" "${VALUES_FILE}" echo "Updated ${VALUES_FILE} with image.tag=${TAG}" # Verify the change grep -A 2 "^image:" "${VALUES_FILE}" # Configure git identity git config user.email "gitlab-ci@dvirlabs.com" git config user.name "GitLab CI" # Commit & push values bump (skip-ci to avoid loop) git add "${VALUES_FILE}" git commit -m "ci: bump image tag to ${TAG} [skip ci]" || echo "No changes to commit" # Push using GITLAB_TOKEN (Project Access Token with api scope) if [ -n "${GITLAB_TOKEN:-}" ]; then git remote set-url origin "https://oauth2:${GITLAB_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git" git push origin "HEAD:${CI_COMMIT_REF_NAME}" && echo "Pushed values.yaml update successfully" || echo "Failed to push, continuing deployment anyway" else echo "GITLAB_TOKEN not set, skipping git push (values.yaml is updated locally for this deployment)" fi # Create namespace if it doesn't exist kubectl create namespace "${NAMESPACE}" --dry-run=client -o yaml | kubectl apply -f - # Create or update GitLab registry secret for pulling images echo "Creating/updating image pull secret..." kubectl create secret docker-registry gitlab-registry \ --docker-server="${CI_REGISTRY}" \ --docker-username="${CI_REGISTRY_USER}" \ --docker-password="${CI_REGISTRY_PASSWORD}" \ --namespace="${NAMESPACE}" \ --dry-run=client -o yaml | kubectl apply -f - echo "Deploying with Helm..." helm upgrade --install "${RELEASE}" "${CHART_PATH}" \ -f "${VALUES_FILE}" \ -n "${NAMESPACE}" \ --create-namespace \ --wait --timeout 10m \ --debug echo "Waiting for deployment to be ready..." kubectl -n "${NAMESPACE}" rollout status deploy -l app.kubernetes.io/name=open-meteo-service --timeout=180s echo "Port-forward for tests..." SERVICE_NAME="${RELEASE}-open-meteo-service" kubectl -n "${NAMESPACE}" port-forward "svc/${SERVICE_NAME}" 8000:8000 >/tmp/pf.log 2>&1 & PF_PID=$! sleep 5 echo "Testing /healthz..." curl -fsS http://localhost:8000/healthz >/dev/null echo "OK /healthz" echo "Testing /coordinates..." COORDS_RESPONSE="$(curl -fsS http://localhost:8000/coordinates)" echo "$COORDS_RESPONSE" | head -20 if ! echo "$COORDS_RESPONSE" | grep -q '"data"'; then echo "ERROR: /coordinates response missing 'data' field" kill $PF_PID || true exit 1 fi echo "OK /coordinates" echo "Testing /metrics..." curl -fsS http://localhost:8000/metrics | head -20 echo "OK /metrics" kill $PF_PID || true echo "All tests passed!"