Skip to content
Latchkey

Compatibility E2E Test workflow (dragonflyoss/dragonfly)

The Compatibility E2E Test workflow from dragonflyoss/dragonfly, explained and optimized by Latchkey.

A

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 →
Source: dragonflyoss/dragonfly.github/workflows/compatibility-e2e.ymlLicense Apache-2.0View source

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

workflow (.yml)
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

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:

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.

Actions used in this workflow