Skip to content
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
47 changes: 41 additions & 6 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,36 @@ variables:
# Destination registry for mirrored CI images.
MIRROR_DEST_REGISTRY: "registry.ddbuild.io/system-tests/mirror"

resolve_ssi_pr_title:
image: registry.ddbuild.io/system-tests/ci-runner:9b1520f98ee9
tags: ["arch:amd64"]
stage: configure
id_tokens:
DDOCTOSTS_ID_TOKEN:
aud: dd-octo-sts
rules:
- if: >-
$CI_PROJECT_PATH == "DataDog/system-tests" &&
$CI_PIPELINE_SOURCE == "push" &&
$CI_COMMIT_BRANCH &&
$CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH &&
($SYSTEM_TESTS_SCENARIOS == null || $SYSTEM_TESTS_SCENARIOS == "") &&
($SYSTEM_TESTS_SCENARIOS_GROUPS == null || $SYSTEM_TESTS_SCENARIOS_GROUPS == "")
- when: never
script:
- bash utils/scripts/ci_orchestrators/resolve_gitlab_pr_title.sh
artifacts:
reports:
dotenv: pr-title.env

compute_pipeline:
image: registry.ddbuild.io/ci/libdatadog-build/system-tests:146143169
tags: ["arch:amd64"]
stage: configure
needs:
- job: resolve_ssi_pr_title
artifacts: true
optional: true
variables:
CI_ENVIRONMENT: "prod"
script:
Expand Down Expand Up @@ -86,12 +112,21 @@ compute_pipeline:
SYSTEM_TEST_BUILD_ATTEMPTS=3 SYSTEM_TEST_BUILD_TIMEOUT=240 ./build.sh -i runner
source venv/bin/activate
fi
- python utils/scripts/compute-workflow-parameters.py nodejs -s "$scenarios" -g "$scenarios_groups" --parametric-job-count 1 --ci-environment "${CI_ENVIRONMENT}" --format gitlab
- python utils/scripts/compute-workflow-parameters.py java -s "$scenarios" -g "$scenarios_groups" --parametric-job-count 1 --ci-environment "${CI_ENVIRONMENT}" --format gitlab
- python utils/scripts/compute-workflow-parameters.py dotnet -s "$scenarios" -g "$scenarios_groups" --parametric-job-count 1 --ci-environment "${CI_ENVIRONMENT}" --format gitlab
- python utils/scripts/compute-workflow-parameters.py python -s "$scenarios" -g "$scenarios_groups" --parametric-job-count 1 --ci-environment "${CI_ENVIRONMENT}" --format gitlab
- python utils/scripts/compute-workflow-parameters.py php -s "$scenarios" -g "$scenarios_groups" --parametric-job-count 1 --ci-environment "${CI_ENVIRONMENT}" --format gitlab
- python utils/scripts/compute-workflow-parameters.py ruby -s "$scenarios" -g "$scenarios_groups" --parametric-job-count 1 --ci-environment "${CI_ENVIRONMENT}" --format gitlab
- |
for library in nodejs java dotnet python php ruby; do
selected_scenarios="$scenarios"
selected_scenario_groups="$scenarios_groups"
if [ -n "${ssi_library:-}" ] && [ "$library" != "$ssi_library" ]; then
selected_scenarios=""
selected_scenario_groups=""
fi
python utils/scripts/compute-workflow-parameters.py "$library" \
-s "$selected_scenarios" \
-g "$selected_scenario_groups" \
--parametric-job-count 1 \
--ci-environment "${CI_ENVIRONMENT}" \
--format gitlab
done
- |
if [ -n "$SYSTEM_TESTS_SCENARIOS" ] || [ -n "$SYSTEM_TESTS_SCENARIOS_GROUPS" ]; then
cp *.yml "$CI_PROJECT_DIR"
Expand Down
42 changes: 41 additions & 1 deletion tests/test_the_test/test_compute_libraries_and_scenarios.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from functools import wraps

from utils import pytest
from utils.scripts.compute_libraries_and_scenarios import Inputs, process
from utils.scripts.compute_libraries_and_scenarios import Inputs, get_gitlab_ssi_library, process
from utils import scenarios


