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

Autobuild latest gradle versions #277

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
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
24 changes: 11 additions & 13 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ jobs:
build:
name: "build"
runs-on: ubuntu-latest
env:
TEST_GRADLE_VERSION: 6.7
steps:
- uses: actions/checkout@v2
with:
Expand All @@ -24,7 +22,7 @@ jobs:
- name: Pull docker images
run: 'parallel docker pull -- xenit/alfresco-repository-skeleton:6.0 alfresco/alfresco-content-repository-community:6.0.7-ga tomcat:7-jre8 hello-world alpine:edge'
- name: Check
run: ./gradlew check -PintegrationTestGradleVersions=$TEST_GRADLE_VERSION
run: ./gradlew check -PintegrationTestScope=0
- name: Upload reports
if: ${{ failure() }}
uses: actions/upload-artifact@v2
Expand All @@ -36,24 +34,24 @@ jobs:
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
GITHUB_TOKEN: ${{ github.token }}
run: ./gradlew sonarqube -Dsonar.projectKey=xenit-eu_alfresco-docker-gradle-plugin -Dsonar.organization=xenit-eu -Dsonar.host.url=https://sonarcloud.io -PintegrationTestGradleVersions=$TEST_GRADLE_VERSION
run: ./gradlew sonarqube -Dsonar.projectKey=xenit-eu_alfresco-docker-gradle-plugin -Dsonar.organization=xenit-eu -Dsonar.host.url=https://sonarcloud.io -PintegrationTestScope=0
- name: Publish
if: ${{ startsWith(github.ref, 'refs/tags/') }}
env:
GRADLE_PUBLISH_KEY: ${{ secrets.GRADLE_PLUGINS_PUBLISH_KEY }}
GRADLE_PUBLISH_SECRET: ${{ secrets.GRADLE_PLUGINS_PUBLISH_SECRET }}
run: ./gradlew publishPlugins -Pgradle.publish.key=$GRADLE_PUBLISH_KEY -Pgradle.publish.secret=$GRADLE_PUBLISH_SECRET
integration-test:
name: "integration-test (gradle-versions=${{ matrix.gradle-versions}})"
name: "integration-test (slice=${{ matrix.slice }})"
runs-on: ubuntu-latest
strategy:
matrix:
gradle-versions:
- 5.6
- 6.0,6.1,6.2
- 6.3,6.4,6.5
- 6.6,6.7,6.8
- 7.0,7.1,7.2
slice:
- 0
- 1
- 2
- 3
- 4
steps:
- uses: actions/checkout@v2
with:
Expand All @@ -64,10 +62,10 @@ jobs:
- name: Pull docker images
run: 'parallel docker pull -- alfresco/alfresco-content-repository-community:6.0.7-ga tomcat:7-jre8 hello-world alpine:edge'
- name: Check
run: ./gradlew check -PintegrationTestGradleVersions=${{ matrix.gradle-versions }}
run: ./gradlew check -PintegrationTestSlice.index=${{ matrix.slice }} -PintegrationTestSlice.total=5 -PintegrationTestScope=2
- name: Upload reports
if: ${{ failure() }}
uses: actions/upload-artifact@v2
with:
name: reports-integration-test-${{ matrix.gradle-versions }}
name: reports-integration-test-${{ matrix.slice }}
path: build/reports
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ install:
build_script:
- cmd: gradlew assemble
test_script:
- cmd: gradlew check -i -PintegrationTestGradleVersions=6.4
- cmd: gradlew check -i -PintegrationTestScope=0
26 changes: 12 additions & 14 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ dependencies {
testImplementation gradleTestKit()
testImplementation "org.mockito:mockito-core:4.+"
testImplementation 'com.github.stefanbirkner:system-rules:1.19.0'

integrationTestImplementation 'com.fasterxml.jackson.core:jackson-databind:2.10.3'
}


Expand Down Expand Up @@ -166,20 +168,16 @@ import org.gradle.util.GradleVersion

