Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: execute e2e-tests only when needed #1903

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 9 additions & 12 deletions .tekton/pull-request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,12 @@ spec:
value:
- tasks := strings.any_prefix_match(input, ["task/", "hack/", ".tekton/"])
- tasks_pipelines := strings.any_prefix_match(input, ["task/", "pipelines/", "hack/", ".tekton/"])
- |
e2e_tests if {
some file in input
strings.any_prefix_match(file, ["task/", "pipelines/", "hack/", ".tekton/"])
not endswith(file, "/OWNERS")
}
- check_partner_tasks := strings.any_prefix_match(input, ["partners/", "hack/", ".tekton/"])
runAfter:
- build-appstudio-utils
workspaces:
- name: source
workspace: workspace
- name: task-lint-check
when:
- input: "tasks"
Expand Down Expand Up @@ -208,9 +205,9 @@ spec:
- name: source
- name: e2e-tests
when:
- input: "e2e_tests"
- input: "$(tasks.task-switchboard.results.run-e2e)"
operator: "in"
values: ["$(tasks.task-switchboard.results.bindings[*])"]
values: ["execute_e2e"]
params:
- name: e2e_test_namespace
value: $(params.e2e_test_namespace)
Expand Down Expand Up @@ -286,9 +283,9 @@ spec:
finally:
- name: e2e-cleanup
when:
- input: "e2e_tests"
- input: "$(tasks.task-switchboard.results.run-e2e)"
operator: "in"
values: ["$(tasks.task-switchboard.results.bindings[*])"]
values: ["execute_e2e"]
params:
- name: e2e_test_namespace
value: $(params.e2e_test_namespace)
Expand All @@ -306,9 +303,9 @@ spec:
oc delete --ignore-not-found eventlisteners --all -n $(params.e2e_test_namespace)
- name: pull-request-status-message
when:
- input: "tasks_pipelines"
- input: "$(tasks.task-switchboard.results.run-e2e)"
operator: "in"
values: ["$(tasks.task-switchboard.results.bindings[*])"]
values: ["execute_e2e"]
taskRef:
resolver: git
params:
Expand Down
94 changes: 94 additions & 0 deletions .tekton/scripts/determine-if-e2e-execution-needed.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#!/usr/bin/env python3

import os
import sys
import json
import urllib.error
import urllib.request
import subprocess

# Pipelines currently covered by e2e tests
pipelines_covered_by_e2e = ["docker-build", "docker-build-oci-ta", "docker-build-multi-platform-oci-ta", "fbc-builder"]

# Task list which are covered by e2e tests, generated dynamically
tasks_covered_by_e2e = []

# Otherthan tasks and pipelines, related files for which e2e tests needs to be executed
files_covered_by_e2e = [".tekton/pull-request.yaml", ".tekton/tasks/e2e-test.yaml", ".tekton/scripts/determine-if-e2e-execution-needed.py"]

def add_only_unique_task_names(task_list):
for task_name in task_list:
if task_name not in tasks_covered_by_e2e:
tasks_covered_by_e2e.append(task_name)

def get_tasks_covered_by_e2e():
for pipeline_name in pipelines_covered_by_e2e:
pipeline_path = f"pipelines/{pipeline_name}/{pipeline_name}.yaml"
# Get the task names from pipeline spec
result = subprocess.run(["yq", "-e", ".spec.tasks[].taskRef.name", pipeline_path], capture_output=True, text=True)
if result.stderr != "":
sys.stderr.write(f"[ERROR] failed to get tasks inside spec.tasks: {result.stderr}\n")
sys.exit(1)
output = result.stdout
task_names = output.split()
add_only_unique_task_names(task_names)
# Get the task names from pipeline finally
result = subprocess.run([f"yq -e '.spec.finally[].taskRef.name' {pipeline_path}"], shell=True, capture_output=True, text=True)
if result.stderr != "":
sys.stderr.write(f"[ERROR] failed to get tasks inside .spec.finally: {result.stderr}\n")
sys.exit(1)
output = result.stdout
task_names = output.split()
add_only_unique_task_names(task_names)

def get_changed_files_from_pr(pull_number):
updated_files = []
base_url = "https://api.github.com"
repo = "konflux-ci/build-definitions"
url = f"{base_url}/repos/{repo}/pulls/{pull_number}/files"
req = urllib.request.Request(url=url, method="GET")
try:
with urllib.request.urlopen(req) as resp:
if resp.status != 200:
sys.stderr.write(f"[ERROR] Unknown response status code: {resp.status}\n")
sys.exit(1)
response_in_json = json.loads(resp.read())
for object in response_in_json:
updated_files.append(object['filename'])
except urllib.error.HTTPError as e:
sys.stderr.write(f"[ERROR] got error response: {e.read()} with status {e.code}\n")
sys.exit(1)
return updated_files

def does_updated_files_covered_by_e2e(updated_files):
required_to_run_e2e = False
for file_path in updated_files:
if file_path.startswith("task/"):
task_name = file_path.split("/")[1]
if task_name in tasks_covered_by_e2e:
required_to_run_e2e = True
break
elif file_path.startswith("pipelines/"):
pipeline_name = file_path.split("/")[1]
if pipeline_name in pipelines_covered_by_e2e:
required_to_run_e2e = True
break
elif file_path in files_covered_by_e2e:
required_to_run_e2e = True
break
else:
sys.stderr.write("No need to run e2e tests\n")
return required_to_run_e2e

if __name__ == '__main__':
if len(sys.argv) != 2:
sys.stderr.write("[ERROR] provide correct number of arguments\n")
sys.exit(1)
pr_number = sys.argv[1]
get_tasks_covered_by_e2e()
updated_files = get_changed_files_from_pr(pr_number)
required_to_run_e2e = does_updated_files_covered_by_e2e(updated_files)
if required_to_run_e2e:
print("execute_e2e")
else:
print("dont_execute_e2e")
6 changes: 6 additions & 0 deletions .tekton/tasks/task-switchboard.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ spec:
results:
- name: bindings
type: array
- name: run-e2e
type: string
steps:
- name: evaluate
image: $(params.utils_image)
Expand All @@ -32,6 +34,7 @@ spec:
key: "git-provider-token"
args:
- "$(params.expressions[*])"
workingDir: $(workspaces.source.path)/source
script: |
#!/bin/bash
set -o errexit
Expand All @@ -53,3 +56,6 @@ spec:
'data[_]' \
| jq '[.result.[].expressions.[].value | to_entries | .[] | select(.value == true) | .key]' \
| tee "$(results.bindings.path)"

# Output is "execute_e2e" or "dont_execute_e2e" based on files changed in pr
chmeliik marked this conversation as resolved.
Show resolved Hide resolved
.tekton/scripts/determine-if-e2e-execution-needed.py "${pr_number}" | tr -d '\n' | tee "$(results.run-e2e.path)"
Loading