Skip to content

[879] [EPIC] Container Registry Management with Security Scanning #526

[879] [EPIC] Container Registry Management with Security Scanning

[879] [EPIC] Container Registry Management with Security Scanning #526

name: "Verify Operator Boot"
# Verifies that the operator binary builds and connects to a live kind cluster.
# Acceptance criteria:
# 1. cargo build --release succeeds with zero errors
# 2. ./target/release/stellar-operator run starts against a kind cluster
# 3. Log line "Connected to Kubernetes cluster" appears
#
# Uses shared composite actions for Rust setup and log collection.
on:
push:
branches: [main, "fix/issue-146-*"]
pull_request:
branches: [main]
workflow_dispatch:
concurrency:
group: verify-boot-${{ github.ref }}
cancel-in-progress: true
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
CLUSTER_NAME: stellar-verify
OPERATOR_NAMESPACE: stellar-system
jobs:
verify-operator-boot:
name: Verify Operator Boot & Cluster Connection
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
# ── Scope check: skip on PRs that don't touch operator code ──────────
- name: Decide whether boot verification should run
id: scope
run: |
set -euo pipefail
if [[ "${{ github.event_name }}" != "pull_request" ]]; then
echo "run=true" >> "$GITHUB_OUTPUT"
exit 0
fi
BASE_SHA="${{ github.event.pull_request.base.sha }}"
HEAD_SHA="${{ github.event.pull_request.head.sha }}"
CHANGED=$(git diff --name-only "$BASE_SHA" "$HEAD_SHA" || true)
echo "$CHANGED"
if echo "$CHANGED" | grep -Eq '^(src/|config/crd/|Cargo\.toml|Cargo\.lock|build\.rs|Makefile)'; then
echo "run=true" >> "$GITHUB_OUTPUT"
else
echo "run=false" >> "$GITHUB_OUTPUT"
fi
# ── Build (AC #1) ─────────────────────────────────────────────────────
- name: Setup Rust
if: steps.scope.outputs.run == 'true'
uses: ./.github/actions/setup-rust
with:
cache-key: "verify-boot"
- name: Build release binary
if: steps.scope.outputs.run == 'true'
run: cargo build --release --locked --bin stellar-operator
- name: Confirm binary exists
if: steps.scope.outputs.run == 'true'
run: |
ls -lh target/release/stellar-operator
echo "✅ cargo build --release succeeded"
# ── Create kind cluster (AC #2) ───────────────────────────────────────
- name: Install kind
if: steps.scope.outputs.run == 'true'
uses: helm/kind-action@v1.14.0
with:
install_only: true
- name: Create kind cluster
if: steps.scope.outputs.run == 'true'
run: |
kind create cluster --name ${{ env.CLUSTER_NAME }} --wait 60s
kubectl cluster-info --context kind-${{ env.CLUSTER_NAME }}
echo "✅ kind cluster '${{ env.CLUSTER_NAME }}' is ready"
# ── Install CRD ───────────────────────────────────────────────────────
- name: Install StellarNode CRD
if: steps.scope.outputs.run == 'true'
run: |
kubectl apply -f config/crd/stellarnode-crd.yaml
kubectl wait --for=condition=established --timeout=30s \
crd/stellarnodes.stellar.org || true
# ── Run operator and verify log line (AC #2 + AC #3) ─────────────────
- name: Run operator and verify cluster connection
if: steps.scope.outputs.run == 'true'
run: |
./target/release/stellar-operator run \
--namespace ${{ env.OPERATOR_NAMESPACE }} \
> /tmp/operator.log 2>&1 &
OPERATOR_PID=$!
echo "Operator PID: $OPERATOR_PID"
TIMEOUT=60
ELAPSED=0
FOUND=false
while [[ $ELAPSED -lt $TIMEOUT ]]; do
if grep -q "Connected to Kubernetes cluster" /tmp/operator.log 2>/dev/null; then
FOUND=true
break
fi
sleep 1
ELAPSED=$((ELAPSED + 1))
done
echo "--- Operator log ---"
cat /tmp/operator.log || true
echo "--------------------"
kill "$OPERATOR_PID" 2>/dev/null || true
if [[ "$FOUND" == "true" ]]; then
echo "✅ Log line 'Connected to Kubernetes cluster' confirmed"
else
echo "❌ Log line 'Connected to Kubernetes cluster' NOT found within ${TIMEOUT}s"
exit 1
fi
# ── Runtime error check ───────────────────────────────────────────────
- name: Report runtime errors
if: always() && steps.scope.outputs.run == 'true'
run: |
echo "--- Runtime error check ---"
if grep -iE "error|panic|missing env" /tmp/operator.log 2>/dev/null; then
echo "⚠️ Errors found in operator log (see above)"
else
echo "✅ No runtime errors detected"
fi
# ── Upload log artifact ───────────────────────────────────────────────
- name: Upload operator log
if: always() && steps.scope.outputs.run == 'true'
uses: actions/upload-artifact@v4
with:
name: operator-boot-log-${{ github.run_id }}
path: /tmp/operator.log
retention-days: 7
# ── Cleanup ───────────────────────────────────────────────────────────
- name: Delete kind cluster
if: always() && steps.scope.outputs.run == 'true'
run: kind delete cluster --name ${{ env.CLUSTER_NAME }} || true
- name: Skip message
if: steps.scope.outputs.run != 'true'
run: echo "Skipping verify-operator-boot — no operator/runtime files changed."