Просмотр исходного кода

ref(testing): change the e2e workflow to separate building stage from e2e stage (and free up resources) (#6634)

* refactor(test): isolate destructive actions to CI runners

Signed-off-by: Alexander Chernov <alexander@chernov.it>

* fix(run): update conditional syntax for GITHUB_ACTIONS check

Signed-off-by: Alexander Chernov <alexander@chernov.it>

* refactor(e2e): streamline e2e workflow by introducing reusable jobs and reducing redundancy

Signed-off-by: Alexander Chernov <alexander@chernov.it>

* fix(e2e): specify secrets for e2e reusable workflows to enhance security

Signed-off-by: Alexander Chernov <alexander@chernov.it>

* fix(e2e): hardening

Signed-off-by: Alexander Chernov <alexander@chernov.it>

* fix(e2e): cleaning up

Signed-off-by: Alexander Chernov <alexander@chernov.it>

* fix(e2e): make linter happy

Signed-off-by: Alexander Chernov <alexander@chernov.it>

* fix(e2e): optimize go cache

Signed-off-by: Alexander Chernov <alexander@chernov.it>

* chore(e2e): ignore image-artifacts dir produced by test.build

Signed-off-by: Alexander Chernov <alexander@chernov.it>

---------

Signed-off-by: Alexander Chernov <alexander@chernov.it>
Alexander Chernov 1 день назад
Родитель
Сommit
f2ff5d3964
6 измененных файлов с 320 добавлено и 118 удалено
  1. 0 59
      .github/actions/e2e/action.yml
  2. 256 0
      .github/workflows/e2e-reusable.yml
  3. 46 40
      .github/workflows/e2e.yml
  4. 1 0
      .gitignore
  5. 17 9
      e2e/Makefile
  6. 0 10
      e2e/run.sh

+ 0 - 59
.github/actions/e2e/action.yml

@@ -1,59 +0,0 @@
-name: "e2e"
-description: "runs our e2e test suite"
-
-runs:
-  using: composite
-  steps:
-
-    - name: Configure AWS Credentials
-      uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2
-      with:
-        role-to-assume: ${{ env.AWS_OIDC_ROLE_ARN }}
-        aws-region: ${{ env.AWS_REGION }}
-
-    - name: Setup Go
-      uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
-      with:
-        go-version-file: go.mod
-
-    - name: Find the Go Cache
-      id: go
-      shell: bash
-      run: |
-        echo "build-cache=$(go env GOCACHE)" >> $GITHUB_OUTPUT
-        echo "mod-cache=$(go env GOMODCACHE)" >> $GITHUB_OUTPUT
-
-    - name: Cache the Go Build Cache
-      uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
-      with:
-        path: ${{ steps.go.outputs.build-cache }}
-        key: ${{ runner.os }}-build-unit-tests-${{ github.sha }}-${{ hashFiles('**/go.sum') }}
-        restore-keys: ${{ runner.os }}-build-unit-tests-${{ github.sha }}-
-
-    - name: Cache Go Dependencies
-      uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
-      with:
-        path: ${{ steps.go.outputs.mod-cache }}
-        key: ${{ runner.os }}-pkg-${{ github.sha }}-${{ hashFiles('**/go.sum') }}
-        restore-keys: ${{ runner.os }}-pkg-${{ github.sha }}-
-
-    - name: Setup kind
-      # https://github.com/engineerd/setup-kind/releases/tag/v0.5.0
-      uses: engineerd/setup-kind@aa272fe2a7309878ffc2a81c56cfe3ef108ae7d0 # v0.5.0
-      with:
-        version: ${{ env.KIND_VERSION }}
-        wait: 10m
-        image: ${{ env.KIND_IMAGE }}
-        name: external-secrets
-
-    - name: Setup Docker Buildx
-      # https://github.com/docker/setup-buildx-action/releases/tag/v3.12.0
-      uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
-      with:
-        install: true
-
-    - name: Run e2e Tests
-      shell: bash
-      env:
-        DOCKER_BUILD_ARGS: --load
-      run: make test.e2e

+ 256 - 0
.github/workflows/e2e-reusable.yml

@@ -0,0 +1,256 @@
+# Reusable kind-based e2e pipeline, split into two jobs so the disk-heavy build
+# and the kind test run never share a runner. The build job compiles the
+# controller + e2e images and exports them as tarballs; the test job loads those
+# tarballs into kind and runs the suite, needing no Go toolchain or buildx.
+name: e2e reusable
+
+on:
+  workflow_call:
+    secrets:
+      GCP_SERVICE_ACCOUNT_KEY:
+        required: false
+      GCP_FED_REGION:
+        required: false
+      GCP_GSA_NAME:
+        required: false
+      GCP_KSA_NAME:
+        required: false
+      GCP_FED_PROJECT_ID:
+        required: false
+      AWS_OIDC_ROLE_ARN:
+        required: false
+      AWS_SA_NAME:
+        required: false
+      AWS_SA_NAMESPACE:
+        required: false
+      TFC_AZURE_CLIENT_ID:
+        required: false
+      TFC_AZURE_CLIENT_SECRET:
+        required: false
+      TFC_AZURE_TENANT_ID:
+        required: false
+      TFC_AZURE_SUBSCRIPTION_ID:
+        required: false
+      TFC_VAULT_URL:
+        required: false
+      SCALEWAY_API_URL:
+        required: false
+      SCALEWAY_REGION:
+        required: false
+      SCALEWAY_PROJECT_ID:
+        required: false
+      SCALEWAY_ACCESS_KEY:
+        required: false
+      SCALEWAY_SECRET_KEY:
+        required: false
+      DELINEA_TLD:
+        required: false
+      DELINEA_URL_TEMPLATE:
+        required: false
+      DELINEA_TENANT:
+        required: false
+      DELINEA_CLIENT_ID:
+        required: false
+      DELINEA_CLIENT_SECRET:
+        required: false
+      SECRETSERVER_USERNAME:
+        required: false
+      SECRETSERVER_PASSWORD:
+        required: false
+      SECRETSERVER_URL:
+        required: false
+      GRAFANA_URL:
+        required: false
+      GRAFANA_TOKEN:
+        required: false
+      AKEYLESS_ACCESS_ID:
+        required: false
+      AKEYLESS_ACCESS_TYPE:
+        required: false
+      AKEYLESS_ACCESS_TYPE_PARAM:
+        required: false
+      GITLAB_TOKEN:
+        required: false
+      GITLAB_PROJECT_ID:
+        required: false
+      GITLAB_ENVIRONMENT:
+        required: false
+      ORACLE_USER_OCID:
+        required: false
+      ORACLE_TENANCY_OCID:
+        required: false
+      ORACLE_REGION:
+        required: false
+      ORACLE_FINGERPRINT:
+        required: false
+      ORACLE_KEY:
+        required: false
+
+permissions:
+  contents: read
+
+env:
+  KIND_VERSION: 'v0.30.0'
+  KIND_IMAGE: 'kindest/node:v1.33.4'
+  AWS_REGION: "eu-central-1"
+  TARGET_SHA: ${{ github.event.client_payload.slash_command.args.named.sha }}
+  # Ephemeral tag: images are only ever loaded into kind, never pushed, so a
+  # fixed tag keeps the build and test jobs in sync without passing a version.
+  VERSION: "e2e"
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    permissions:
+      contents: read
+    steps:
+      - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
+        with:
+          egress-policy: audit
+
+      - name: Checkout
+        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
+        with:
+          ref: ${{ env.TARGET_SHA || github.sha }}
+          persist-credentials: false
+
+      - name: Fetch History
+        run: git fetch --prune --unshallow
+
+      - name: Free Disk Space
+        uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1
+        with:
+          tool-cache: true
+          android: true
+          dotnet: true
+          haskell: true
+          large-packages: false
+          docker-images: false
+          swap-storage: false
+
+      - name: Setup Go
+        uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
+        with:
+          go-version-file: go.mod
+
+      - name: Find the Go Cache
+        id: go
+        run: |
+          echo "build-cache=$(go env GOCACHE)" >> "$GITHUB_OUTPUT"
+          echo "mod-cache=$(go env GOMODCACHE)" >> "$GITHUB_OUTPUT"
+
+      - name: Cache the Go Build Cache
+        uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
+        with:
+          path: ${{ steps.go.outputs.build-cache }}
+          key: ${{ runner.os }}-build-unit-tests-${{ github.sha }}-${{ hashFiles('**/go.sum') }}
+          restore-keys: ${{ runner.os }}-build-unit-tests-
+
+      - name: Cache Go Dependencies
+        uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
+        with:
+          path: ${{ steps.go.outputs.mod-cache }}
+          key: ${{ runner.os }}-pkg-${{ github.sha }}-${{ hashFiles('**/go.sum') }}
+          restore-keys: ${{ runner.os }}-pkg-
+
+      - name: Setup Docker Buildx
+        uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
+        with:
+          install: true
+
+      - name: Build images
+        env:
+          DOCKER_BUILD_ARGS: --load
+        run: make -C e2e test.build
+
+      - name: Upload image tarballs
+        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
+        with:
+          name: e2e-images
+          path: e2e/image-artifacts/*.tar
+          retention-days: 1
+
+  test:
+    needs: build
+    runs-on: ubuntu-latest
+    permissions:
+      id-token: write # for oidc auth with aws/gcp/azure
+      contents: read  # for checkout
+    env:
+      # Role ARN (an identifier, not a credential) lives at job level so the AWS
+      # step can be skipped when it is absent, e.g. fork runs without secrets.
+      # The actual provider credentials stay scoped to the Run e2e step below.
+      AWS_OIDC_ROLE_ARN: ${{ secrets.AWS_OIDC_ROLE_ARN }}
+    steps:
+      - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
+        with:
+          egress-policy: audit
+
+      - name: Checkout
+        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
+        with:
+          ref: ${{ env.TARGET_SHA || github.sha }}
+          persist-credentials: false
+
+      - name: Configure AWS Credentials
+        if: env.AWS_OIDC_ROLE_ARN != ''
+        uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2
+        with:
+          role-to-assume: ${{ env.AWS_OIDC_ROLE_ARN }}
+          aws-region: ${{ env.AWS_REGION }}
+
+      - name: Setup kind
+        uses: engineerd/setup-kind@aa272fe2a7309878ffc2a81c56cfe3ef108ae7d0 # v0.5.0
+        with:
+          version: ${{ env.KIND_VERSION }}
+          wait: 10m
+          image: ${{ env.KIND_IMAGE }}
+          name: external-secrets
+
+      - name: Download image tarballs
+        uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
+        with:
+          name: e2e-images
+          path: e2e/image-artifacts
+
+      - name: Run e2e
+        env:
+          GCP_SERVICE_ACCOUNT_KEY: ${{ secrets.GCP_SERVICE_ACCOUNT_KEY }}
+          GCP_FED_REGION: ${{ secrets.GCP_FED_REGION }}
+          GCP_GSA_NAME: ${{ secrets.GCP_GSA_NAME }}
+          GCP_KSA_NAME: ${{ secrets.GCP_KSA_NAME }}
+          GCP_FED_PROJECT_ID: ${{ secrets.GCP_FED_PROJECT_ID }}
+          AWS_SA_NAME: ${{ secrets.AWS_SA_NAME }}
+          AWS_SA_NAMESPACE: ${{ secrets.AWS_SA_NAMESPACE }}
+          TFC_AZURE_CLIENT_ID: ${{ secrets.TFC_AZURE_CLIENT_ID }}
+          TFC_AZURE_CLIENT_SECRET: ${{ secrets.TFC_AZURE_CLIENT_SECRET }}
+          TFC_AZURE_TENANT_ID: ${{ secrets.TFC_AZURE_TENANT_ID }}
+          TFC_AZURE_SUBSCRIPTION_ID: ${{ secrets.TFC_AZURE_SUBSCRIPTION_ID }}
+          TFC_VAULT_URL: ${{ secrets.TFC_VAULT_URL }}
+          SCALEWAY_API_URL: ${{ secrets.SCALEWAY_API_URL }}
+          SCALEWAY_REGION: ${{ secrets.SCALEWAY_REGION }}
+          SCALEWAY_PROJECT_ID: ${{ secrets.SCALEWAY_PROJECT_ID }}
+          SCALEWAY_ACCESS_KEY: ${{ secrets.SCALEWAY_ACCESS_KEY }}
+          SCALEWAY_SECRET_KEY: ${{ secrets.SCALEWAY_SECRET_KEY }}
+          DELINEA_TLD: ${{ secrets.DELINEA_TLD }}
+          DELINEA_URL_TEMPLATE: ${{ secrets.DELINEA_URL_TEMPLATE }}
+          DELINEA_TENANT: ${{ secrets.DELINEA_TENANT }}
+          DELINEA_CLIENT_ID: ${{ secrets.DELINEA_CLIENT_ID }}
+          DELINEA_CLIENT_SECRET: ${{ secrets.DELINEA_CLIENT_SECRET }}
+          SECRETSERVER_USERNAME: ${{ secrets.SECRETSERVER_USERNAME }}
+          SECRETSERVER_PASSWORD: ${{ secrets.SECRETSERVER_PASSWORD }}
+          SECRETSERVER_URL: ${{ secrets.SECRETSERVER_URL }}
+          GRAFANA_URL: ${{ secrets.GRAFANA_URL }}
+          GRAFANA_TOKEN: ${{ secrets.GRAFANA_TOKEN }}
+          AKEYLESS_ACCESS_ID: ${{ secrets.AKEYLESS_ACCESS_ID }}
+          AKEYLESS_ACCESS_TYPE: ${{ secrets.AKEYLESS_ACCESS_TYPE }}
+          AKEYLESS_ACCESS_TYPE_PARAM: ${{ secrets.AKEYLESS_ACCESS_TYPE_PARAM }}
+          GITLAB_TOKEN: ${{ secrets.GITLAB_TOKEN }}
+          GITLAB_PROJECT_ID: ${{ secrets.GITLAB_PROJECT_ID }}
+          GITLAB_ENVIRONMENT: ${{ secrets.GITLAB_ENVIRONMENT }}
+          ORACLE_USER_OCID: ${{ secrets.ORACLE_USER_OCID }}
+          ORACLE_TENANCY_OCID: ${{ secrets.ORACLE_TENANCY_OCID }}
+          ORACLE_REGION: ${{ secrets.ORACLE_REGION }}
+          ORACLE_FINGERPRINT: ${{ secrets.ORACLE_FINGERPRINT }}
+          ORACLE_KEY: ${{ secrets.ORACLE_KEY }}
+        run: make -C e2e test.run

+ 46 - 40
.github/workflows/e2e.yml

@@ -15,15 +15,17 @@ env:
   TARGET_SHA: ${{ github.event.client_payload.slash_command.args.named.sha }}
   GHCR_USERNAME: ${{ github.actor }}
   AWS_REGION: "eu-central-1"
+
 jobs:
 
+  # Same-repo pull request: build and test run as two jobs on separate runners.
   integration-trusted:
-    runs-on: ubuntu-latest
     permissions:
-      id-token: write #for oidc auth with aws/gcp/azure
-      contents: read  #for checkout
+      id-token: write # for oidc auth with aws/gcp/azure
+      contents: read  # for checkout
     if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && github.actor !='dependabot[bot]'
-    env:
+    uses: ./.github/workflows/e2e-reusable.yml
+    secrets:
       GCP_SERVICE_ACCOUNT_KEY: ${{ secrets.GCP_SERVICE_ACCOUNT_KEY }}
       GCP_FED_REGION: ${{ secrets.GCP_FED_REGION }}
       GCP_GSA_NAME: ${{ secrets.GCP_GSA_NAME }}
@@ -52,30 +54,26 @@ jobs:
       SECRETSERVER_URL: ${{ secrets.SECRETSERVER_URL }}
       GRAFANA_URL: ${{ secrets.GRAFANA_URL }}
       GRAFANA_TOKEN: ${{ secrets.GRAFANA_TOKEN }}
-    steps:
-    - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
-      with:
-        egress-policy: audit
-
-    - name: Branch based PR checkout
-      uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
-      with:
-        persist-credentials: false
-
-    - name: Fetch History
-      run: git fetch --prune --unshallow
-
-    - uses: ./.github/actions/e2e
+      AKEYLESS_ACCESS_ID: ${{ secrets.AKEYLESS_ACCESS_ID }}
+      AKEYLESS_ACCESS_TYPE: ${{ secrets.AKEYLESS_ACCESS_TYPE }}
+      AKEYLESS_ACCESS_TYPE_PARAM: ${{ secrets.AKEYLESS_ACCESS_TYPE_PARAM }}
+      GITLAB_TOKEN: ${{ secrets.GITLAB_TOKEN }}
+      GITLAB_PROJECT_ID: ${{ secrets.GITLAB_PROJECT_ID }}
+      GITLAB_ENVIRONMENT: ${{ secrets.GITLAB_ENVIRONMENT }}
+      ORACLE_USER_OCID: ${{ secrets.ORACLE_USER_OCID }}
+      ORACLE_TENANCY_OCID: ${{ secrets.ORACLE_TENANCY_OCID }}
+      ORACLE_REGION: ${{ secrets.ORACLE_REGION }}
+      ORACLE_FINGERPRINT: ${{ secrets.ORACLE_FINGERPRINT }}
+      ORACLE_KEY: ${{ secrets.ORACLE_KEY }}
 
-  # Repo owner has commented /ok-to-test on a (fork-based) pull request
+  # Repo owner has commented /ok-to-test on a (fork-based) pull request.
   integration-fork:
-    runs-on: ubuntu-latest
     permissions:
-      id-token: write      #for oidc auth with aws/gcp/azure
-      contents: read       #for checkout
-      pull-requests: write # to publish the status as comments
+      id-token: write # for oidc auth with aws/gcp/azure
+      contents: read  # for checkout
     if: github.event_name == 'repository_dispatch'
-    env:
+    uses: ./.github/workflows/e2e-reusable.yml
+    secrets:
       GCP_SERVICE_ACCOUNT_KEY: ${{ secrets.GCP_SERVICE_ACCOUNT_KEY }}
       GCP_FED_REGION: ${{ secrets.GCP_FED_REGION }}
       GCP_GSA_NAME: ${{ secrets.GCP_GSA_NAME }}
@@ -104,25 +102,32 @@ jobs:
       SECRETSERVER_URL: ${{ secrets.SECRETSERVER_URL }}
       GRAFANA_URL: ${{ secrets.GRAFANA_URL }}
       GRAFANA_TOKEN: ${{ secrets.GRAFANA_TOKEN }}
+      AKEYLESS_ACCESS_ID: ${{ secrets.AKEYLESS_ACCESS_ID }}
+      AKEYLESS_ACCESS_TYPE: ${{ secrets.AKEYLESS_ACCESS_TYPE }}
+      AKEYLESS_ACCESS_TYPE_PARAM: ${{ secrets.AKEYLESS_ACCESS_TYPE_PARAM }}
+      GITLAB_TOKEN: ${{ secrets.GITLAB_TOKEN }}
+      GITLAB_PROJECT_ID: ${{ secrets.GITLAB_PROJECT_ID }}
+      GITLAB_ENVIRONMENT: ${{ secrets.GITLAB_ENVIRONMENT }}
+      ORACLE_USER_OCID: ${{ secrets.ORACLE_USER_OCID }}
+      ORACLE_TENANCY_OCID: ${{ secrets.ORACLE_TENANCY_OCID }}
+      ORACLE_REGION: ${{ secrets.ORACLE_REGION }}
+      ORACLE_FINGERPRINT: ${{ secrets.ORACLE_FINGERPRINT }}
+      ORACLE_KEY: ${{ secrets.ORACLE_KEY }}
+
+  # Report the fork run result back onto the originating pull request.
+  report-fork:
+    if: github.event_name == 'repository_dispatch' && always()
+    needs: integration-fork
+    runs-on: ubuntu-latest
+    permissions:
+      pull-requests: write # to publish the status as comments
+      contents: read
     steps:
     - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
       with:
         egress-policy: audit
 
-    # Check out merge commit
-    - name: Fork based /ok-to-test checkout
-      uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
-      with:
-        ref: '${{ env.TARGET_SHA }}'
-        persist-credentials: false
-
-    - name: Fetch History
-      run: git fetch --prune --unshallow
-
-    - id: e2e
-      uses: ./.github/actions/e2e
     - id: create_token
-      if: always()
       uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
       env:
         APP_ID: ${{ secrets.APP_ID }}
@@ -131,16 +136,17 @@ jobs:
         private-key: ${{ secrets.PRIVATE_KEY }}
         owner: ${{ github.repository_owner }}
 
-    - name: Update on Succeess
-      if: always() && steps.e2e.conclusion == 'success'
+    - name: Update on Success
+      if: needs.integration-fork.result == 'success'
       uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5.0.0
       with:
         token: ${{ steps.create_token.outputs.token }}
         issue-number: ${{ github.event.client_payload.pull_request.number }}
         body: |
             [Bot] - :white_check_mark: [e2e for ${{ env.TARGET_SHA }} passed](https://github.com/external-secrets/external-secrets/actions/runs/${{ github.run_id }})
+
     - name: Update on Failure
-      if: always() &&  steps.e2e.conclusion != 'success'
+      if: needs.integration-fork.result != 'success'
       uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5.0.0
       with:
         token: ${{ steps.create_token.outputs.token }}

+ 1 - 0
.gitignore

@@ -26,6 +26,7 @@ deploy/charts/external-secrets/templates/crds/*.yaml
 
 site/
 e2e/k8s/deploy
+e2e/image-artifacts/
 e2e/suites/argocd/argocd.test
 e2e/suites/flux/flux.test
 e2e/suites/provider/provider.test

+ 17 - 9
e2e/Makefile

@@ -11,6 +11,11 @@ export TEST_SUITES ?= provider generator flux argocd
 
 export OCI_IMAGE_NAME = ghcr.io/external-secrets/external-secrets
 
+# Directory where test.build writes the docker-saved image tarballs and where
+# test.run loads them from. Lets CI hand images between a build job and a
+# separate test job as artifacts instead of rebuilding on the test runner.
+E2E_ARTIFACT_DIR ?= $(shell pwd)/image-artifacts
+
 start-kind: ## Start kind cluster
 	kind create cluster \
 	  --name external-secrets \
@@ -22,20 +27,23 @@ stop-kind: ## Stop kind cluster
 	kind delete cluster \
 		--name external-secrets \
 
-test: e2e-image ## Run e2e tests against current kube context
-	$(MAKE) -C ../ docker.build \
-		IMAGE_NAME=$(IMAGE_NAME) \
-		VERSION=$(VERSION) \
-		ARCH=amd64 \
-		DOCKER_BUILD_ARGS="${DOCKER_BUILD_ARGS} --build-arg TARGETARCH=amd64 --build-arg TARGETOS=linux"
+test: ## Build images and run the e2e suite on the current runner (local convenience)
+	$(MAKE) test.build
+	$(MAKE) test.run
+
+test.build: e2e-image ## Build the e2e + controller images and export them as tarballs
 	$(MAKE) -C ../ docker.build \
 		IMAGE_NAME=$(OCI_IMAGE_NAME) \
 		VERSION=$(VERSION) \
 		ARCH=amd64 \
 		DOCKER_BUILD_ARGS="${DOCKER_BUILD_ARGS} --build-arg TARGETARCH=amd64 --build-arg TARGETOS=linux"
-	kind load docker-image --name="external-secrets" $(IMAGE_NAME):$(VERSION)
-	kind load docker-image --name="external-secrets" $(OCI_IMAGE_NAME):$(VERSION)
-	kind load docker-image --name="external-secrets" $(E2E_IMAGE_NAME):$(VERSION)
+	mkdir -p $(E2E_ARTIFACT_DIR)
+	docker save -o $(E2E_ARTIFACT_DIR)/eso.tar $(OCI_IMAGE_NAME):$(VERSION)
+	docker save -o $(E2E_ARTIFACT_DIR)/e2e.tar $(E2E_IMAGE_NAME):$(VERSION)
+
+test.run: ## Load prebuilt image tarballs into kind and run the e2e suite
+	kind load image-archive --name="external-secrets" $(E2E_ARTIFACT_DIR)/eso.tar
+	kind load image-archive --name="external-secrets" $(E2E_ARTIFACT_DIR)/e2e.tar
 	./run.sh
 
 test.managed: e2e-image ## Run e2e tests against current kube context

+ 0 - 10
e2e/run.sh

@@ -15,11 +15,6 @@
 # limitations under the License.
 set -euo pipefail
 
-if ! command -v kind --version &> /dev/null; then
-  echo "kind is not installed. Use the package manager or visit the official site https://kind.sigs.k8s.io/"
-  exit 1
-fi
-
 DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
 cd $DIR
 
@@ -39,11 +34,6 @@ kubectl create clusterrolebinding service-account-issuer-discovery-binding \
   --clusterrole=system:service-account-issuer-discovery \
   --group=system:unauthenticated || true
 
-echo -e "Cleaning cache before running tests"
-docker system prune --force
-go clean -cache
-go clean -modcache
-
 echo -e "Starting the e2e test pod ${E2E_IMAGE_NAME}:${VERSION}"
 kubectl run --rm \
   --attach \