浏览代码

Add checkSamples task

Closes gh-9846
Marcus Da Coregio 4 年之前
父节点
当前提交
c562d56ff4

+ 20 - 0
.github/workflows/continuous-integration-workflow.yml

@@ -111,6 +111,26 @@ jobs:
           export GRADLE_ENTERPRISE_CACHE_PASSWORD="$GRADLE_ENTERPRISE_CACHE_PASSWORD"
           export GRADLE_ENTERPRISE_ACCESS_KEY="$GRADLE_ENTERPRISE_SECRET_ACCESS_KEY"
           ./gradlew sonarqube -PartifactoryUsername="$ARTIFACTORY_USERNAME" -PartifactoryPassword="$ARTIFACTORY_PASSWORD" -PexcludeProjects='**/samples/**' -Dsonar.host.url="$SONAR_URL" -Dsonar.login="$SONAR_TOKEN" --stacktrace
+  check_samples:
+    name: Check Samples project
+    needs: [build_jdk_11]
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - name: Set up JDK
+        uses: actions/setup-java@v1
+        with:
+          java-version: '11'
+      - name: Setup gradle user name
+        run: |
+          mkdir -p ~/.gradle
+          echo 'systemProp.user.name=spring-builds' >> ~/.gradle/gradle.properties
+      - name: Check samples project
+        run: |
+          export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER"
+          export GRADLE_ENTERPRISE_CACHE_PASSWORD="$GRADLE_ENTERPRISE_CACHE_PASSWORD"
+          export GRADLE_ENTERPRISE_ACCESS_KEY="$GRADLE_ENTERPRISE_SECRET_ACCESS_KEY"
+          ./gradlew checkSamples --stacktrace
   deploy_artifacts:
     name: Deploy Artifacts
     needs: [build_jdk_11, snapshot_tests, sonar_analysis]

+ 9 - 0
build.gradle