task integrationTest(type: Test, group: "verification") {
useJUnit()
if (project.hasProperty("integrationTestGradleVersions")) {
// This is used for sharding integration tests across different gradle versions
// to avoid a timeout on travis because the total build takes too long.
// See also the .travis.yml file
project.property("integrationTestGradleVersions").tokenize(",").forEach({ version ->
// The versions specified in `integrationTestGradleVersions` are major.minor.
// We only want it to match those, and eventual patches to those versions.
// In particular, we want 4.1 to match 4.1.2, but not 4.10.
// Since there is only one test parameter for every version, either the first
// pattern matches major.minor, or the second pattern matches major.minor.patch
filter.includeTestsMatching("*[Gradle v${version}]")
filter.includeTestsMatching("*[Gradle v${version}.*]")
})
}
/**
* integrationTestScope selects which Gradle versions get tested against
* A scope of 0 only tests the earliest and latest version and gives quick feedback
* A scope of 1 additionally tests the earliest and latest version of every major release
* A scope of 2 additionally tests the latest version of every minor release
* A scope of 3 tests all patch releases"
*/
systemProperty "eu.xenit.gradle.integration.scope", project.findProperty("integrationTestScope") ?: (ci.isCi()?"2":"0")
systemProperty "eu.xenit.gradle.integration.slice.index", project.findProperty("integrationTestSlice.index") ?: "0"
systemProperty "eu.xenit.gradle.integration.slice.total", project.findProperty("integrationTestSlice.total") ?: "1"
doFirst {
if (gradle.startParameter.offline) {
systemProperty "eu.xenit.gradle.integration.useGradleVersion", GradleVersion.current().version
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,30 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import eu.xenit.gradle.testrunner.versions.GradleVersionSeries;
import eu.xenit.gradle.testrunner.versions.GradleVersionSpec;
import eu.xenit.gradle.testrunner.versions.VersionFetcher;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.io.FileUtils;
import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.GradleRunner;
import org.gradle.testkit.runner.TaskOutcome;
import org.gradle.util.GradleVersion;
import org.junit.Rule;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
Expand All @@ -36,28 +44,55 @@ public abstract class AbstractIntegrationTest {
public String gradleVersion;

@Parameters(name = "Gradle v{0}")
public static Collection<Object[]> testData() {
public static List<String[]> testData() {
String forceGradleVersion = System.getProperty("eu.xenit.gradle.integration.useGradleVersion");
if (forceGradleVersion != null) {
return Arrays.asList(new Object[][]{
return Arrays.asList(new String[][]{
{forceGradleVersion},
});
}
return Arrays.asList(new Object[][]{
{"7.2"},
{"7.1"},
{"7.0"},
{"6.8.3"},
{"6.7.1"},
{"6.6.1"},
{"6.5.1"},
{"6.4.1"},
{"6.3"},
{"6.2.2"},
{"6.1.1"},
{"6.0.1"},
{"5.6.4"},
});

int scope = Integer.parseUnsignedInt(System.getProperty("eu.xenit.gradle.integration.scope", "2"));
List<String[]> versionsToBuild = VersionFetcher.fetchVersionSeries()
// Only release versions >= 5.6
.map(series -> series.filter(VersionFetcher::isRelease)
.filter(VersionFetcher.greaterThanOrEqual("5.6")))
.filter(series -> !series.isEmpty())
// Select only the series within a certain scope
.filter(series -> series.getSeriesPriority() <= scope)
// For series with none, or only the major version component, select the first and last version, for series with the minor version component, only select the last version
.flatMap(series -> series.getSeriesPriority() <= 1 ? Stream.of(series.getLowestVersion(), series.getHighestVersion()): Stream.of(
series.getHighestVersion()))
// Collect to a set to deduplicate versions
.collect(Collectors.toSet())
.stream()
// Re-sort by version number
.sorted(GradleVersionSpec.BY_VERSION_NUMBER)
// Convert to parameter for junit
.map(GradleVersionSpec::getVersion)
.map(version -> new String[]{version})
.collect(Collectors.toList());

List<String[]> slicedVersions = slice(versionsToBuild);

System.out.println(slicedVersions.stream()
.map(i -> i[0])
.collect(Collectors.joining(", ", "Running test on versions: ", "")));
return slicedVersions;
}

private static <T> List<T> slice(List<T> items) {
try {
int sliceTotal = Integer.parseUnsignedInt(
System.getProperty("eu.xenit.gradle.integration.slice.total", "1"));
int sliceIndex = Integer.parseUnsignedInt(
System.getProperty("eu.xenit.gradle.integration.slice.index", "0"));
int itemsPerSlice = (int)Math.ceil(items.size()/(float)sliceTotal);
System.out.println("Executing slice "+(sliceIndex+1)+"/"+sliceTotal+ " with "+itemsPerSlice+" items per slice");
return items.subList(itemsPerSlice*sliceIndex, Math.min(itemsPerSlice*(sliceIndex+1), items.size()));
} catch (NumberFormatException e) {
return items;
}
}


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package eu.xenit.gradle.testrunner.versions;

import java.util.Collection;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class GradleVersionSeries {
private final String series;
private final Set<GradleVersionSpec> versionSpecs;

public GradleVersionSeries(String series, Set<GradleVersionSpec> versionSpecs) {
this.series = series;
this.versionSpecs = versionSpecs;
}

public static GradleVersionSeries extract(String series, Collection<GradleVersionSpec> versionSpecs) {
Set<GradleVersionSpec> extractedVersions = versionSpecs.stream()
.filter(spec -> spec.getVersionSeries().contains(series))
.collect(Collectors.toSet());
return new GradleVersionSeries(series, extractedVersions);
}

public int getSeriesPriority() {
if(series.isEmpty()) {
return 0;
}
return series.split("\\.").length;
}

public GradleVersionSpec getLowestVersion() {
return versionSpecs.stream()
.min(GradleVersionSpec.BY_VERSION_NUMBER)
.orElse(null);
}

public GradleVersionSpec getHighestVersion() {
return versionSpecs.stream()
.max(GradleVersionSpec.BY_VERSION_NUMBER)
.orElse(null);
}

public GradleVersionSeries filter(Predicate<GradleVersionSpec> predicate) {
return new GradleVersionSeries(series, versionSpecs.stream().filter(predicate).collect(Collectors.toSet()));
}

public boolean isEmpty() {
return versionSpecs.isEmpty();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package eu.xenit.gradle.testrunner.versions;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import org.gradle.util.GradleVersion;

@JsonIgnoreProperties(ignoreUnknown = true)
public class GradleVersionSpec {
public static final Comparator<GradleVersionSpec> BY_VERSION_NUMBER = Comparator.comparing(versionSpec -> GradleVersion.version(versionSpec.getVersion()));

private String version;
private boolean snapshot;
private boolean broken;
private String rcFor;

public String getVersion() {
return version;
}

public Set<String> getVersionSeries() {
String[] parts = GradleVersion.version(version).getBaseVersion().getVersion().split("\\.");

Set<String> series = new HashSet<>();

for (int i = 0; i < parts.length; i++) {
String serie = "";
for (int j = 0; j <= i; j++) {
serie+=parts[j]+".";
}
series.add(serie.substring(0, Math.max(serie.length()-1, 0)));
}
series.add("");

return Collections.unmodifiableSet(series);
}

public void setVersion(String version) {
this.version = version;
}

public boolean isSnapshot() {
return snapshot;
}

public void setSnapshot(boolean snapshot) {
this.snapshot = snapshot;
}

public boolean isBroken() {
return broken;
}

public void setBroken(boolean broken) {
this.broken = broken;
}

public String getRcFor() {
return rcFor;
}

public void setRcFor(String rcFor) {
this.rcFor = rcFor;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
GradleVersionSpec that = (GradleVersionSpec) o;
return snapshot == that.snapshot && broken == that.broken && version.equals(that.version) && rcFor.equals(
that.rcFor);
}

@Override
public int hashCode() {
return Objects.hash(version, snapshot, broken, rcFor);
}
}
Loading