Expand Down Expand Up @@ -151,6 +151,19 @@ def test_complete_file_path(self):
"docker_ssi",
)

def test_gitlab_ssi_title_resolver_file_does_not_select_scenarios(self):
inputs = build_inputs(["utils/scripts/ci_orchestrators/resolve_gitlab_pr_title.sh"])

assert_github_processor(
inputs,
[],
[],
3600,
"false",
"DEFAULT",
"",
)

def test_multiple_file_changes(self):
inputs = build_inputs([".github/workflows/run-docker-ssi.yml", "README.md"])

Expand Down Expand Up @@ -510,6 +523,33 @@ def test_gitlab(self):
'scenarios_groups=""',
]

@pytest.mark.parametrize(
("pr_title", "expected"),
[
("", None),
("[nodejs] Test Node.js", "nodejs"),
("[java] Test Java", "java"),
("[dotnet] Test .NET", "dotnet"),
("[PYTHON] Test Python", "python"),
("[php] Test PHP", "php"),
("[ruby] Test Ruby", "ruby"),
("[golang] Test Go", None),
("[java@feature] Test a Java branch", None),
("Test Java [java]", None),
],
)
def test_gitlab_ssi_library_title(self, pr_title: str, expected: str | None):
assert get_gitlab_ssi_library(pr_title) == expected

@set_env("GITLAB_CI", "true")
@set_env("CI_PIPELINE_SOURCE", "pull_request")
@set_env("CI_COMMIT_REF_NAME", "")
@set_env("GITHUB_PR_TITLE", "[java] Test Java")
def test_gitlab_ssi_library_output(self):
inputs = build_inputs(["README.md"])

assert 'ssi_library="java"' in process(inputs)

def test_manifest_no_edit(self):
inputs = build_inputs(
["manifests/java.yml"],
Expand Down
22 changes: 22 additions & 0 deletions tests/test_the_test/test_external_gitlab_pipeline.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
"""Tests for utils/scripts/ci_orchestrators/external_gitlab_pipeline.py."""

from pathlib import Path

import yaml

from utils import pytest

from utils import scenarios
Expand Down Expand Up @@ -45,3 +49,21 @@ def test_filter_yaml_keeps_only_requested_language(self):
assert "python_job" in result
assert "configure_job" in result
assert result["stages"] == ["configure", "python", "pipeline-status"]

def test_external_pipeline_keeps_compute_contract(self) -> None:
data = yaml.safe_load(Path(".gitlab-ci.yml").read_text())
_strip_local_includes(data)

result = filter_yaml(data, "java")

assert result["compute_pipeline"]["image"] == ("registry.ddbuild.io/ci/libdatadog-build/system-tests:146143169")
assert result["compute_pipeline"]["needs"] == [
{"job": "resolve_ssi_pr_title", "artifacts": True, "optional": True}
]

resolver = result["resolve_ssi_pr_title"]
assert resolver["image"] == "registry.ddbuild.io/system-tests/ci-runner:9b1520f98ee9"
assert '$CI_PROJECT_PATH == "DataDog/system-tests"' in resolver["rules"][0]["if"]
assert '$CI_PIPELINE_SOURCE == "push"' in resolver["rules"][0]["if"]
assert "$SYSTEM_TESTS_SCENARIOS == null" in resolver["rules"][0]["if"]
assert "$SYSTEM_TESTS_SCENARIOS_GROUPS == null" in resolver["rules"][0]["if"]
33 changes: 33 additions & 0 deletions utils/scripts/ci_orchestrators/resolve_gitlab_pr_title.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/bin/bash

set -euo pipefail

GITHUB_PR_TITLE=""

if GITHUB_TOKEN=$(dd-octo-sts token \
--scope DataDog/system-tests \
--policy gitlab.github-access.read); then
trap 'dd-octo-sts revoke -t "$GITHUB_TOKEN" >/dev/null 2>&1 || true' EXIT

if PR_DATA=$(curl -fsS --retry 3 --retry-delay 2 --retry-connrefused \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $GITHUB_TOKEN" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/repos/DataDog/system-tests/commits/$CI_COMMIT_SHA/pulls"); then
if ! GITHUB_PR_TITLE=$(jq -r \
'[.[] | select(.state == "open")] | if length == 1 then .[0].title else "" end' <<< "$PR_DATA"); then
echo "⚠️ Unable to parse the GitHub PR title. Running all SSI languages."
GITHUB_PR_TITLE=""
fi
else
echo "⚠️ Unable to read the GitHub PR title. Running all SSI languages."
fi

dd-octo-sts revoke -t "$GITHUB_TOKEN" || true
trap - EXIT
unset GITHUB_TOKEN
else
echo "⚠️ Unable to authenticate to GitHub. Running all SSI languages."
fi

printf 'GITHUB_PR_TITLE=%s\n' "$GITHUB_PR_TITLE" > pr-title.env
20 changes: 16 additions & 4 deletions utils/scripts/compute_libraries_and_scenarios.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ def _get_scenarios_by_definition_file() -> dict[str, set[str]]:
},
}
GITLAB_MAIN = {"python"}
GITLAB_SSI_LIBRARIES = tuple(sorted(COMPONENT_GROUPS.ssi & COMPONENT_GROUPS.lib_injection))