@@ -15,6 +15,7 @@ buildscript {
 apply plugin: 'io.spring.nohttp'
 apply plugin: 'locks'
 apply plugin: 'io.spring.convention.root'
+apply plugin: 'io.spring.convention.include-check-remote'
 apply plugin: 'org.jetbrains.kotlin.jvm'
 apply plugin: 'org.springframework.security.update-dependencies'
 apply plugin: 'org.springframework.security.sagan'
@@ -145,3 +146,11 @@ nohttp {
 	source.exclude "buildSrc/build/**"
 
 }
+
+tasks.register('checkSamples') {
+	includeCheckRemote {
+		repository = 'spring-projects/spring-security-samples'
+		ref = samplesBranch
+	}
+	dependsOn checkRemote
+}

+ 104 - 0
buildSrc/src/main/groovy/io/spring/gradle/IncludeRepoTask.groovy

@@ -0,0 +1,104 @@
+/*
+ * Copyright 2002-2021 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+
+package io.spring.gradle
+
+import groovy.transform.CompileStatic
+import groovy.transform.TypeChecked
+import groovy.transform.TypeCheckingMode
+import org.gradle.api.DefaultTask
+import org.gradle.api.Task
+import org.gradle.api.provider.Property
+import org.gradle.api.tasks.Input
+import org.gradle.api.tasks.OutputDirectory
+import org.gradle.api.tasks.TaskAction
+
+/**
+ * Checkout a project template from a git repository.
+ *
+ * @author Marcus Da Coregio
+ */
+@CompileStatic
+abstract class IncludeRepoTask extends DefaultTask {
+
+	private static final String DEFAULT_URI_PREFIX = 'https://github.com/'
+
+	/**
+	 * Git repository to use. Will be prefixed with {@link #DEFAULT_URI_PREFIX} if it isn't already
+	 * @return
+	 */
+	@Input
+	abstract Property<String> getRepository();
+
+	/**
+	 * Git reference to use.
+	 */
+	@Input
+	abstract Property<String> getRef()
+
+	/**
+	 * Directory where the project template should be copied.
+	 */
+	@OutputDirectory
+	final File outputDirectory = project.file("$project.buildDir/$name")
+
+	@TaskAction
+	void checkoutAndCopy() {
+		outputDirectory.deleteDir()
+		File checkoutDir = checkout(this, getRemoteUri(), ref.get())
+		moveToOutputDir(checkoutDir, outputDirectory)
+	}
+
+	private static File cleanTemporaryDir(Task task, File tmpDir) {
+		if (tmpDir.exists()) {
+			task.project.delete(tmpDir)
+		}
+		return tmpDir
+	}
+
+	static File checkout(Task task, String remoteUri, String ref) {
+		checkout(task, remoteUri, ref, task.getTemporaryDir())
+	}
+
+	@TypeChecked(TypeCheckingMode.SKIP)
+	static File checkout(Task task, String remoteUri, String ref, File checkoutDir) {
+		cleanTemporaryDir(task, checkoutDir)
+		task.project.exec {
+			commandLine = ["git", "clone", "--no-checkout", remoteUri, checkoutDir.absolutePath]
+			errorOutput = System.err
+		}
+		task.project.exec {
+			commandLine = ["git", "checkout", ref]
+			workingDir = checkoutDir
+			errorOutput = System.err
+		}
+		return checkoutDir
+	}
+
+	private static void moveToOutputDir(File tmpDir, File outputDirectory) {
+		File baseDir = tmpDir
+		baseDir.renameTo(outputDirectory)
+	}
+
+	private String getRemoteUri() {
+		String remoteUri = this.repository.get()
+		if (remoteUri.startsWith(DEFAULT_URI_PREFIX)) {
+			return remoteUri
+		}
+		return DEFAULT_URI_PREFIX + remoteUri
+	}
+}

+ 65 - 0
buildSrc/src/main/groovy/io/spring/gradle/convention/IncludeCheckRemotePlugin.groovy

@@ -0,0 +1,65 @@
+/*
+ * Copyright 2002-2021 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package io.spring.gradle.convention
+
+import io.spring.gradle.IncludeRepoTask
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.provider.Property
+import org.gradle.api.tasks.GradleBuild
+import org.gradle.api.tasks.TaskProvider
+
+/**
+ * Adds a set of tasks that make easy to clone a remote repository and perform some task
+ *
+ * @author Marcus Da Coregio
+ */
+class IncludeCheckRemotePlugin implements Plugin<Project> {
+	@Override
+	void apply(Project project) {
+		IncludeCheckRemoteExtension extension = project.extensions.create('includeCheckRemote', IncludeCheckRemoteExtension)
+		TaskProvider<IncludeRepoTask> includeRepoTask = project.tasks.register('includeRepo', IncludeRepoTask) { IncludeRepoTask it ->
+			it.repository = extension.repository.get()
+			it.ref = extension.ref.get()
+		}
+		project.tasks.register('checkRemote', GradleBuild) {
+			it.dependsOn 'includeRepo'
+			it.dir = includeRepoTask.get().outputDirectory
+			it.tasks = extension.getTasks()
+		}
+	}
+
+	abstract static class IncludeCheckRemoteExtension {
+		/**
+		 * Git repository to clone
+		 */
+		abstract Property<String> getRepository();
+		/**
+		 * Git ref to checkout
+		 */
+		abstract Property<String> getRef();
+		/**
+		 * Task to run in the repository
+		 */
+		List<String> tasks = ['check']
+
+		void setTask(List<String> tasks) {
+			this.tasks = tasks
+		}
+	}
+
+}

+ 1 - 0
buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.include-check-remote.properties

@@ -0,0 +1 @@
+implementation-class=io.spring.gradle.convention.IncludeCheckRemotePlugin

+ 100 - 0
buildSrc/src/test/java/io/spring/gradle/convention/IncludeCheckRemotePluginTest.java

@@ -0,0 +1,100 @@
+/*
+ * Copyright 2002-2021 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package io.spring.gradle.convention;
+
+import io.spring.gradle.IncludeRepoTask;
+import org.apache.commons.io.FileUtils;
+import org.gradle.api.Project;
+import org.gradle.api.tasks.GradleBuild;
+import org.gradle.testfixtures.ProjectBuilder;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class IncludeCheckRemotePluginTest {
+
+	Project rootProject;
+
+	@AfterEach
+	public void cleanup() throws Exception {
+		if (rootProject != null) {
+			FileUtils.deleteDirectory(rootProject.getProjectDir());
+		}
+	}
+
+	@Test
+	void applyWhenExtensionPropertiesNoTasksThenCreateCheckRemoteTaskWithDefaultTask() {
+		this.rootProject = ProjectBuilder.builder().build();
+		this.rootProject.getPluginManager().apply(IncludeCheckRemotePlugin.class);
+		this.rootProject.getExtensions().configure(IncludeCheckRemotePlugin.IncludeCheckRemoteExtension.class,
+				(includeCheckRemoteExtension) -> {
+					includeCheckRemoteExtension.setProperty("repository", "my-project/my-repository");
+					includeCheckRemoteExtension.setProperty("ref", "main");
+				});
+
+		GradleBuild checkRemote = (GradleBuild) this.rootProject.getTasks().named("checkRemote").get();
+		assertThat(checkRemote.getTasks()).containsExactly("check");
+	}
+
+	@Test
+	void applyWhenExtensionPropertiesTasksThenCreateCheckRemoteWithProvidedTasks() {
+		this.rootProject = ProjectBuilder.builder().build();
+		this.rootProject.getPluginManager().apply(IncludeCheckRemotePlugin.class);
+		this.rootProject.getExtensions().configure(IncludeCheckRemotePlugin.IncludeCheckRemoteExtension.class,
+				(includeCheckRemoteExtension) -> {
+					includeCheckRemoteExtension.setProperty("repository", "my-project/my-repository");
+					includeCheckRemoteExtension.setProperty("ref", "main");
+					includeCheckRemoteExtension.setProperty("tasks", Arrays.asList("clean", "build", "test"));
+				});
+
+		GradleBuild checkRemote = (GradleBuild) this.rootProject.getTasks().named("checkRemote").get();
+		assertThat(checkRemote.getTasks()).containsExactly("clean", "build", "test");
+	}
+
+	@Test
+	void applyWhenExtensionPropertiesThenRegisterIncludeRepoTaskWithExtensionProperties() {
+		this.rootProject = ProjectBuilder.builder().build();
+		this.rootProject.getPluginManager().apply(IncludeCheckRemotePlugin.class);
+		this.rootProject.getExtensions().configure(IncludeCheckRemotePlugin.IncludeCheckRemoteExtension.class,
+				(includeCheckRemoteExtension) -> {
+					includeCheckRemoteExtension.setProperty("repository", "my-project/my-repository");
+					includeCheckRemoteExtension.setProperty("ref", "main");
+				});
+
+		IncludeRepoTask includeRepo = (IncludeRepoTask) this.rootProject.getTasks().named("includeRepo").get();
+		assertThat(includeRepo).isNotNull();
+		assertThat(includeRepo.getRepository().get()).isEqualTo("my-project/my-repository");
+		assertThat(includeRepo.getRef().get()).isEqualTo("main");
+	}
+
+	@Test
+	void applyWhenRegisterTasksThenCheckRemoteDirSameAsIncludeRepoOutputDir() {
+		this.rootProject = ProjectBuilder.builder().build();
+		this.rootProject.getPluginManager().apply(IncludeCheckRemotePlugin.class);
+		this.rootProject.getExtensions().configure(IncludeCheckRemotePlugin.IncludeCheckRemoteExtension.class,
+				(includeCheckRemoteExtension) -> {
+					includeCheckRemoteExtension.setProperty("repository", "my-project/my-repository");
+					includeCheckRemoteExtension.setProperty("ref", "main");
+				});
+		IncludeRepoTask includeRepo = (IncludeRepoTask) this.rootProject.getTasks().named("includeRepo").get();
+		GradleBuild checkRemote = (GradleBuild) this.rootProject.getTasks().named("checkRemote").get();
+		assertThat(checkRemote.getDir()).isEqualTo(includeRepo.getOutputDirectory());
+	}
+}