Skip to content

Commit e88e5d0

Browse files
committed
Run CI only for changed modules in pull requests
1 parent 04b123e commit e88e5d0

File tree

4 files changed

+67
-9
lines changed

4 files changed

+67
-9
lines changed

.circleci/collect_results.sh

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,17 @@ shopt -s globstar
1010
TEST_RESULTS_DIR=./results
1111
mkdir -p $TEST_RESULTS_DIR >/dev/null 2>&1
1212

13-
echo "saving test results"
1413
mkdir -p $TEST_RESULTS_DIR
15-
find workspace/**/build/test-results -name \*.xml -exec sh -c '
14+
15+
mkdir -p workspace
16+
mapfile -t test_result_dirs < <(find workspace -name test-results -type d)
17+
18+
if [[ ${#test_result_dirs[@]} -eq 0 ]]; then
19+
echo "No test results found"
20+
exit 0
21+
fi
22+
23+
echo "saving test results"
24+
find "${test_result_dirs[@]}" -name \*.xml -exec sh -c '
1625
file=$(echo "$0" | rev | cut -d "/" -f 1,2,5 | rev | tr "/" "_")
1726
cp "$0" "$1/$file"' {} $TEST_RESULTS_DIR \;

.circleci/config.continue.yml.j2

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,11 @@ commands:
9999
setup_code:
100100
steps:
101101
- checkout
102+
{% if use_git_changes %}
103+
- run:
104+
name: Fetch base branch
105+
command: git fetch origin {{ pr_base_ref }}
106+
{% endif %}
102107
- run:
103108
name: Checkout merge commit
104109
command: .circleci/checkout_merge_commit.sh
@@ -301,6 +306,10 @@ jobs:
301306
GRADLE_OPTS="-Dorg.gradle.jvmargs='-Xmx2G -Xms2G -XX:ErrorFile=/tmp/hs_err_pid%p.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp'"
302307
./gradlew clean
303308
<< parameters.gradleTarget >>
309+
{% if use_git_changes %}
310+
-Paffected_module_detector.enable
311+
-PbaseBranch=origin/{{ pr_base_ref }}
312+
{% endif %}
304313
-PskipTests
305314
<< pipeline.parameters.gradle_flags >>
306315
--max-workers=8
@@ -393,6 +402,10 @@ jobs:
393402
GRADLE_OPTS="-Dorg.gradle.jvmargs='-Xmx2G -Xms2G -XX:ErrorFile=/tmp/hs_err_pid%p.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp'"
394403
./gradlew
395404
<< parameters.gradleTarget >>
405+
{% if use_git_changes %}
406+
-Paffected_module_detector.enable
407+
-PbaseBranch=origin/{{ pr_base_ref }}
408+
{% endif %}
396409
-PskipTests
397410
-PrunBuildSrcTests
398411
-PtaskPartitionCount=${CIRCLE_NODE_TOTAL} -PtaskPartition=${CIRCLE_NODE_INDEX}
@@ -539,6 +552,10 @@ jobs:
539552
./gradlew
540553
<< parameters.gradleTarget >>
541554
<< parameters.gradleParameters >>
555+
{% if use_git_changes %}
556+
-Paffected_module_detector.enable
557+
-PbaseBranch=origin/{{ pr_base_ref }}
558+
{% endif %}
542559
-PtaskPartitionCount=${CIRCLE_NODE_TOTAL} -PtaskPartition=${CIRCLE_NODE_INDEX}
543560
<<# parameters.testJvm >>-PtestJvm=<< parameters.testJvm >><</ parameters.testJvm >>
544561
<< pipeline.parameters.gradle_flags >>

.circleci/render_config.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
}
2929
# Version to use for all the base Docker images, see
3030
# https://github.com/DataDog/dd-trace-java-docker-build/pkgs/container/dd-trace-java-docker-build
31-
DOCKER_IMAGE_VERSION="v24.01"
31+
DOCKER_IMAGE_VERSION = "v24.01"
3232

3333
# Get labels from pull requests to override some defaults for jobs to run.
3434
# `run-tests: all` will run all tests.
@@ -52,7 +52,7 @@
5252
)
5353
resp.raise_for_status()
5454
except Exception as e:
55-
print(f"Request filed: {e}")
55+
print(f"Request failed: {e}")
5656
time.sleep(1)
5757
continue
5858
data = resp.json()
@@ -63,12 +63,16 @@
6363
labels = {
6464
l.replace("run-tests: ", "") for l in labels if l.startswith("run-tests: ")
6565
}
66+
# get the base reference (e.g. `master`), commit hash is also available at the `sha` field.
67+
pr_base_ref = data.get("base", {}).get("ref")
6668
else:
6769
labels = set()
6870

69-
7071
branch = os.environ.get("CIRCLE_BRANCH", "")
71-
if branch == "master" or branch.startswith("release/v") or "all" in labels:
72+
run_all = "all" in labels
73+
is_master_or_release = branch == "master" or branch.startswith("release/v")
74+
75+
if is_master_or_release or run_all:
7276
all_jdks = ALWAYS_ON_JDKS | MASTER_ONLY_JDKS
7377
else:
7478
all_jdks = ALWAYS_ON_JDKS | (MASTER_ONLY_JDKS & labels)
@@ -83,6 +87,9 @@
8387
is_weekly = os.environ.get("CIRCLE_IS_WEEKLY", "false") == "true"
8488
is_regular = not is_nightly and not is_weekly
8589

90+
# Use git changes detection on PRs
91+
use_git_changes = not run_all and not is_master_or_release
92+
8693
vars = {
8794
"is_nightly": is_nightly,
8895
"is_weekly": is_weekly,
@@ -92,12 +99,14 @@
9299
"nocov_jdks": nocov_jdks,
93100
"flaky": branch == "master" or "flaky" in labels or "all" in labels,
94101
"docker_image_prefix": "" if is_nightly else f"{DOCKER_IMAGE_VERSION}-",
102+
"use_git_changes": use_git_changes,
103+
"pr_base_ref": pr_base_ref,
95104
}
96105

97106
print(f"Variables for this build: {vars}")
98107

99108
loader = jinja2.FileSystemLoader(searchpath=SCRIPT_DIR)
100-
env = jinja2.Environment(loader=loader)
109+
env = jinja2.Environment(loader=loader, trim_blocks=True)
101110
tpl = env.get_template(TPL_FILENAME)
102111
out = tpl.render(**vars)
103112

build.gradle

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
buildscript {
22
dependencies {
33
classpath "pl.allegro.tech.build:axion-release-plugin:1.14.4"
4+
classpath "com.dropbox.affectedmoduledetector:affectedmoduledetector:0.2.2"
45
}
56

67
configurations.all {
@@ -24,6 +25,8 @@ plugins {
2425
id "me.champeau.jmh" version "0.7.0" apply false
2526
id 'org.gradle.playframework' version '0.13' apply false
2627
id 'info.solidsoft.pitest' version '1.9.11' apply false
28+
29+
id 'com.dropbox.affectedmoduledetector' version '0.2.2'
2730
}
2831

2932
description = 'dd-trace-java'
@@ -160,15 +163,35 @@ allprojects { project ->
160163
}
161164
}
162165

166+
affectedModuleDetector {
167+
baseDir = "${project.rootDir}"
168+
pathsAffectingAllModules = [".circleci/", "buildSrc/"]
169+
specifiedBranch = project.hasProperty("baseBranch") ? project.property("baseBranch") : "origin/master"
170+
compareFrom = "SpecifiedBranchCommit"
171+
excludedModules = []
172+
includeUncommitted = true
173+
}
174+
175+
subprojects { subproject ->
176+
subproject.tasks.withType(Test) { testTask ->
177+
com.dropbox.affectedmoduledetector.AffectedModuleDetector.configureTaskGuard(testTask)
178+
}
179+
}
163180

164181
def testAggregate(String baseTaskName, includePrefixes, excludePrefixes) {
182+
165183
def createRootTask = { rootTaskName, subProjTaskName ->
166-
tasks.register(rootTaskName) { aggTest ->
184+
tasks.register(rootTaskName) { aggTask ->
167185
subprojects { subproject ->
168186
if (subproject.property("activePartition") && includePrefixes.any { subproject.path.startsWith(it) } && !excludePrefixes.any { subproject.path.startsWith(it) }) {
187+
def affected = com.dropbox.affectedmoduledetector.AffectedModuleDetector.isProjectAffected(subproject)
169188
def testTask = subproject.tasks.findByName(subProjTaskName)
170189
if (testTask != null) {
171-
aggTest.dependsOn(testTask)
190+
if (affected) {
191+
aggTask.dependsOn(testTask)
192+
} else {
193+
logger.info("Skipped based on git changes: ${subproject.path}")
194+
}
172195
}
173196
}
174197
}

0 commit comments

Comments
 (0)