def check_scenarios(scenarios: set[str]) -> bool:
Expand All @@ -76,6 +77,14 @@ def check_libraries(val: set[str]) -> bool:
return all(library in ALL_LIBRARIES for library in val)


def get_gitlab_ssi_library(pr_title: str) -> str | None:
normalized_title = pr_title.lower()
for library in GITLAB_SSI_LIBRARIES:
if normalized_title.startswith(f"[{library}]"):
return library
return None


def _setify(value: list[str] | set[str] | str | None) -> set[str]:
if isinstance(value, set):
return value
Expand Down Expand Up @@ -403,17 +412,16 @@ def __init__(

def load_git_info(self) -> None:
# Get all relevant environment variables.
self.pr_title = os.environ.get("GITHUB_PR_TITLE", "").lower()
if "GITLAB_CI" in os.environ:
source = os.environ.get("CI_PIPELINE_SOURCE", "push")
self.event_name = "pull_request" if source == "merge_request_event" else source
branch = os.environ.get("CI_COMMIT_REF_NAME", "")
self.ref = f"refs/heads/{branch}" if branch else ""
self.pr_title = ""
self.is_gitlab = True
else:
self.event_name = os.environ.get("GITHUB_EVENT_NAME", "pull_request")
self.ref = os.environ.get("GITHUB_REF", "")
self.pr_title = os.environ.get("GITHUB_PR_TITLE", "").lower()

def load_raw_impacts(self) -> None:
# Gets the raw pattern matching data that maps file to impacted
Expand Down Expand Up @@ -459,7 +467,10 @@ def load_scenario_mappings(self) -> None:


def extra_gitlab_output(inputs: Inputs) -> dict[str, str]:
return {"CI_PIPELINE_SOURCE": inputs.event_name, "CI_COMMIT_REF_NAME": inputs.ref}
outputs = {"CI_PIPELINE_SOURCE": inputs.event_name, "CI_COMMIT_REF_NAME": inputs.ref}
if ssi_library := get_gitlab_ssi_library(inputs.pr_title):
outputs["ssi_library"] = ssi_library
return outputs


def stringify_outputs(outputs: dict[str, Any]) -> list[str]:
Expand Down Expand Up @@ -500,7 +511,8 @@ def process(inputs: Inputs) -> list[str]:
scenario_processor.process_manifests(inputs)
scenario_processor.compute_scenarios_by_files(inputs)

library_processor.process_pr_title(inputs)
if not inputs.is_gitlab:
library_processor.process_pr_title(inputs)

assert inputs.modified_files is not None
for file in inputs.modified_files:
Expand Down
3 changes: 3 additions & 0 deletions utils/scripts/libraries_and_scenarios_rules.yml
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,9 @@ patterns:
scenario_groups: null
utils/scripts/check_version.sh:
scenario_groups: null
utils/scripts/ci_orchestrators/resolve_gitlab_pr_title.sh:
scenario_groups: null
libraries: null
utils/scripts/ci_orchestrators/compute-time-stats.py:
scenario_groups: null
libraries: null
Expand Down
Loading