Compatibility E2E Test workflow (dragonflyoss/dragonfly)
The Compatibility E2E Test workflow from dragonflyoss/dragonfly, explained and optimized by Latchkey.
CI health: A - excellent
Run this on Latchkey for self-healing, caching, and up to 58% lower cost.
Grade your own workflow free or run it on Latchkey →What it does
This is the Compatibility E2E Test workflow from the dragonflyoss/dragonfly repository, a real project running GitHub Actions. It is shown here with attribution under its Apache-2.0 license.
Below, Latchkey shows a faster, safer version produced by its optimization engine.
The workflow
name: Compatibility E2E Test
on:
push:
branches: [main, release-*]
paths-ignore: ['**.md', '**.png', '**.jpg', '**.svg', '**/docs/**']
pull_request:
branches: [main, release-*]
paths-ignore: ['**.md', '**.png', '**.jpg', '**.svg', '**/docs/**']
schedule:
- cron: '0 4 * * *'
permissions:
contents: read
env:
KIND_VERSION: v0.32.0
CONTAINERD_VERSION: v1.5.2
KIND_CONFIG_PATH: test/testdata/kind/config.yaml
DRAGONFLY_CHARTS_CONFIG_PATH: test/testdata/charts/config.yaml
DRAGONFLY_CHARTS_PATH: deploy/helm-charts/charts/dragonfly
DRAGONFLY_FILE_SERVER_PATH: test/testdata/k8s/dufs.yaml
jobs:
compatibility_e2e_tests:
runs-on: oracle-vm-24cpu-96gb-x86-64
timeout-minutes: 60
strategy:
matrix:
module: ['manager', 'scheduler', 'client', 'seed-client']
include:
- module: manager
image: manager
image-tag: v2.4.2
chart-name: manager
skip: 'Rate Limit'
- module: scheduler
image: scheduler
image-tag: v2.4.2
chart-name: scheduler
skip: 'Rate Limit'
- module: client
image: client
image-tag: v1.2.15
chart-name: client
skip: 'Rate Limit'
- module: seed-client
image: client
image-tag: v1.2.15
chart-name: seed-client
skip: 'Rate Limit'
steps:
- name: Free Disk Space (Ubuntu)
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be
with:
tool-cache: false
android: true
dotnet: true
haskell: true
large-packages: true
docker-images: true
swap-storage: true
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
with:
submodules: recursive
fetch-depth: 0
- name: Install Go
uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16
with:
go-version-file: go.mod
- name: Get dependencies
run: |
go install github.com/onsi/ginkgo/v2/ginkgo@v2.22.1
mkdir -p /tmp/artifact
- name: Setup buildx
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c
id: buildx
with:
install: true
- name: Cache Docker layers
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Pull Rust Client Image
run: |
cd client
CLIENT_TAG=$(git describe --tags $(git rev-parse HEAD))
docker pull dragonflyoss/client:$CLIENT_TAG
docker tag dragonflyoss/client:$CLIENT_TAG dragonflyoss/client:latest
docker pull dragonflyoss/dfinit:$CLIENT_TAG
docker tag dragonflyoss/dfinit:$CLIENT_TAG dragonflyoss/dfinit:latest
- name: Build Scheduler Image
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf
with:
context: .
file: build/images/scheduler/Dockerfile
push: false
load: true
tags: dragonflyoss/scheduler:latest
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new
- name: Build Manager Image
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf
with:
context: .
file: build/images/manager/Dockerfile
push: false
load: true
tags: dragonflyoss/manager:latest
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new
- name: Setup Kind
uses: helm/kind-action@ef37e7f390d99f746eb8b610417061a60e82a6cc
with:
version: ${{ env.KIND_VERSION }}
config: ${{ env.KIND_CONFIG_PATH }}
cluster_name: kind
- name: Kind load images
run: |
kind load docker-image dragonflyoss/manager:latest
kind load docker-image dragonflyoss/scheduler:latest
kind load docker-image dragonflyoss/client:latest
kind load docker-image dragonflyoss/dfinit:latest
- name: Generate Dragonfly PAT
run: |
DRAGONFLY_PAT=$(uuidgen | tr -d '\n' | base64 | tr '+/' '-_' | tr -d '=')
echo "DRAGONFLY_PAT=$DRAGONFLY_PAT" >> $GITHUB_ENV
- name: Setup Helm
uses: azure/setup-helm@9bc31f4ebc9c6b171d7bfbaa5d006ae7abdb4310 # v5.0.1
- name: Setup dragonfly
run: |
helm install --wait --timeout 15m --dependency-update --create-namespace --namespace dragonfly-system --set ${{ matrix.chart-name }}.image.tag=${{ matrix.image-tag }} --set ${{ matrix.chart-name }}.image.repository=dragonflyoss/${{ matrix.image }} --set manager.extraEnvVars[0].name=DRAGONFLY_PAT --set manager.extraEnvVars[0].value=${{ env.DRAGONFLY_PAT }} -f ${{ env.DRAGONFLY_CHARTS_CONFIG_PATH }} dragonfly ${{ env.DRAGONFLY_CHARTS_PATH }}
mkdir -p /tmp/artifact/dufs && chmod 777 /tmp/artifact/dufs
kubectl apply -f ${{ env.DRAGONFLY_FILE_SERVER_PATH }}
kubectl wait po dufs-0 --namespace dragonfly-e2e --for=condition=ready --timeout=10m
- name: Run E2E test
run: |
ginkgo -v -r --race --fail-fast --cover --trace --show-node-events --skip="${{ matrix.skip }}" test/e2e
cat coverprofile.out >> coverage.txt
- name: Move cache
run: |
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
- name: Upload coverage to Codecov
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage.txt
flags: e2etests
- name: Upload Logs
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
if: always()
with:
name: ${{ matrix.module }}-e2e-tests-logs
path: |
/tmp/artifact/**
The same workflow, on Latchkey
Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.
name: Compatibility E2E Test on: push: branches: [main, release-*] paths-ignore: ['**.md', '**.png', '**.jpg', '**.svg', '**/docs/**'] pull_request: branches: [main, release-*] paths-ignore: ['**.md', '**.png', '**.jpg', '**.svg', '**/docs/**'] schedule: - cron: '0 4 * * *' permissions: contents: read env: KIND_VERSION: v0.32.0 CONTAINERD_VERSION: v1.5.2 KIND_CONFIG_PATH: test/testdata/kind/config.yaml DRAGONFLY_CHARTS_CONFIG_PATH: test/testdata/charts/config.yaml DRAGONFLY_CHARTS_PATH: deploy/helm-charts/charts/dragonfly DRAGONFLY_FILE_SERVER_PATH: test/testdata/k8s/dufs.yaml concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: compatibility_e2e_tests: runs-on: oracle-vm-24cpu-96gb-x86-64 timeout-minutes: 60 strategy: matrix: module: ['manager', 'scheduler', 'client', 'seed-client'] include: - module: manager image: manager image-tag: v2.4.2 chart-name: manager skip: 'Rate Limit' - module: scheduler image: scheduler image-tag: v2.4.2 chart-name: scheduler skip: 'Rate Limit' - module: client image: client image-tag: v1.2.15 chart-name: client skip: 'Rate Limit' - module: seed-client image: client image-tag: v1.2.15 chart-name: seed-client skip: 'Rate Limit' steps: - name: Free Disk Space (Ubuntu) uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be with: tool-cache: false android: true dotnet: true haskell: true large-packages: true docker-images: true swap-storage: true - name: Checkout code uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 with: submodules: recursive fetch-depth: 0 - name: Install Go uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 with: go-version-file: go.mod - name: Get dependencies run: | go install github.com/onsi/ginkgo/v2/ginkgo@v2.22.1 mkdir -p /tmp/artifact - name: Setup buildx uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c id: buildx with: install: true - name: Cache Docker layers uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae with: path: /tmp/.buildx-cache key: ${{ runner.os }}-buildx-${{ github.sha }} restore-keys: | ${{ runner.os }}-buildx- - name: Pull Rust Client Image run: | cd client CLIENT_TAG=$(git describe --tags $(git rev-parse HEAD)) docker pull dragonflyoss/client:$CLIENT_TAG docker tag dragonflyoss/client:$CLIENT_TAG dragonflyoss/client:latest docker pull dragonflyoss/dfinit:$CLIENT_TAG docker tag dragonflyoss/dfinit:$CLIENT_TAG dragonflyoss/dfinit:latest - name: Build Scheduler Image uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf with: context: . file: build/images/scheduler/Dockerfile push: false load: true tags: dragonflyoss/scheduler:latest cache-from: type=local,src=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache-new - name: Build Manager Image uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf with: context: . file: build/images/manager/Dockerfile push: false load: true tags: dragonflyoss/manager:latest cache-from: type=local,src=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache-new - name: Setup Kind uses: helm/kind-action@ef37e7f390d99f746eb8b610417061a60e82a6cc with: version: ${{ env.KIND_VERSION }} config: ${{ env.KIND_CONFIG_PATH }} cluster_name: kind - name: Kind load images run: | kind load docker-image dragonflyoss/manager:latest kind load docker-image dragonflyoss/scheduler:latest kind load docker-image dragonflyoss/client:latest kind load docker-image dragonflyoss/dfinit:latest - name: Generate Dragonfly PAT run: | DRAGONFLY_PAT=$(uuidgen | tr -d '\n' | base64 | tr '+/' '-_' | tr -d '=') echo "DRAGONFLY_PAT=$DRAGONFLY_PAT" >> $GITHUB_ENV - name: Setup Helm uses: azure/setup-helm@9bc31f4ebc9c6b171d7bfbaa5d006ae7abdb4310 # v5.0.1 - name: Setup dragonfly run: | helm install --wait --timeout 15m --dependency-update --create-namespace --namespace dragonfly-system --set ${{ matrix.chart-name }}.image.tag=${{ matrix.image-tag }} --set ${{ matrix.chart-name }}.image.repository=dragonflyoss/${{ matrix.image }} --set manager.extraEnvVars[0].name=DRAGONFLY_PAT --set manager.extraEnvVars[0].value=${{ env.DRAGONFLY_PAT }} -f ${{ env.DRAGONFLY_CHARTS_CONFIG_PATH }} dragonfly ${{ env.DRAGONFLY_CHARTS_PATH }} mkdir -p /tmp/artifact/dufs && chmod 777 /tmp/artifact/dufs kubectl apply -f ${{ env.DRAGONFLY_FILE_SERVER_PATH }} kubectl wait po dufs-0 --namespace dragonfly-e2e --for=condition=ready --timeout=10m - name: Run E2E test run: | ginkgo -v -r --race --fail-fast --cover --trace --show-node-events --skip="${{ matrix.skip }}" test/e2e cat coverprofile.out >> coverage.txt - name: Move cache run: | rm -rf /tmp/.buildx-cache mv /tmp/.buildx-cache-new /tmp/.buildx-cache - name: Upload coverage to Codecov uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f with: token: ${{ secrets.CODECOV_TOKEN }} files: ./coverage.txt flags: e2etests - name: Upload Logs uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a if: always() with: name: ${{ matrix.module }}-e2e-tests-logs path: | /tmp/artifact/**
What changed
- Cancel superseded runs when a branch or PR gets a newer push.
What Latchkey heals here
This workflow has steps that commonly fail on transient issues (network, registries, flaky browsers). On Latchkey managed runners they are detected, retried, and self-healed instead of failing your build:
- Container pulls and builds
- End-to-end and browser tests
This workflow runs 1 job (4 with the matrix expanded) per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.