Verified Commit 1df2f5e6 authored by Lukas Wiest's avatar Lukas Wiest 🚂
Browse files

refactor: remove all old stuff, no longer used

BREAKING CHANGE: removed lots of code, templates, etc
parent ad257a19
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="LogToConsole" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="modocotbackend" level="debug" additivity="false">
<AppenderRef ref="LogToConsole"/>
</Logger>
<Root level="debug">
<AppenderRef ref="LogToConsole"/>
</Root>
</Loggers>
</Configuration>
\ No newline at end of file
package de.hftstuttgart.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ModocotProperties {
private final String dockerHostIp;
private final String jenkinsApiToken;
private final String jenkinsBaseUrl;
private final String modocotParentDirectory;
private final String modocotAssignmentFolderPrefix;
private final String modocotTestFolderName;
private final String gitTeaBasePath;
private final String gitTeaUsername;
private final String gitTeaPassword;
private final String gitTeaDefaultCommitMessage;
private final String gitTeaOrigin;
public ModocotProperties(@Value("${docker.hostIp}") String dockerHostIp,
@Value("${jenkins.api.token}") String jenkinsApiToken,
@Value("${jenkins.url}") String jenkinsBaseUrl,
@Value("${modocot.dir.parent}") String modocotParentDirectory,
@Value("${modocot.dir.assignment.prefix}") String modocotAssignmentFolderPrefix,
@Value("${modocot.dir.test.folder.name}") String modocotTestFolderName,
@Value("${gitTea.basePath}") String gitTeaBasePath,
@Value("${gitTea.username}") String gitTeaUsername,
@Value("${gitTea.password}") String gitTeaPassword,
@Value("${gitTea.defaultCommitMessage}") String gitTeaDefaultCommitMessage,
@Value("${gitTea.defaultOrigin}") String gitTeaOrigin) {
this.dockerHostIp = dockerHostIp;
this.jenkinsApiToken = jenkinsApiToken;
this.jenkinsBaseUrl = jenkinsBaseUrl;
this.modocotParentDirectory = modocotParentDirectory;
this.modocotAssignmentFolderPrefix = modocotAssignmentFolderPrefix;
this.modocotTestFolderName = modocotTestFolderName;
this.gitTeaBasePath = gitTeaBasePath;
this.gitTeaUsername = gitTeaUsername;
this.gitTeaPassword = gitTeaPassword;
this.gitTeaDefaultCommitMessage = gitTeaDefaultCommitMessage;
this.gitTeaOrigin = gitTeaOrigin;
}
public String getDockerHostIp() {
return dockerHostIp;
}
public String getJenkinsApiToken() {
return jenkinsApiToken;
}
public String getJenkinsBaseUrl() {
return jenkinsBaseUrl;
}
public String getModocotParentDirectory() {
return modocotParentDirectory;
}
public String getModocotAssignmentFolderPrefix() {
return modocotAssignmentFolderPrefix;
}
public String getModocotTestFolderName() {
return modocotTestFolderName;
}
public String getGitTeaBasePath() {
return gitTeaBasePath;
}
public String getGitTeaUsername() {
return gitTeaUsername;
}
public String getGitTeaPassword() {
return gitTeaPassword;
}
public String getGitTeaDefaultCommitMessage() {
return gitTeaDefaultCommitMessage;
}
public String getGitTeaOrigin() {
return gitTeaOrigin;
}
}
package de.hftstuttgart.exceptions;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
/**
* Created by Marcel Bochtler on 28.11.16.
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
public class CorruptedZipFileException extends RuntimeException {
public CorruptedZipFileException(String s) {
super(s);
}
}
package de.hftstuttgart.exceptions;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
/**
* Created by Marcel Bochtler on 29.11.16.
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
public class NoZipFileException extends RuntimeException {
public NoZipFileException(String message) {
super(message);
}
}
package de.hftstuttgart.models;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import de.hftstuttgart.utils.BuildState;
import java.util.List;
@JsonInclude
public class JenkinsJobData {
public JenkinsJobData() {
}
public String getClassData() {
return classData;
}
public List<Job> getJobs() {
return jobs;
}
@JsonProperty("_class")
private String classData;
private List<Job> jobs;
@JsonProperty("jobs")
public void unpackingJobs(List<Job> jobs) {
this.jobs = jobs;
}
public static class Job {
@JsonProperty("_class")
private String jobClassData;
@JsonProperty("name")
private String name;
@JsonProperty("color")
private BuildState color;
public String getJobClassData() {
return jobClassData;
}
public void setJobClassData(String jobClassData) {
this.jobClassData = jobClassData;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public BuildState getColor() {
return color;
}
public void setColor(BuildState color) {
this.color = color;
}
}
}
package de.hftstuttgart.models;
import org.junit.runner.notification.Failure;
import java.util.List;
public class TestResult {
private String testName;
private int testCount;
private int failureCount;
private List<String> successfulTests;
private List<Failure> testFailures;
public String getTestName() {
return testName;
}
public void setTestName(String testName) {
this.testName = testName;
}
public int getTestCount() {
return testCount;
}
public void setTestCount(int testCount) {
this.testCount = testCount;
}
public int getFailureCount() {
return failureCount;
}
public void setFailureCount(int failureCount) {
this.failureCount = failureCount;
}
public List<String> getSuccessfulTests() {
return successfulTests;
}
public void setSuccessfulTests(List<String> successfulTests) {
this.successfulTests = successfulTests;
}
public List<Failure> getTestFailures() {
return testFailures;
}
public void setTestFailures(List<Failure> testFailures) {
this.testFailures = testFailures;
}
@Override
public String toString() {
return "TestResult{" +
"testName='" + testName + '\'' +
", testCount=" + testCount +
", failureCount=" + failureCount +
", testFailures=" + testFailures +
'}';
}
}
package de.hftstuttgart.models;
import javax.tools.Diagnostic;
import java.util.List;
public class UserResult {
private List<TestResult> testResults;
private List<Diagnostic> compilationErrors;
public UserResult(List<TestResult> testResults) {
this.testResults = testResults;
}
public List<TestResult> getTestResults() {
return testResults;
}
public void setTestResults(List<TestResult> testResults) {
this.testResults = testResults;
}
public List<Diagnostic> getCompilationErrors() {
return compilationErrors;
}
public void setCompilationErrors(List<Diagnostic> compilationErrors) {
this.compilationErrors = compilationErrors;
}
}
package de.hftstuttgart.rest.v1.jenkins;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
public class RestAPIController {
private static final Logger LOG = LogManager.getLogger(RestAPIController.class);
public static final Map<String, String> JOB_MAP = new HashMap<>();
@PostMapping("/v1/uploaduserresults")
public void uploadsResults(@RequestParam("jobID") String jobId, @RequestBody String userResult) {
LOG.info("result: " + userResult);
if (!JOB_MAP.containsKey(jobId)) {
String keys = String.join(", ", JOB_MAP.keySet());
throw new IllegalArgumentException(
String.format("Key %s does not exist in JOB_MAP, available Keys: [%s]", jobId, keys));
}
JOB_MAP.put(jobId, userResult);
}
}
\ No newline at end of file
package de.hftstuttgart.utils;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.stream.Collectors;
public class BackendUtil {
/**
* Loop through all {@link File}s in {@code filesFromZipFile} and find {@link File} {@code fileNameToSearchFor}. <br>
* And return a {@link List} of Strings for each line in file {@code fileNameToSearchFor}
*
* @param filesFromZipFile all files which get extracted from previous zipFile
* @param fileNameToSearchFor search for specific name
* @return {@link List} of Strings for each line in file {@code fileNameToSearchFor}
*/
public static List<String> extractLinesFromRepoFile(List<File> filesFromZipFile, String fileNameToSearchFor) {
if(filesFromZipFile.size() < 1 && fileNameToSearchFor != null) {
throw new IllegalArgumentException();
}
List<String> lines = null;
for (File file : filesFromZipFile) {
if (file.getName().equalsIgnoreCase(fileNameToSearchFor)) {
try {
FileInputStream fis = new FileInputStream(file);
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
lines = br.lines().collect(Collectors.toList());
br.close();
if (file.exists())
file.delete();
} catch (IOException ignored) { }
}
}
return lines;
}
}
package de.hftstuttgart.utils;
import com.fasterxml.jackson.annotation.JsonProperty;
public enum BuildState {
@JsonProperty("blue") BLUE,
@JsonProperty("notbuilt") NOTBUILT,
@JsonProperty("notbuilt_anime") NOTBUILT_ANMIE,
@JsonProperty("red") RED,
@JsonProperty("yellow") YELLOW,
@JsonProperty("grey") GREY,
@JsonProperty("disabled") DISABLED,
@JsonProperty("aborted") ABORTED,
@JsonProperty("aborted_anime") ABORTED_ANIME,
@JsonProperty("grey_anime") GREY_ANIME
}
package de.hftstuttgart.utils;
import de.hftstuttgart.config.ModocotProperties;
import io.gitea.ApiClient;
import io.gitea.ApiException;
import io.gitea.Configuration;
import io.gitea.api.RepositoryApi;
import io.gitea.api.UserApi;
import io.gitea.auth.HttpBasicAuth;
import io.gitea.model.CreateRepoOption;
import io.gitea.model.Repository;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Component;
@Component
public class GitTeaUtil {
private static final Logger LOG = LogManager.getLogger(GitTeaUtil.class);
private final ModocotProperties modocotProperties;
public GitTeaUtil(ModocotProperties modocotProperties) {
this.modocotProperties = modocotProperties;
}
/**
* Create Git-Repository with name {@code repositoryName} on internal Git-Server
*
* @param repositoryName name of new Repository
* @return newly created Repository
*/
public Repository createRepository(String repositoryName) {
setupAuth();
Repository repo = null;
try {
repo = new UserApi()
.createCurrentUserRepo(new CreateRepoOption().name(repositoryName));
} catch (ApiException e) {
LOG.error(String.format("Error while creating repository: %s", repositoryName), e);
}
if (repo != null) {
LOG.info("Created repository {} on {}", repositoryName, repo.getCloneUrl());
} else {
throw new IllegalStateException("Repository is null");
}
return repo;
}
/**
* Delete Git-Repository with name {@code repositoryName} on internal Git-Server
*
* @param repositoryName name of new Repository
*/
public void deleteRepository(String repositoryName) {
setupAuth();
try {
new RepositoryApi().repoDelete(this.modocotProperties.getGitTeaUsername(), repositoryName);
} catch (ApiException e) {
LOG.error("Error while deleting repository:" + e.getMessage());
}
}
/**
* Check if a Git-Repository with the given name exists.
*
* @param repositoryName name of the Repository
*/
public boolean repositoryExists(String repositoryName) {
setupAuth();
Repository repository = null;
try {
repository = new RepositoryApi().repoGet(this.modocotProperties.getGitTeaUsername(), repositoryName);
} catch (ApiException e) {
LOG.error("Error while deleting repository:" + e.getMessage());
}
return repository != null;
}
private void setupAuth() {
ApiClient defaultClient = Configuration.getDefaultApiClient();
defaultClient.setBasePath(this.modocotProperties.getGitTeaBasePath());
HttpBasicAuth basicAuth = (HttpBasicAuth) defaultClient.getAuthentication("BasicAuth");
basicAuth.setUsername(this.modocotProperties.getGitTeaUsername());
basicAuth.setPassword(this.modocotProperties.getGitTeaPassword());
}
}
package de.hftstuttgart.utils;
import de.hftstuttgart.config.ModocotProperties;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
@Component
public class RestCall {
private static final Logger LOG = LogManager.getLogger(RestCall.class);
private final ModocotProperties modocotProperties;
public RestCall(ModocotProperties modocotProperties) {
this.modocotProperties = modocotProperties;
}
public <T> ResponseEntity<T> exchange(String specificUrl, HttpMethod method, T body, Class<T> responseType, Object... uriVariables) {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_XML);
headers.add("Authorization", "Basic " + new String(Base64.encodeBase64((this.modocotProperties.getJenkinsApiToken()).getBytes())));
headers.add("user", "admin");
LOG.info(method.toString() + ", to: " + this.modocotProperties.getJenkinsBaseUrl() + specificUrl);
return restTemplate.exchange(this.modocotProperties.getJenkinsBaseUrl() + specificUrl, method, new HttpEntity<>(body, headers), responseType, uriVariables);
}
}
package de.hftstuttgart.utils;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.hftstuttgart.config.ModocotProperties;
import de.hftstuttgart.models.JenkinsJobData;
import de.hftstuttgart.rest.v1.jenkins.RestAPIController;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.Version;
import io.gitea.model.Repository;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
@Component
public class TaskUploadUtils {
private static final Logger LOG = LogManager.getLogger(TaskUploadUtils.class);
private final GitTeaUtil gitTeaUtil;
private final ModocotProperties modocotProperties;
private final JGitUtil jGitUtil;
private final RestCall restCall;
public TaskUploadUtils(GitTeaUtil gitTeaUtil,
ModocotProperties modocotProperties,
JGitUtil jGitUtil,
RestCall restCall) {
this.gitTeaUtil = gitTeaUtil;
this.modocotProperties = modocotProperties;
this.jGitUtil = jGitUtil;
this.restCall = restCall;
}
/**
* Start jenkinsJob and return its BuildStatus after completion
*
* @param jobId String jenkinsJobId
* @param subFolderPath workingDirectory
* @return Jenkins BuildStatus
*/
public BuildState startTask(String jobId, String subFolderPath) throws IOException, InterruptedException {
// we clone the Student submission to /Test subfolder and then copy those files into the working directory
File f = new File(subFolderPath + "/src/Test");
for (File fi : f.listFiles()) {
Files.move(Paths.get(fi.getPath()), Paths.get(subFolderPath + "/src/" + fi.getName()));
}
if (f.exists()) f.delete();
File temp = new File(subFolderPath + "/src/UnitTests/.git");
if (temp.exists() && temp.isDirectory() && temp.canWrite()) {
FileUtil.deleteFolderRecursively(temp);
}
temp = new File(subFolderPath + "/src/.git");
if (temp.exists() && temp.isDirectory() && temp.canWrite()) {
FileUtil.deleteFolderRecursively(temp);
}
// creating the jobId.json containing the jobId
FileWriter fileWriter = new FileWriter(subFolderPath + "/src/jobId.json");
fileWriter.write(new ObjectMapper().readTree("{\"jobId\":\"" + jobId + "\"}").toString());
fileWriter.close();
// creating repository with name jobId
Repository repository = this.gitTeaUtil.createRepository(jobId);
repository.setCloneUrl(repository.getCloneUrl().replace("localhost", modocotProperties.getDockerHostIp()));
// committing work-directory and pushing all files to repository
this.jGitUtil.commitAllAndPush(new File(subFolderPath), repository, false);
FileUtil.deleteFolderRecursively(new File(subFolderPath));
// persisting the jobId
RestAPIController.JOB_MAP.put(jobId, null);
createJenkinsJob(jobId, repository.getCloneUrl());
buildJenkinsJob(jobId);
// waiting for jenkinsJob to finish then returning its BuildStatus
int timeout = 0;
BuildState buildState = getJenkinsBuildState(jobId);
while (buildState != BuildState.BLUE && buildState != BuildState.RED) {
buildState = getJenkinsBuildState(jobId);
if (timeout >= 100) break;
Thread.sleep(6000);
timeout++;
}
return buildState;
}
public void deleteJenkinsJob(String jobId) {
LOG.info("deleteJenkinsJob jobId: " + jobId);
ResponseEntity<String> response = this.restCall.exchange("job/" + jobId + "/doDelete", HttpMethod.POST, null, String.class);
}
private BuildState getJenkinsBuildState(String jenkinsJob) {
LOG.info("getJenkinsBuildState jenkinsJob: " + jenkinsJob);
ResponseEntity<JenkinsJobData> response = this.restCall.exchange("api/json?tree=jobs[name,color]", HttpMethod.GET, null, JenkinsJobData.class);
if (response.getBody() == null) {
throw new NullPointerException("Jenkins Response was null");
}
return response.getBody()
.getJobs()
.stream()
.filter(job -> job.getName().equals(jenkinsJob))
.findFirst()
.get()
.getColor();
}
public String getJenkinsConsoleOutput(String jenkinsJob) {
ResponseEntity<String> response = this.restCall.exchange("job/" + jenkinsJob + "/lastBuild/consoleText", HttpMethod.GET, null, String.class);
return response.getBody();
}
private void buildJenkinsJob(String user) {
LOG.info("buildJenkinsJob user: " + user);
ResponseEntity<String> response = this.restCall.exchange("job/" + user + "/build", HttpMethod.POST, null, String.class);
}
private void createJenkinsJob(String gitUser, String gitUrl) {
LOG.info("createJenkinsJob gitUser: " + gitUser + ", gitUrl: " + gitUrl);
ResponseEntity<String> response = this.restCall.exchange("createItem?name=" + gitUser, HttpMethod.POST, createXmlFile(gitUser, gitUrl), String.class);
}
private String createXmlFile(String gitUser, String gitUrl) {
// fill data map for template
Map<String, String> templateData = new HashMap<>();
templateData.put("gitUser", gitUser);
templateData.put("gitUrl", gitUrl);
// freemarker create config
Configuration cfg = new Configuration(new Version("2.3.30"));
cfg.setClassForTemplateLoading(this.getClass(), "/templates");
cfg.setDefaultEncoding("UTF-8");
// fuse config and data
StringWriter out = new StringWriter();
try {
Template template = cfg.getTemplate("JenkinsFile.ftl");
template.process(templateData, out);
LOG.info(String.format("Template created with gitUrl: %s and gitUser: %s", gitUrl, gitUser));
} catch (IOException | TemplateException e) {
e.printStackTrace();
}
return out.getBuffer().toString();
}
public boolean isValidJSON(final String json) {
boolean valid = false;
try {
final JsonParser parser = new ObjectMapper().getFactory().createParser(json);
while (parser.nextToken() != null) {
}
valid = true;
} catch (IOException e) {
LOG.error("Json is invalid", e);
}
return valid;
}
}
package de.hftstuttgart.utils;
import de.hftstuttgart.exceptions.CorruptedZipFileException;
import de.hftstuttgart.exceptions.NoZipFileException;
import org.apache.log4j.Logger;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipInputStream;
/**
* Created by Marcel Bochtler on 13.11.16.
* Based on: https://www.mkyong.com/java/how-to-decompress-files-from-a-zip-file/
*/
public class UnzipUtil {
private static final Logger LOG = Logger.getLogger(UnzipUtil.class);
/**
* Unzips files and saves them to the disk.
* Checks if the zip file is valid.
*/
public static List<File> unzip(File zipFile) throws IOException {
String outputFolder = zipFile.getParentFile().getAbsolutePath();
List<File> unzippedFiles = new ArrayList<>();
byte[] buffer = new byte[1024];
//create output directory is not exists
File folder = new File(zipFile.getAbsolutePath());
if (!folder.exists()) {
folder.mkdir();
}
try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFile))) {
ZipEntry zipEntry = zipInputStream.getNextEntry();
if (zipEntry == null) {
String message = "The file " + zipFile.getAbsolutePath() + " does not seem be a zip file";
LOG.error(message);
throw new NoZipFileException(message);
}
while (zipEntry != null) {
String fileName = zipEntry.getName();
File unzippedFile = new File(outputFolder + File.separator + fileName);
LOG.info("Unzipped file: " + unzippedFile.getName());
// create all non exists folders
// else we will hit FileNotFoundException for compressed folder
new File(unzippedFile.getParent()).mkdirs();
FileOutputStream fos = new FileOutputStream(unzippedFile);
int length;
while ((length = zipInputStream.read(buffer)) > 0) {
fos.write(buffer, 0, length);
}
fos.close();
zipEntry = zipInputStream.getNextEntry();
unzippedFiles.add(unzippedFile);
}
if (zipFile.exists()) {
zipFile.delete();
}
return unzippedFiles;
} catch (ZipException ze) {
String msg = "Failed to unzip file " + zipFile;
LOG.error(msg);
throw new CorruptedZipFileException(msg);
}
}
}
# Multipart settings
spring.http.multipart.enabled=true
spring.http.multipart.max-file-size=5Mb
server.port=8081
docker.hostIp=10.40.10.144
jenkins.api.token=dome:1194017120ee74c91ee314e6f796e7b2ae
jenkins.url=http://${docker.hostIp}:8080/
###############################################
# Modocot properties
###############################################
# Holds the uploaded Zip-Files
modocot.dir.parent=/home/modocot
modocot.dir.assignment.prefix=Assignment_
modocot.dir.test.folder.name=UnitTests
gitTea.basePath=http://${docker.hostIp}:3000/api/v1
gitTea.username=giteaUser
gitTea.password=giteaUser1!
gitTea.defaultCommitMessage=Commit all changes including additions
gitTea.defaultOrigin=origin
\ No newline at end of file
modocot.git.username=username
modocot.git.password=password
\ No newline at end of file
<?xml version='1.1' encoding='UTF-8'?>
<flow-definition plugin="workflow-job@2.39">
<actions>
<org.jenkinsci.plugins.pipeline.modeldefinition.actions.DeclarativeJobAction plugin="pipeline-model-definition@1.6.0"/>
<org.jenkinsci.plugins.pipeline.modeldefinition.actions.DeclarativeJobPropertyTrackerAction plugin="pipeline-model-definition@1.6.0">
<jobProperties/>
<triggers/>
<parameters/>
<options/>
</org.jenkinsci.plugins.pipeline.modeldefinition.actions.DeclarativeJobPropertyTrackerAction>
</actions>
<description>Pipeline for User: ${gitUser} </description>
<keepDependencies>false</keepDependencies>
<properties/>
<definition class="org.jenkinsci.plugins.workflow.cps.CpsScmFlowDefinition" plugin="workflow-cps@2.80">
<scm class="hudson.plugins.git.GitSCM" plugin="git@4.2.2">
<configVersion>2</configVersion>
<userRemoteConfigs>
<hudson.plugins.git.UserRemoteConfig>
<url>${gitUrl}</url>
<credentialsId>giteaUser</credentialsId>
</hudson.plugins.git.UserRemoteConfig>
</userRemoteConfigs>
<branches>
<hudson.plugins.git.BranchSpec>
<name>*/master</name>
</hudson.plugins.git.BranchSpec>
</branches>
<doGenerateSubmoduleConfigurations>false</doGenerateSubmoduleConfigurations>
<submoduleCfg class="list"/>
<extensions/>
</scm>
<scriptPath>src/Jenkinsfile</scriptPath>
<lightweight>true</lightweight>
</definition>
<triggers/>
<disabled>false</disabled>
</flow-definition>
\ No newline at end of file
<project>
<actions/>
<description>${gitUser} ${gitUrl}</description>
<keepDependencies>false</keepDependencies>
<properties>
<hudson.plugins.jira.JiraProjectProperty plugin="jira@3.0.17"/>
</properties>
<scm class="hudson.scm.NullSCM"/>
<canRoam>true</canRoam>
<disabled>false</disabled>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<triggers/>
<concurrentBuild>false</concurrentBuild>
<builders/>
<publishers/>
<buildWrappers/>
</project>
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment