Skip to content

E2E Tests (CR Cache - Nightly) #40

E2E Tests (CR Cache - Nightly)

E2E Tests (CR Cache - Nightly) #40

# Copyright 2026 The kpt Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
name: "E2E Tests (CR Cache - Nightly)"
on:
schedule:
- cron: "0 3 * * *" # 03:00 UTC daily
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
IMAGE_REPO: porch-kind
KIND_CONTEXT_NAME: porch-test
PORCH_FUNCTION_RUNNER_IMAGE: porch-function-runner
PORCH_WRAPPER_SERVER_IMAGE: porch-wrapper-server
PORCH_SERVER_IMAGE: porch-server
PORCH_CONTROLLERS_IMAGE: porch-controllers
jobs:
build:
name: Build Dev Images
runs-on: ubuntu-latest
timeout-minutes: 15
env:
IMAGE_TAG: ${{ github.sha }}
GOTOOLCHAIN: auto
outputs:
image-tag: ${{ steps.vars.outputs.image-tag }}
steps:
- name: Checkout Porch
uses: actions/checkout@v4
- name: Set up Go
uses: ./.github/actions/setup-go-kpt
with:
install-kpt: "false"
go-cache: "true"
- name: Set variables
id: vars
run: |
echo "image-tag=${IMAGE_TAG:0:8}" >> $GITHUB_OUTPUT
echo "alpine-version=$(make --eval='print: ; @echo $(ALPINE_VERSION)' print)" >> $GITHUB_OUTPUT
echo "golang-bookworm=$(make --eval='print: ; @echo $(GOLANG_BOOKWORM_VERSION)' print)" >> $GITHUB_OUTPUT
echo "golang-alpine=$(make --eval='print: ; @echo $(GOLANG_ALPINE_VERSION)' print)" >> $GITHUB_OUTPUT
- name: Build images in parallel
run: |
set -e
export IMAGE_TAG=${IMAGE_TAG:0:8}
export ALPINE_VERSION=${{ steps.vars.outputs.alpine-version }}
export GOLANG_BOOKWORM_VERSION=${{ steps.vars.outputs.golang-bookworm }}
export GOLANG_ALPINE_VERSION=${{ steps.vars.outputs.golang-alpine }}
IMAGE_NAME=${PORCH_FUNCTION_RUNNER_IMAGE} WRAPPER_SERVER_IMAGE_NAME=${PORCH_WRAPPER_SERVER_IMAGE} make -C func/ build-image &
pid1=$!
IMAGE_NAME=${PORCH_SERVER_IMAGE} make -C build/ build-image &
pid2=$!
IMAGE_NAME=${PORCH_CONTROLLERS_IMAGE} make -C controllers/ build-image &
pid3=$!
wait $pid1 && wait $pid2 && wait $pid3
- name: Save all images
run: |
export IMAGE_TAG=${IMAGE_TAG:0:8}
docker save \
${IMAGE_REPO}/${PORCH_SERVER_IMAGE}:${IMAGE_TAG} \
${IMAGE_REPO}/${PORCH_CONTROLLERS_IMAGE}:${IMAGE_TAG} \
${IMAGE_REPO}/${PORCH_FUNCTION_RUNNER_IMAGE}:${IMAGE_TAG} \
${IMAGE_REPO}/${PORCH_WRAPPER_SERVER_IMAGE}:${IMAGE_TAG} \
| gzip > porch-images.tar.gz
- name: Upload images
uses: actions/upload-artifact@v4
with:
name: porch-images
path: porch-images.tar.gz
compression-level: 0
retention-days: 1
tests:
name: ${{ matrix.name }}
runs-on: ubuntu-latest
timeout-minutes: 30
needs: build
env:
IMAGE_TAG: ${{ needs.build.outputs.image-tag }}
strategy:
fail-fast: false
matrix:
include:
- name: "Porch E2E Tests (CR Cache)"
make_target: "run-in-kind"
test_path: "${GITHUB_WORKSPACE}/test/e2e/api"
test_env: "E2E=1"
log_prefix: "porch-e2e-crcache"
- name: "Porch CLI E2E Tests (CR Cache)"
make_target: "run-in-kind"
test_path: "${GITHUB_WORKSPACE}/test/e2e/cli"
test_env: "E2E=1"
log_prefix: "porch-cli-e2e-crcache"
steps:
- name: Checkout Porch
uses: actions/checkout@v4
- name: Set up Go and kpt
uses: ./.github/actions/setup-go-kpt
with:
go-cache: "true"
- name: Install Kind
uses: helm/kind-action@v1
with:
version: v0.32.0
install_only: true
- name: Set up Git config
run: |
git config --global user.name "Porch E2E"
git config --global user.email "porch-e2e@porch.dev"
- name: Setup dev env
run: ${GITHUB_WORKSPACE}/scripts/setup-dev-env.sh
- name: Download image artifacts
uses: actions/download-artifact@v4
with:
name: porch-images
- name: Load images to kind
run: |
gunzip -c porch-images.tar.gz | docker load
kind load docker-image ${IMAGE_REPO}/${PORCH_SERVER_IMAGE}:${{ needs.build.outputs.image-tag }} -n ${KIND_CONTEXT_NAME}
kind load docker-image ${IMAGE_REPO}/${PORCH_CONTROLLERS_IMAGE}:${{ needs.build.outputs.image-tag }} -n ${KIND_CONTEXT_NAME}
kind load docker-image ${IMAGE_REPO}/${PORCH_FUNCTION_RUNNER_IMAGE}:${{ needs.build.outputs.image-tag }} -n ${KIND_CONTEXT_NAME}
kind load docker-image ${IMAGE_REPO}/${PORCH_WRAPPER_SERVER_IMAGE}:${{ needs.build.outputs.image-tag }} -n ${KIND_CONTEXT_NAME}
- name: Deploy porch kpt pkg
timeout-minutes: 10
run: IMAGE_TAG=${{ needs.build.outputs.image-tag }} SKIP_IMG_BUILD=true make ${{ matrix.make_target }}
- name: Dump cluster state on deploy failure
if: failure()
run: |
echo "=== Node Resources ==="
kubectl top nodes 2>/dev/null || kubectl describe nodes | grep -A 5 "Allocated resources" || true
echo ""
echo "=== Pods (all namespaces) ==="
kubectl get pods -A -o wide || true
echo ""
echo "=== Pod Resource Usage ==="
kubectl top pods -A 2>/dev/null || true
echo ""
echo "=== Services (porch-system) ==="
kubectl get svc -n porch-system 2>/dev/null || true
echo ""
echo "=== PVCs (porch-system) ==="
kubectl get pvc -n porch-system 2>/dev/null || true
echo ""
echo "=== CRDs ==="
kubectl get crds | grep -E "porch|kpt" || true
echo ""
echo "=== APIServices ==="
kubectl get apiservices | grep -E "porch|kpt" || true
echo ""
echo "=== Events (porch-system, last 60) ==="
kubectl get events -n porch-system --sort-by='.lastTimestamp' 2>/dev/null | tail -60 || true
echo ""
echo "=== All pods details (porch-system) ==="
for pod in $(kubectl get pods -n porch-system -o jsonpath='{.items[*].metadata.name}' 2>/dev/null); do
echo ""
echo "--- Pod: porch-system/$pod ---"
kubectl describe pod -n porch-system "$pod" 2>/dev/null | grep -A 30 "Conditions:" || true
echo "--- Logs: porch-system/$pod (last 50 lines, all containers) ---"
kubectl logs -n porch-system "$pod" --all-containers --tail=50 2>/dev/null || true
done
- name: Run E2E tests
run: ${{ matrix.test_env }} go test -v -timeout 20m ${{ matrix.test_path }}
- name: Export porch server logs
if: always()
run: |
kubectl -n porch-system logs -l app=porch-server --all-containers --tail=-1 > ${{ matrix.log_prefix }}-server.log 2>/dev/null || true
- name: Export porch controllers logs
if: always()
run: |
kubectl -n porch-system logs -l k8s-app=porch-controllers --all-containers --tail=-1 > ${{ matrix.log_prefix }}-controllers.log 2>/dev/null || true
- name: Archive logs
if: always()
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.log_prefix }}-logs
path: "*.log"
compression-level: 0
retention-days: 5