ci: skip secret-dependent steps on fork PRs and add optional Vertica license gating #775
Workflow file for this run
This file contains hidden or 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: CI and Codecov | |
| on: | |
| push: | |
| branches: | |
| - master | |
| pull_request: | |
| branches: | |
| - master | |
| jobs: | |
| # Determine whether a Vertica license is available. The VerticaDB operator | |
| # requires a non-empty licenseSecret, and secrets are not exposed to fork PRs, | |
| # so the coverage job only runs when VERTICA_LICENSE is present. | |
| license-check: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| run_licensed: ${{ steps.check.outputs.run_licensed }} | |
| steps: | |
| - name: Check Vertica license availability | |
| id: check | |
| env: | |
| VERTICA_LICENSE: ${{ secrets.VERTICA_LICENSE }} | |
| run: | | |
| if [ -z "${VERTICA_LICENSE:-}" ]; then | |
| echo "::notice::VERTICA_LICENSE is unavailable (e.g. fork PR). Skipping the coverage job." | |
| echo "run_licensed=false" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "run_licensed=true" >> "$GITHUB_OUTPUT" | |
| fi | |
| codecov: | |
| name: Codecov Workflow | |
| needs: license-check | |
| if: needs.license-check.outputs.run_licensed == 'true' | |
| runs-on: ubuntu-latest | |
| # Coverage needs a live Vertica brought up via the operator on KinD, which is | |
| # heavy on hosted runners. Marked non-blocking so the coverage signal stays | |
| # visible without failing the pipeline; remove once consistently green. | |
| continue-on-error: true | |
| steps: | |
| - name: Installing graphviz package | |
| run: sudo apt-get update && sudo apt-get install -y graphviz | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Set up Python 3.11 | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| # --------------------------- | |
| # Kubernetes (KinD) + Helm setup | |
| # The standalone opentext/vertica-ce image was removed from Docker Hub, so | |
| # Vertica is brought up via the VerticaDB operator on KinD (CE mode). | |
| # --------------------------- | |
| - name: Set up Kubernetes (KinD) | |
| uses: helm/kind-action@v1.8.0 | |
| with: | |
| cluster_name: vertica-codecov | |
| node_image: kindest/node:v1.29.0 | |
| - name: Set up Helm | |
| uses: azure/setup-helm@v3 | |
| with: | |
| version: "3.11.3" | |
| - name: Add Helm repositories | |
| run: | | |
| helm repo add vertica-charts https://vertica.github.io/charts | |
| helm repo add bitnami https://charts.bitnami.com/bitnami || true | |
| helm repo update | |
| # --------------------------- | |
| # MinIO (communal storage required by the operator) | |
| # --------------------------- | |
| - name: Install MinIO | |
| run: | | |
| kubectl create ns minio | |
| cat <<'EOF' > minio.yaml | |
| apiVersion: apps/v1 | |
| kind: Deployment | |
| metadata: | |
| name: minio | |
| namespace: minio | |
| spec: | |
| replicas: 1 | |
| selector: | |
| matchLabels: | |
| app: minio | |
| template: | |
| metadata: | |
| labels: | |
| app: minio | |
| spec: | |
| containers: | |
| - name: minio | |
| image: minio/minio:latest | |
| args: ["server", "/data"] | |
| env: | |
| - name: MINIO_ROOT_USER | |
| value: "minioadmin" | |
| - name: MINIO_ROOT_PASSWORD | |
| value: "minioadmin" | |
| ports: | |
| - containerPort: 9000 | |
| volumeMounts: | |
| - name: data | |
| mountPath: /data | |
| volumes: | |
| - name: data | |
| emptyDir: {} | |
| --- | |
| apiVersion: v1 | |
| kind: Service | |
| metadata: | |
| name: minio | |
| namespace: minio | |
| spec: | |
| selector: | |
| app: minio | |
| ports: | |
| - port: 9000 | |
| targetPort: 9000 | |
| EOF | |
| kubectl apply -f minio.yaml | |
| kubectl -n minio rollout status deployment/minio --timeout=5m | |
| - name: Ensure MinIO bucket exists | |
| run: | | |
| kubectl run mc-client --rm -i --restart=Never \ | |
| --image=minio/mc:latest \ | |
| -n minio \ | |
| --command -- bash -c " | |
| mc alias set localminio http://minio.minio.svc.cluster.local:9000 minioadmin minioadmin && \ | |
| mc mb --ignore-existing localminio/vertica-fleeting && \ | |
| mc ls localminio | |
| " | |
| - name: Create MinIO Secret | |
| run: | | |
| kubectl create ns my-verticadb-operator | |
| kubectl delete secret communal-creds -n my-verticadb-operator --ignore-not-found | |
| kubectl create secret generic communal-creds \ | |
| -n my-verticadb-operator \ | |
| --from-literal=accesskey="minioadmin" \ | |
| --from-literal=secretkey="minioadmin" | |
| # --------------------------- | |
| # Vertica license (this job only runs when VERTICA_LICENSE is available) | |
| # --------------------------- | |
| - name: Create Vertica license secret | |
| env: | |
| VERTICA_LICENSE: ${{ secrets.VERTICA_LICENSE }} | |
| run: | | |
| set -uo pipefail | |
| if printf '%s' "${VERTICA_LICENSE}" | base64 -d > /tmp/license.dat 2>/dev/null && [ -s /tmp/license.dat ]; then | |
| echo "Decoded VERTICA_LICENSE as base64." | |
| else | |
| printf '%s' "${VERTICA_LICENSE}" > /tmp/license.dat | |
| echo "Using VERTICA_LICENSE as raw license content." | |
| fi | |
| if [ ! -s /tmp/license.dat ]; then | |
| echo "::error::Resulting license file is empty. Check the 'VERTICA_LICENSE' secret value." | |
| rm -f /tmp/license.dat | |
| exit 1 | |
| fi | |
| kubectl delete secret vertica-license -n my-verticadb-operator --ignore-not-found | |
| kubectl create secret generic vertica-license \ | |
| -n my-verticadb-operator \ | |
| --from-file=license.dat=/tmp/license.dat | |
| rm -f /tmp/license.dat | |
| # --------------------------- | |
| # Vertica operator + DB deployment | |
| # --------------------------- | |
| - name: Install Vertica Operator | |
| run: | | |
| cat <<'EOF' > operator-values.yaml | |
| installCRDs: true | |
| controller: | |
| extraEnv: | |
| - name: AWS_REGION | |
| value: "us-east-1" | |
| - name: AWS_DEFAULT_REGION | |
| value: "us-east-1" | |
| EOF | |
| helm upgrade --install vdb-op vertica-charts/verticadb-operator \ | |
| -n my-verticadb-operator -f operator-values.yaml --wait --timeout 10m | |
| kubectl -n my-verticadb-operator get pods -o wide || true | |
| - name: Deploy VerticaDB | |
| run: | | |
| cat > /tmp/verticadb.yaml <<'EOF' | |
| apiVersion: vertica.com/v1 | |
| kind: VerticaDB | |
| metadata: | |
| name: verticadb-sample | |
| namespace: my-verticadb-operator | |
| annotations: | |
| vertica.com/k-safety: "0" | |
| spec: | |
| image: opentext/vertica-k8s:latest | |
| dbName: vdb | |
| initPolicy: Create | |
| licenseSecret: vertica-license | |
| communal: | |
| path: s3://vertica-fleeting/verticapy-codecov/ | |
| credentialSecret: communal-creds | |
| endpoint: http://minio.minio.svc.cluster.local:9000 | |
| region: us-east-1 | |
| local: | |
| dataPath: /data | |
| depotPath: /depot | |
| subclusters: | |
| - name: defaultsubcluster | |
| size: 1 | |
| EOF | |
| echo "--- VerticaDB manifest ---" | |
| cat /tmp/verticadb.yaml | |
| kubectl apply -f /tmp/verticadb.yaml | |
| - name: Wait for Vertica readiness | |
| run: | | |
| NS=my-verticadb-operator | |
| SS=verticadb-sample-defaultsubcluster | |
| POD=${SS}-0 | |
| for i in $(seq 1 60); do | |
| kubectl get pod ${POD} -n ${NS} >/dev/null 2>&1 && break || sleep 10 | |
| done | |
| if ! kubectl wait --for=condition=Ready pod/${POD} -n ${NS} --timeout=15m; then | |
| echo "::error::Vertica pod ${POD} did not become Ready. Dumping diagnostics." | |
| kubectl -n ${NS} get verticadb -o wide || true | |
| kubectl -n ${NS} get pods -o wide || true | |
| kubectl -n ${NS} describe pod ${POD} || true | |
| kubectl -n ${NS} logs ${POD} -c server --tail=200 || true | |
| exit 1 | |
| fi | |
| kubectl -n ${NS} get pods -o wide || true | |
| # --------------------------- | |
| # Coverage (tox with --cov via kubectl port-forward) | |
| # --------------------------- | |
| - name: Install dependencies | |
| run: pip install tox | |
| - name: Run tests with coverage | |
| run: | | |
| set -uo pipefail | |
| NS=my-verticadb-operator | |
| SVC=verticadb-sample-defaultsubcluster | |
| for i in {1..30}; do | |
| addrs=$(kubectl -n ${NS} get endpoints ${SVC} \ | |
| -o jsonpath='{.subsets[*].addresses[*].ip}' 2>/dev/null || true) | |
| [ -n "$addrs" ] && break || sleep 5 | |
| done | |
| kubectl -n ${NS} port-forward svc/${SVC} 5433:5433 > /tmp/pf.log 2>&1 & | |
| PF_PID=$! | |
| trap 'kill ${PF_PID} 2>/dev/null || true' EXIT | |
| for i in {1..30}; do | |
| if (exec 3<>/dev/tcp/127.0.0.1/5433) 2>/dev/null; then | |
| exec 3>&- | |
| echo "Vertica reachable on localhost:5433" | |
| break | |
| fi | |
| sleep 2 | |
| done | |
| export VP_TEST_HOST=localhost | |
| export VP_TEST_PORT=5433 | |
| export VP_TEST_USER=dbadmin | |
| export VP_TEST_PASSWORD="" | |
| export VP_TEST_DATABASE=vdb | |
| tox -e py311 -- --cov=./ --cov-report=xml | |
| - name: Check Codecov token availability | |
| id: codecov-check | |
| env: | |
| CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} | |
| run: | | |
| is_fork="${{ github.event.pull_request.head.repo.fork }}" | |
| if [ "$is_fork" = "true" ] && [ -z "${CODECOV_TOKEN:-}" ]; then | |
| echo "::notice::Fork PR detected — CODECOV_TOKEN secret is unavailable. Skipping coverage upload." | |
| echo "run_codecov=false" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| # For internal PRs and pushes, the token must be present | |
| if [ -z "${CODECOV_TOKEN:-}" ]; then | |
| echo "::error::GitHub secret 'CODECOV_TOKEN' is not set or is empty. Configure it under repo Settings > Secrets and variables > Actions." | |
| exit 1 | |
| fi | |
| echo "run_codecov=true" >> "$GITHUB_OUTPUT" | |
| - name: Upload coverage to Codecov | |
| if: steps.codecov-check.outputs.run_codecov == 'true' | |
| uses: codecov/codecov-action@v3 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| file: ./coverage.xml | |
| flags: unittests | |
| # --------------------------- | |
| # Teardown | |
| # --------------------------- | |
| - name: Cleanup Kubernetes resources | |
| if: always() | |
| run: | | |
| kubectl delete verticadb verticadb-sample -n my-verticadb-operator --ignore-not-found || true | |
| helm uninstall vdb-op -n my-verticadb-operator || true | |
| kubectl delete ns my-verticadb-operator --ignore-not-found || true | |
| kubectl delete -f minio.yaml --ignore-not-found || true | |
| kubectl delete ns minio --ignore-not-found || true | |
| - name: Delete KinD cluster | |
| if: always() | |
| run: | | |
| kind delete cluster --name vertica-codecov || true |