mirror of
https://github.com/theonedev/onedev.git
synced 2025-12-08 18:26:30 +00:00
Display job information on commit detail page
This commit is contained in:
parent
d7ae03ad21
commit
b4bccc3dc7
@ -81,9 +81,9 @@ import io.onedev.server.cache.DefaultCommitInfoManager;
|
||||
import io.onedev.server.cache.DefaultUserInfoManager;
|
||||
import io.onedev.server.cache.UserInfoManager;
|
||||
import io.onedev.server.ci.detector.CISpecDetector;
|
||||
import io.onedev.server.ci.job.DefaultJobScheduler;
|
||||
import io.onedev.server.ci.job.DefaultJobManager;
|
||||
import io.onedev.server.ci.job.DependencyPopulator;
|
||||
import io.onedev.server.ci.job.JobScheduler;
|
||||
import io.onedev.server.ci.job.JobManager;
|
||||
import io.onedev.server.ci.job.log.DefaultLogManager;
|
||||
import io.onedev.server.ci.job.log.LogManager;
|
||||
import io.onedev.server.ci.job.log.instruction.LogInstruction;
|
||||
@ -109,7 +109,7 @@ import io.onedev.server.entitymanager.IssueWatchManager;
|
||||
import io.onedev.server.entitymanager.MembershipManager;
|
||||
import io.onedev.server.entitymanager.MilestoneManager;
|
||||
import io.onedev.server.entitymanager.ProjectManager;
|
||||
import io.onedev.server.entitymanager.BuildRequirementManager;
|
||||
import io.onedev.server.entitymanager.PullRequestBuildManager;
|
||||
import io.onedev.server.entitymanager.PullRequestChangeManager;
|
||||
import io.onedev.server.entitymanager.PullRequestCommentManager;
|
||||
import io.onedev.server.entitymanager.PullRequestManager;
|
||||
@ -142,7 +142,7 @@ import io.onedev.server.entitymanager.impl.DefaultIssueWatchManager;
|
||||
import io.onedev.server.entitymanager.impl.DefaultMembershipManager;
|
||||
import io.onedev.server.entitymanager.impl.DefaultMilestoneManager;
|
||||
import io.onedev.server.entitymanager.impl.DefaultProjectManager;
|
||||
import io.onedev.server.entitymanager.impl.DefaultBuildRequirementManager;
|
||||
import io.onedev.server.entitymanager.impl.DefaultPullRequestBuildManager;
|
||||
import io.onedev.server.entitymanager.impl.DefaultPullRequestChangeManager;
|
||||
import io.onedev.server.entitymanager.impl.DefaultPullRequestCommentManager;
|
||||
import io.onedev.server.entitymanager.impl.DefaultPullRequestManager;
|
||||
@ -315,9 +315,9 @@ public class CoreModule extends AbstractPluginModule {
|
||||
bind(PullRequestReviewManager.class).to(DefaultPullRequestReviewManager.class);
|
||||
bind(BuildManager.class).to(DefaultBuildManager.class);
|
||||
bind(BuildDependenceManager.class).to(DefaultBuildDependenceManager.class);
|
||||
bind(JobScheduler.class).to(DefaultJobScheduler.class);
|
||||
bind(JobManager.class).to(DefaultJobManager.class);
|
||||
bind(LogManager.class).to(DefaultLogManager.class);
|
||||
bind(BuildRequirementManager.class).to(DefaultBuildRequirementManager.class);
|
||||
bind(PullRequestBuildManager.class).to(DefaultPullRequestBuildManager.class);
|
||||
bind(MailManager.class).to(DefaultMailManager.class);
|
||||
bind(IssueManager.class).to(DefaultIssueManager.class);
|
||||
bind(IssueFieldManager.class).to(DefaultIssueFieldManager.class);
|
||||
|
||||
@ -133,13 +133,13 @@ public class DefaultCacheManager implements CacheManager {
|
||||
for (Membership membership: dao.query(Membership.class))
|
||||
memberships.put(membership.getId(), membership.getFacade());
|
||||
|
||||
Query<?> query = dao.getSessionManager().getSession().createQuery("select id, project.id, commitHash from Build");
|
||||
Query<?> query = dao.getSession().createQuery("select id, project.id, commitHash from Build");
|
||||
for (Object[] fields: (List<Object[]>)query.list()) {
|
||||
Long buildId = (Long) fields[0];
|
||||
builds.put(buildId, new BuildFacade(buildId, (Long)fields[1], (String)fields[2]));
|
||||
}
|
||||
|
||||
query = dao.getSessionManager().getSession().createQuery("select id, project.id, number from Issue");
|
||||
query = dao.getSession().createQuery("select id, project.id, number from Issue");
|
||||
for (Object[] fields: (List<Object[]>)query.list()) {
|
||||
Long issueId = (Long) fields[0];
|
||||
issues.put(issueId, new IssueFacade(issueId, (Long)fields[1], (Long)fields[2]));
|
||||
@ -150,7 +150,7 @@ public class DefaultCacheManager implements CacheManager {
|
||||
for (UserAuthorization userAuthorization: dao.query(UserAuthorization.class))
|
||||
userAuthorizations.put(userAuthorization.getId(), userAuthorization.getFacade());
|
||||
|
||||
query = dao.getSessionManager().getSession().createQuery("select distinct name, type, value, id from BuildParam order by id");
|
||||
query = dao.getSession().createQuery("select distinct name, type, value, id from BuildParam order by id");
|
||||
for (Object[] fields: (List<Object[]>)query.list()) {
|
||||
if (!fields[1].equals(InputSpec.SECRET))
|
||||
addBuildParam((String) fields[0], (String) fields[2]);
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package io.onedev.server.ci;
|
||||
|
||||
import static java.util.stream.Collectors.toSet;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
@ -13,8 +15,11 @@ import javax.validation.ConstraintValidatorContext;
|
||||
import javax.validation.ValidationException;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import io.onedev.commons.utils.DependencyAware;
|
||||
import io.onedev.commons.utils.DependencyUtils;
|
||||
import io.onedev.commons.utils.StringUtils;
|
||||
import io.onedev.server.ci.job.Job;
|
||||
import io.onedev.server.ci.job.param.JobParam;
|
||||
@ -35,6 +40,8 @@ public class CISpec implements Serializable, Validatable {
|
||||
private List<Job> jobs = new ArrayList<>();
|
||||
|
||||
private transient Map<String, Job> jobMap;
|
||||
|
||||
private transient List<Job> sortedJobs;
|
||||
|
||||
@Editable
|
||||
public List<Job> getJobs() {
|
||||
@ -53,6 +60,37 @@ public class CISpec implements Serializable, Validatable {
|
||||
}
|
||||
return jobMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get jobs sorted by dependencies
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<Job> getSortedJobs() {
|
||||
if (sortedJobs == null) {
|
||||
sortedJobs = new ArrayList<>();
|
||||
|
||||
Map<String, DependencyAware<String>> dependencyMap = new LinkedHashMap<>();
|
||||
for (Job job: jobs) {
|
||||
dependencyMap.put(job.getName(), new DependencyAware<String>() {
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return job.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getDependencies() {
|
||||
return job.getDependencies().stream().map(it->it.getJobName()).collect(toSet());
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
for (String jobName: DependencyUtils.sortDependencies(dependencyMap))
|
||||
sortedJobs.add(Preconditions.checkNotNull(getJobMap().get(jobName)));
|
||||
}
|
||||
return sortedJobs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(ConstraintValidatorContext context) {
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
package io.onedev.server.ci.job;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -16,10 +16,12 @@ import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import javax.transaction.Synchronization;
|
||||
import javax.validation.ValidationException;
|
||||
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
@ -31,7 +33,6 @@ import org.slf4j.LoggerFactory;
|
||||
import com.google.common.base.CharMatcher;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import io.onedev.commons.launcher.loader.Listen;
|
||||
import io.onedev.commons.launcher.loader.ListenerRegistry;
|
||||
@ -49,7 +50,6 @@ import io.onedev.server.ci.job.param.JobParam;
|
||||
import io.onedev.server.ci.job.trigger.JobTrigger;
|
||||
import io.onedev.server.entitymanager.BuildManager;
|
||||
import io.onedev.server.entitymanager.BuildParamManager;
|
||||
import io.onedev.server.entitymanager.ProjectManager;
|
||||
import io.onedev.server.entitymanager.SettingManager;
|
||||
import io.onedev.server.entitymanager.UserManager;
|
||||
import io.onedev.server.event.BuildCommitAware;
|
||||
@ -81,18 +81,16 @@ import io.onedev.server.util.inputspec.SecretInput;
|
||||
import io.onedev.server.util.patternset.PatternSet;
|
||||
|
||||
@Singleton
|
||||
public class DefaultJobScheduler implements JobScheduler, Runnable, SchedulableTask {
|
||||
public class DefaultJobManager implements JobManager, Runnable, SchedulableTask {
|
||||
|
||||
private static final int CHECK_INTERVAL = 1000; // check internal in milli-seconds
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DefaultJobScheduler.class);
|
||||
private static final Logger logger = LoggerFactory.getLogger(DefaultJobManager.class);
|
||||
|
||||
private enum Status {STARTED, STOPPING, STOPPED};
|
||||
|
||||
private final Map<Long, JobExecution> jobExecutions = new ConcurrentHashMap<>();
|
||||
|
||||
private final ProjectManager projectManager;
|
||||
|
||||
private final BuildManager buildManager;
|
||||
|
||||
private final UserManager userManager;
|
||||
@ -122,12 +120,11 @@ public class DefaultJobScheduler implements JobScheduler, Runnable, SchedulableT
|
||||
private volatile Status status;
|
||||
|
||||
@Inject
|
||||
public DefaultJobScheduler(ProjectManager projectManager, BuildManager buildManager,
|
||||
public DefaultJobManager(BuildManager buildManager,
|
||||
UserManager userManager, ListenerRegistry listenerRegistry, SettingManager settingManager,
|
||||
TransactionManager transactionManager, LogManager logManager, ExecutorService executorService,
|
||||
SessionManager sessionManager, Set<DependencyPopulator> dependencyPopulators,
|
||||
TaskScheduler taskScheduler, BuildParamManager buildParamManager) {
|
||||
this.projectManager = projectManager;
|
||||
this.settingManager = settingManager;
|
||||
this.buildManager = buildManager;
|
||||
this.userManager = userManager;
|
||||
@ -141,54 +138,32 @@ public class DefaultJobScheduler implements JobScheduler, Runnable, SchedulableT
|
||||
this.buildParamManager = buildParamManager;
|
||||
}
|
||||
|
||||
@Sessional
|
||||
@Transactional
|
||||
@Override
|
||||
public void submit(Project project, String commitHash, String jobName, Map<String, List<List<String>>> paramMatrix) {
|
||||
String lockKey = "job-schedule: " + project.getId() + "-" + commitHash;
|
||||
Long projectId = project.getId();
|
||||
Long submitterId = User.idOf(userManager.getCurrent());
|
||||
transactionManager.runAsyncAfterCommit(new Runnable() {
|
||||
|
||||
public Build submit(Project project, String commitHash, String jobName, Map<String, List<String>> paramMap) {
|
||||
Lock lock = LockUtils.getLock("job-schedule: " + project.getId() + "-" + commitHash);
|
||||
transactionManager.getTransaction().registerSynchronization(new Synchronization() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
LockUtils.call(lockKey, new Callable<Void>() {
|
||||
|
||||
@Override
|
||||
public Void call() {
|
||||
transactionManager.run(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Project project = projectManager.load(projectId);
|
||||
User submitter = (submitterId != null? userManager.load(submitterId): null);
|
||||
new MatrixRunner<List<String>>(paramMatrix) {
|
||||
|
||||
@Override
|
||||
public void run(Map<String, List<String>> params) {
|
||||
submit(project, submitter, commitHash, jobName, params, new LinkedHashSet<>());
|
||||
}
|
||||
|
||||
}.run();
|
||||
}
|
||||
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
});
|
||||
public void beforeCompletion() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompletion(int status) {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
try {
|
||||
lock.lockInterruptibly();
|
||||
return submit(project, commitHash, jobName, paramMap, new LinkedHashSet<>());
|
||||
} catch (Exception e) {
|
||||
throw ExceptionUtils.unchecked(e);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, List<List<String>>> getParamMatrix(List<JobParam> params) {
|
||||
Map<String, List<List<String>>> paramMatrix = new LinkedHashMap<>();
|
||||
for (JobParam param: params)
|
||||
paramMatrix.put(param.getName(), param.getValuesProvider().getValues());
|
||||
return paramMatrix;
|
||||
}
|
||||
|
||||
private List<Build> submit(Project project, @Nullable User user, String commitHash, String jobName,
|
||||
private Build submit(Project project, String commitHash, String jobName,
|
||||
Map<String, List<String>> paramMap, Set<String> checkedJobNames) {
|
||||
Build build = new Build();
|
||||
build.setProject(project);
|
||||
@ -196,30 +171,30 @@ public class DefaultJobScheduler implements JobScheduler, Runnable, SchedulableT
|
||||
build.setJobName(jobName);
|
||||
build.setSubmitDate(new Date());
|
||||
build.setStatus(Build.Status.WAITING);
|
||||
build.setSubmitter(user);
|
||||
build.setSubmitter(userManager.getCurrent());
|
||||
|
||||
try {
|
||||
JobParam.validateParams(build.getJob().getParamSpecs(), JobParam.getParamMatrix(paramMap));
|
||||
JobParam.validateParamMap(build.getJob().getParamSpecMap(), paramMap);
|
||||
} catch (ValidationException e) {
|
||||
markBuildError(build, e.getMessage());
|
||||
return Lists.newArrayList(build);
|
||||
String message = String.format("Error validating build parameters (project: %s, commit: %s, job: %s)",
|
||||
project.getName(), commitHash, jobName);
|
||||
throw new OneException(message, e);
|
||||
}
|
||||
|
||||
if (!checkedJobNames.add(jobName)) {
|
||||
markBuildError(build, "Circular job dependencies found: " + checkedJobNames);
|
||||
return Lists.newArrayList(build);
|
||||
String message = String.format("Circular job dependencies found (project: %s, commit: %s, job: %s, dependency loop: %s)",
|
||||
project.getName(), commitHash, jobName, checkedJobNames);
|
||||
throw new OneException(message);
|
||||
}
|
||||
|
||||
Map<String, List<String>> copyOfParamMap = new HashMap<>(paramMap);
|
||||
Map<String, List<String>> paramMapToQuery = new HashMap<>(paramMap);
|
||||
for (InputSpec paramSpec: build.getJob().getParamSpecs()) {
|
||||
if (paramSpec instanceof SecretInput)
|
||||
copyOfParamMap.remove(paramSpec.getName());
|
||||
paramMapToQuery.remove(paramSpec.getName());
|
||||
}
|
||||
|
||||
List<Build> builds = buildManager.query(project, commitHash, jobName, copyOfParamMap);
|
||||
Collection<Build> builds = buildManager.query(project, commitHash, jobName, paramMapToQuery);
|
||||
if (builds.isEmpty()) {
|
||||
builds.add(build);
|
||||
|
||||
for (Map.Entry<String, List<String>> entry: paramMap.entrySet()) {
|
||||
InputSpec paramSpec = Preconditions.checkNotNull(build.getJob().getParamSpecMap().get(entry.getKey()));
|
||||
if (!entry.getValue().isEmpty()) {
|
||||
@ -241,18 +216,16 @@ public class DefaultJobScheduler implements JobScheduler, Runnable, SchedulableT
|
||||
}
|
||||
|
||||
for (JobDependency dependency: build.getJob().getDependencies()) {
|
||||
new MatrixRunner<List<String>>(getParamMatrix(dependency.getJobParams())) {
|
||||
new MatrixRunner<List<String>>(JobParam.getParamMatrix(dependency.getJobParams())) {
|
||||
|
||||
@Override
|
||||
public void run(Map<String, List<String>> params) {
|
||||
List<Build> dependencyBuilds = submit(project, null, commitHash, dependency.getJobName(),
|
||||
Build dependencyBuild = submit(project, commitHash, dependency.getJobName(),
|
||||
params, new LinkedHashSet<>(checkedJobNames));
|
||||
for (Build dependencyBuild: dependencyBuilds) {
|
||||
BuildDependence dependence = new BuildDependence();
|
||||
dependence.setDependency(dependencyBuild);
|
||||
dependence.setDependent(build);
|
||||
build.getDependencies().add(dependence);
|
||||
}
|
||||
BuildDependence dependence = new BuildDependence();
|
||||
dependence.setDependency(dependencyBuild);
|
||||
dependence.setDependent(build);
|
||||
build.getDependencies().add(dependence);
|
||||
}
|
||||
|
||||
}.run();
|
||||
@ -260,8 +233,10 @@ public class DefaultJobScheduler implements JobScheduler, Runnable, SchedulableT
|
||||
|
||||
buildManager.create(build);
|
||||
listenerRegistry.post(new BuildSubmitted(build));
|
||||
return build;
|
||||
} else {
|
||||
return builds.iterator().next();
|
||||
}
|
||||
return builds;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@ -396,8 +371,6 @@ public class DefaultJobScheduler implements JobScheduler, Runnable, SchedulableT
|
||||
private void markBuildError(Build build, String errorMessage) {
|
||||
build.setStatus(Build.Status.IN_ERROR, errorMessage);
|
||||
build.setFinishDate(new Date());
|
||||
if (build.isNew())
|
||||
buildManager.create(build);
|
||||
listenerRegistry.post(new BuildFinished(build));
|
||||
}
|
||||
|
||||
@ -412,8 +385,16 @@ public class DefaultJobScheduler implements JobScheduler, Runnable, SchedulableT
|
||||
if (ciSpec != null) {
|
||||
for (Job job: ciSpec.getJobs()) {
|
||||
JobTrigger trigger = job.getMatchedTrigger(event);
|
||||
if (trigger != null)
|
||||
submit(event.getProject(), commitId.name(), job.getName(), getParamMatrix(trigger.getParams()));
|
||||
if (trigger != null) {
|
||||
new MatrixRunner<List<String>>(JobParam.getParamMatrix(trigger.getParams())) {
|
||||
|
||||
@Override
|
||||
public void run(Map<String, List<String>> paramMap) {
|
||||
submit(event.getProject(), commitId.name(), job.getName(), paramMap);
|
||||
}
|
||||
|
||||
}.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@ -618,5 +599,5 @@ public class DefaultJobScheduler implements JobScheduler, Runnable, SchedulableT
|
||||
public ScheduleBuilder<?> getScheduleBuilder() {
|
||||
return CronScheduleBuilder.dailyAtHourAndMinute(0, 0);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -3,7 +3,6 @@ package io.onedev.server.ci.job;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@ -15,6 +14,7 @@ import org.hibernate.validator.constraints.NotEmpty;
|
||||
import io.onedev.server.ci.JobDependency;
|
||||
import io.onedev.server.ci.job.cache.JobCache;
|
||||
import io.onedev.server.ci.job.log.LogLevel;
|
||||
import io.onedev.server.ci.job.param.JobParam;
|
||||
import io.onedev.server.ci.job.trigger.JobTrigger;
|
||||
import io.onedev.server.event.ProjectEvent;
|
||||
import io.onedev.server.util.inputspec.InputSpec;
|
||||
@ -229,11 +229,8 @@ public class Job implements Serializable, Validatable {
|
||||
}
|
||||
|
||||
public Map<String, InputSpec> getParamSpecMap() {
|
||||
if (paramSpecMap == null) {
|
||||
paramSpecMap = new LinkedHashMap<>();
|
||||
for (InputSpec paramSpec: getParamSpecs())
|
||||
paramSpecMap.put(paramSpec.getName(), paramSpec);
|
||||
}
|
||||
if (paramSpecMap == null)
|
||||
paramSpecMap = JobParam.getParamSpecMap(paramSpecs);
|
||||
return paramSpecMap;
|
||||
}
|
||||
|
||||
|
||||
@ -6,12 +6,12 @@ import java.util.Map;
|
||||
import io.onedev.server.model.Build;
|
||||
import io.onedev.server.model.Project;
|
||||
|
||||
public interface JobScheduler {
|
||||
public interface JobManager {
|
||||
|
||||
void submit(Project project, String commitHash, String jobName, Map<String, List<List<String>>> paramMatrix);
|
||||
Build submit(Project project, String commitHash, String jobName, Map<String, List<String>> paramMap);
|
||||
|
||||
void resubmit(Build build, Map<String, List<String>> paramMap);
|
||||
|
||||
void cancel(Build build);
|
||||
|
||||
|
||||
}
|
||||
@ -5,6 +5,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@ -87,7 +88,7 @@ public class JobParam implements Serializable {
|
||||
.toHashCode();
|
||||
}
|
||||
|
||||
public static void validateValues(List<List<String>> values) {
|
||||
public static void validateParamValues(List<List<String>> values) {
|
||||
if (values.isEmpty())
|
||||
throw new ValidationException("At least one value needs to be specified");
|
||||
Set<List<String>> encountered = new HashSet<>();
|
||||
@ -99,44 +100,64 @@ public class JobParam implements Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
public static void validateParams(List<InputSpec> paramSpecs, Map<String, List<List<String>>> params) {
|
||||
Map<String, InputSpec> paramSpecMap = new HashMap<>();
|
||||
for (InputSpec paramSpec: paramSpecs) {
|
||||
paramSpecMap.put(paramSpec.getName(), paramSpec);
|
||||
if (!params.containsKey(paramSpec.getName()))
|
||||
throw new ValidationException("Missing job parameter: " + paramSpec.getName());
|
||||
}
|
||||
|
||||
for (Map.Entry<String, List<List<String>>> entry: params.entrySet()) {
|
||||
InputSpec paramSpec = paramSpecMap.get(entry.getKey());
|
||||
if (paramSpec == null)
|
||||
throw new ValidationException("Unknown job parameter: " + entry.getKey());
|
||||
|
||||
public static void validateParamMatrix(Map<String, InputSpec> paramSpecMap, Map<String, List<List<String>>> paramMatrix) {
|
||||
validateParamNames(paramSpecMap.keySet(), paramMatrix.keySet());
|
||||
for (Map.Entry<String, List<List<String>>> entry: paramMatrix.entrySet()) {
|
||||
InputSpec paramSpec = Preconditions.checkNotNull(paramSpecMap.get(entry.getKey()));
|
||||
if (entry.getValue() != null) {
|
||||
try {
|
||||
validateValues(entry.getValue());
|
||||
validateParamValues(entry.getValue());
|
||||
} catch (ValidationException e) {
|
||||
throw new ValidationException("Error validating values of parameter '"
|
||||
+ entry.getKey() + "': " + e.getMessage());
|
||||
}
|
||||
|
||||
for (List<String> value: entry.getValue()) {
|
||||
try {
|
||||
paramSpec.convertToObject(value);
|
||||
} catch (Exception e) {
|
||||
String displayValue;
|
||||
if (paramSpec instanceof SecretInput)
|
||||
displayValue = SecretInput.MASK;
|
||||
else
|
||||
displayValue = value.toString();
|
||||
throw new ValidationException("Error validating value '" + displayValue + "' of parameter '"
|
||||
+ entry.getKey() + "': " + e.getMessage());
|
||||
}
|
||||
}
|
||||
for (List<String> value: entry.getValue())
|
||||
validateParamValue(paramSpec, entry.getKey(), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateParamValue(InputSpec paramSpec, String paramName, List<String> paramValue) {
|
||||
try {
|
||||
paramSpec.convertToObject(paramValue);
|
||||
} catch (Exception e) {
|
||||
String displayValue;
|
||||
if (paramSpec instanceof SecretInput)
|
||||
displayValue = SecretInput.MASK;
|
||||
else
|
||||
displayValue = paramValue.toString();
|
||||
throw new ValidationException("Error validating value '" + displayValue + "' of parameter '"
|
||||
+ paramName + "': " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateParamNames(Collection<String> paramSpecNames, Collection<String> paramNames) {
|
||||
for (String paramSpecName: paramSpecNames) {
|
||||
if (!paramNames.contains(paramSpecName))
|
||||
throw new ValidationException("Missing job parameter: " + paramSpecName);
|
||||
}
|
||||
for (String paramName: paramNames) {
|
||||
if (!paramSpecNames.contains(paramName))
|
||||
throw new ValidationException("Unknow job parameter: " + paramName);
|
||||
}
|
||||
}
|
||||
|
||||
public static void validateParamMap(Map<String, InputSpec> paramSpecMap, Map<String, List<String>> paramMap) {
|
||||
validateParamNames(paramSpecMap.keySet(), paramMap.keySet());
|
||||
for (Map.Entry<String, List<String>> entry: paramMap.entrySet()) {
|
||||
InputSpec paramSpec = Preconditions.checkNotNull(paramSpecMap.get(entry.getKey()));
|
||||
validateParamValue(paramSpec, entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String, InputSpec> getParamSpecMap(List<InputSpec> paramSpecs) {
|
||||
Map<String, InputSpec> paramSpecMap = new LinkedHashMap<>();
|
||||
for (InputSpec paramSpec: paramSpecs)
|
||||
paramSpecMap.put(paramSpec.getName(), paramSpec);
|
||||
return paramSpecMap;
|
||||
}
|
||||
|
||||
public static void validateParams(List<InputSpec> paramSpecs, List<JobParam> params) {
|
||||
Map<String, List<List<String>>> paramMap = new HashMap<>();
|
||||
for (JobParam param: params) {
|
||||
@ -148,17 +169,7 @@ public class JobParam implements Serializable {
|
||||
if (paramMap.put(param.getName(), values) != null)
|
||||
throw new ValidationException("Duplicate param: " + param.getName());
|
||||
}
|
||||
validateParams(paramSpecs, paramMap);
|
||||
}
|
||||
|
||||
public static Map<String, List<List<String>>> getParamMatrix(Map<String, List<String>> paramMap) {
|
||||
Map<String, List<List<String>>> paramMatrix = new HashMap<>();
|
||||
for (Map.Entry<String, List<String>> entry: paramMap.entrySet()) {
|
||||
List<List<String>> values = new ArrayList<>();
|
||||
values.add(entry.getValue());
|
||||
paramMatrix.put(entry.getKey(), values);
|
||||
}
|
||||
return paramMatrix;
|
||||
validateParamMatrix(getParamSpecMap(paramSpecs), paramMap);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -220,5 +231,12 @@ public class JobParam implements Serializable {
|
||||
}
|
||||
return paramMap;
|
||||
}
|
||||
|
||||
public static Map<String, List<List<String>>> getParamMatrix(List<JobParam> params) {
|
||||
Map<String, List<List<String>>> paramMatrix = new LinkedHashMap<>();
|
||||
for (JobParam param: params)
|
||||
paramMatrix.put(param.getName(), param.getValuesProvider().getValues());
|
||||
return paramMatrix;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package io.onedev.server.entitymanager;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -17,13 +18,13 @@ public interface BuildManager extends EntityManager<Build> {
|
||||
@Nullable
|
||||
Build find(Project project, long number);
|
||||
|
||||
List<Build> query(Project project, String commitHash, @Nullable String jobName, Map<String, List<String>> params);
|
||||
Collection<Build> query(Project project, String commitHash, @Nullable String jobName, Map<String, List<String>> params);
|
||||
|
||||
List<Build> query(Project project, String commitHash);
|
||||
Collection<Build> query(Project project, String commitHash);
|
||||
|
||||
void create(Build build);
|
||||
|
||||
List<Build> queryUnfinished();
|
||||
Collection<Build> queryUnfinished();
|
||||
|
||||
List<Build> query(Project project, String term, int count);
|
||||
|
||||
|
||||
@ -1,11 +0,0 @@
|
||||
package io.onedev.server.entitymanager;
|
||||
|
||||
import io.onedev.server.model.PullRequest;
|
||||
import io.onedev.server.model.BuildRequirement;
|
||||
import io.onedev.server.persistence.dao.EntityManager;
|
||||
|
||||
public interface BuildRequirementManager extends EntityManager<BuildRequirement> {
|
||||
|
||||
void saveBuildRequirements(PullRequest request);
|
||||
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package io.onedev.server.entitymanager;
|
||||
|
||||
import io.onedev.server.model.PullRequest;
|
||||
import io.onedev.server.model.PullRequestBuild;
|
||||
import io.onedev.server.persistence.dao.EntityManager;
|
||||
|
||||
public interface PullRequestBuildManager extends EntityManager<PullRequestBuild> {
|
||||
|
||||
void savePullRequestBuilds(PullRequest request);
|
||||
|
||||
}
|
||||
@ -33,8 +33,6 @@ public interface PullRequestManager extends EntityManager<PullRequest> {
|
||||
@Nullable
|
||||
PullRequest findLatest(Project targetProject, User submitter);
|
||||
|
||||
Collection<PullRequest> queryOpenByCommit(String commitHash);
|
||||
|
||||
void discard(PullRequest request, @Nullable String note);
|
||||
|
||||
void reopen(PullRequest request, @Nullable String note);
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package io.onedev.server.entitymanager.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -68,10 +69,6 @@ public class DefaultBuildManager extends AbstractEntityManager<Build> implements
|
||||
@Transactional
|
||||
@Override
|
||||
public void delete(Build build) {
|
||||
Query<?> query = getSession().createQuery("update BuildRequirement set build=null where build=:build");
|
||||
query.setParameter("build", build);
|
||||
query.executeUpdate();
|
||||
|
||||
FileUtils.deleteDir(storageManager.getBuildDir(build.getProject().getId(), build.getNumber()));
|
||||
super.delete(build);
|
||||
}
|
||||
@ -88,13 +85,13 @@ public class DefaultBuildManager extends AbstractEntityManager<Build> implements
|
||||
|
||||
@Sessional
|
||||
@Override
|
||||
public List<Build> query(Project project, String commitHash) {
|
||||
public Collection<Build> query(Project project, String commitHash) {
|
||||
return query(project, commitHash, null, new HashMap<>());
|
||||
}
|
||||
|
||||
@Sessional
|
||||
@Override
|
||||
public List<Build> query(Project project, String commitHash, String jobName, Map<String, List<String>> params) {
|
||||
public Collection<Build> query(Project project, String commitHash, String jobName, Map<String, List<String>> params) {
|
||||
CriteriaBuilder builder = getSession().getCriteriaBuilder();
|
||||
CriteriaQuery<Build> query = builder.createQuery(Build.class);
|
||||
Root<Build> root = query.from(Build.class);
|
||||
@ -124,7 +121,7 @@ public class DefaultBuildManager extends AbstractEntityManager<Build> implements
|
||||
|
||||
@Sessional
|
||||
@Override
|
||||
public List<Build> queryUnfinished() {
|
||||
public Collection<Build> queryUnfinished() {
|
||||
EntityCriteria<Build> criteria = newCriteria();
|
||||
criteria.add(Restrictions.or(
|
||||
Restrictions.eq("status", Status.QUEUEING),
|
||||
|
||||
@ -1,46 +0,0 @@
|
||||
package io.onedev.server.entitymanager.impl;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import io.onedev.server.entitymanager.BuildRequirementManager;
|
||||
import io.onedev.server.model.PullRequest;
|
||||
import io.onedev.server.model.BuildRequirement;
|
||||
import io.onedev.server.persistence.annotation.Transactional;
|
||||
import io.onedev.server.persistence.dao.AbstractEntityManager;
|
||||
import io.onedev.server.persistence.dao.Dao;
|
||||
|
||||
@Singleton
|
||||
public class DefaultBuildRequirementManager extends AbstractEntityManager<BuildRequirement>
|
||||
implements BuildRequirementManager {
|
||||
|
||||
@Inject
|
||||
public DefaultBuildRequirementManager(Dao dao) {
|
||||
super(dao);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void saveBuildRequirements(PullRequest request) {
|
||||
Collection<Long> ids = new HashSet<>();
|
||||
for (BuildRequirement requirement: request.getBuildRequirements()) {
|
||||
save(requirement);
|
||||
ids.add(requirement.getId());
|
||||
}
|
||||
if (!ids.isEmpty()) {
|
||||
Query query = getSession().createQuery("delete from BuildRequirement where request=:request and id not in (:ids)");
|
||||
query.setParameter("request", request);
|
||||
query.setParameter("ids", ids);
|
||||
query.executeUpdate();
|
||||
} else {
|
||||
Query query = getSession().createQuery("delete from BuildRequirement where request=:request");
|
||||
query.setParameter("request", request);
|
||||
query.executeUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
package io.onedev.server.entitymanager.impl;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import io.onedev.commons.launcher.loader.ListenerRegistry;
|
||||
import io.onedev.server.entitymanager.PullRequestBuildManager;
|
||||
import io.onedev.server.event.pullrequest.PullRequestBuildEvent;
|
||||
import io.onedev.server.model.PullRequest;
|
||||
import io.onedev.server.model.PullRequestBuild;
|
||||
import io.onedev.server.persistence.annotation.Transactional;
|
||||
import io.onedev.server.persistence.dao.AbstractEntityManager;
|
||||
import io.onedev.server.persistence.dao.Dao;
|
||||
|
||||
@Singleton
|
||||
public class DefaultPullRequestBuildManager extends AbstractEntityManager<PullRequestBuild>
|
||||
implements PullRequestBuildManager {
|
||||
|
||||
private final ListenerRegistry listenerRegistry;
|
||||
|
||||
@Inject
|
||||
public DefaultPullRequestBuildManager(Dao dao, ListenerRegistry listenerRegistry) {
|
||||
super(dao);
|
||||
this.listenerRegistry = listenerRegistry;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void savePullRequestBuilds(PullRequest request) {
|
||||
Collection<Long> ids = new HashSet<>();
|
||||
for (PullRequestBuild pullRequestBuild: request.getPullRequestBuilds()) {
|
||||
boolean isNew = pullRequestBuild.isNew();
|
||||
save(pullRequestBuild);
|
||||
if (isNew)
|
||||
listenerRegistry.post(new PullRequestBuildEvent(pullRequestBuild));
|
||||
ids.add(pullRequestBuild.getId());
|
||||
}
|
||||
if (!ids.isEmpty()) {
|
||||
Query query = getSession().createQuery("delete from PullRequestBuild where request=:request and id not in (:ids)");
|
||||
query.setParameter("request", request);
|
||||
query.setParameter("ids", ids);
|
||||
query.executeUpdate();
|
||||
} else {
|
||||
Query query = getSession().createQuery("delete from PullRequestBuild where request=:request");
|
||||
query.setParameter("request", request);
|
||||
query.executeUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -17,7 +17,6 @@ import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@ -61,10 +60,9 @@ import io.onedev.server.OneDev;
|
||||
import io.onedev.server.OneException;
|
||||
import io.onedev.server.cache.CommitInfoManager;
|
||||
import io.onedev.server.ci.JobDependency;
|
||||
import io.onedev.server.ci.job.JobScheduler;
|
||||
import io.onedev.server.ci.job.JobManager;
|
||||
import io.onedev.server.ci.job.param.JobParam;
|
||||
import io.onedev.server.entitymanager.BuildManager;
|
||||
import io.onedev.server.entitymanager.BuildRequirementManager;
|
||||
import io.onedev.server.entitymanager.PullRequestBuildManager;
|
||||
import io.onedev.server.entitymanager.ProjectManager;
|
||||
import io.onedev.server.entitymanager.PullRequestChangeManager;
|
||||
import io.onedev.server.entitymanager.PullRequestManager;
|
||||
@ -83,7 +81,7 @@ import io.onedev.server.event.pullrequest.PullRequestOpened;
|
||||
import io.onedev.server.git.GitUtils;
|
||||
import io.onedev.server.git.command.FileChange;
|
||||
import io.onedev.server.model.Build;
|
||||
import io.onedev.server.model.BuildRequirement;
|
||||
import io.onedev.server.model.PullRequestBuild;
|
||||
import io.onedev.server.model.Group;
|
||||
import io.onedev.server.model.Project;
|
||||
import io.onedev.server.model.PullRequest;
|
||||
@ -153,39 +151,36 @@ public class DefaultPullRequestManager extends AbstractEntityManager<PullRequest
|
||||
|
||||
private final PullRequestReviewManager pullRequestReviewManager;
|
||||
|
||||
private final BuildRequirementManager buildRequirementManager;
|
||||
private final PullRequestBuildManager pullRequestBuildManager;
|
||||
|
||||
private final BatchWorkManager batchWorkManager;
|
||||
|
||||
private final PullRequestChangeManager pullRequestChangeManager;
|
||||
|
||||
private final BuildManager buildManager;
|
||||
|
||||
private final TransactionManager transactionManager;
|
||||
|
||||
private final JobScheduler jobScheduler;
|
||||
private final JobManager jobManager;
|
||||
|
||||
@Inject
|
||||
public DefaultPullRequestManager(Dao dao, PullRequestUpdateManager pullRequestUpdateManager,
|
||||
PullRequestReviewManager pullRequestReviewManager, UserManager userManager,
|
||||
MarkdownManager markdownManager, BatchWorkManager batchWorkManager,
|
||||
ListenerRegistry listenerRegistry, SessionManager sessionManager,
|
||||
PullRequestChangeManager pullRequestChangeManager, BuildManager buildManager,
|
||||
BuildRequirementManager buildRequirementManager, TransactionManager transactionManager,
|
||||
JobScheduler jobScheduler, ProjectManager projectManager) {
|
||||
PullRequestChangeManager pullRequestChangeManager,
|
||||
PullRequestBuildManager pullRequestBuildManager, TransactionManager transactionManager,
|
||||
JobManager jobManager, ProjectManager projectManager) {
|
||||
super(dao);
|
||||
|
||||
this.pullRequestUpdateManager = pullRequestUpdateManager;
|
||||
this.pullRequestReviewManager = pullRequestReviewManager;
|
||||
this.transactionManager = transactionManager;
|
||||
this.buildManager = buildManager;
|
||||
this.userManager = userManager;
|
||||
this.batchWorkManager = batchWorkManager;
|
||||
this.sessionManager = sessionManager;
|
||||
this.listenerRegistry = listenerRegistry;
|
||||
this.pullRequestChangeManager = pullRequestChangeManager;
|
||||
this.buildRequirementManager = buildRequirementManager;
|
||||
this.jobScheduler = jobScheduler;
|
||||
this.pullRequestBuildManager = pullRequestBuildManager;
|
||||
this.jobManager = jobManager;
|
||||
this.projectManager = projectManager;
|
||||
}
|
||||
|
||||
@ -376,7 +371,7 @@ public class DefaultPullRequestManager extends AbstractEntityManager<PullRequest
|
||||
pullRequestUpdateManager.save(update, false);
|
||||
|
||||
pullRequestReviewManager.saveReviews(request);
|
||||
buildRequirementManager.saveBuildRequirements(request);
|
||||
pullRequestBuildManager.savePullRequestBuilds(request);
|
||||
|
||||
checkAsync(request);
|
||||
|
||||
@ -445,12 +440,12 @@ public class DefaultPullRequestManager extends AbstractEntityManager<PullRequest
|
||||
checkQuality(request);
|
||||
|
||||
pullRequestReviewManager.saveReviews(request);
|
||||
buildRequirementManager.saveBuildRequirements(request);
|
||||
pullRequestBuildManager.savePullRequestBuilds(request);
|
||||
|
||||
MergePreview mergePreview = request.getMergePreview();
|
||||
MergePreview preview = request.getMergePreview();
|
||||
|
||||
if (request.isAllReviewsApproved() && request.isAllBuildsSuccessful()
|
||||
&& mergePreview != null && mergePreview.getMerged() != null) {
|
||||
&& preview != null && preview.getMerged() != null) {
|
||||
merge(request);
|
||||
}
|
||||
}
|
||||
@ -553,7 +548,13 @@ public class DefaultPullRequestManager extends AbstractEntityManager<PullRequest
|
||||
ofOpen(),
|
||||
Restrictions.or(ofSource(projectAndBranch), ofTarget(projectAndBranch)));
|
||||
for (PullRequest request: query(EntityCriteria.of(PullRequest.class).add(criterion))) {
|
||||
check(request);
|
||||
try {
|
||||
check(request);
|
||||
} catch (Exception e) {
|
||||
String message = String.format("Error checking pull request (project: %s, number: %d)",
|
||||
request.getTargetProject().getName(), request.getNumber());
|
||||
logger.error(message, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -637,9 +638,9 @@ public class DefaultPullRequestManager extends AbstractEntityManager<PullRequest
|
||||
@Transactional
|
||||
public void on(BuildEvent event) {
|
||||
Build build = event.getBuild();
|
||||
for (PullRequest request: queryOpenByCommit(build.getCommitHash())) {
|
||||
listenerRegistry.post(new PullRequestBuildEvent(request, build));
|
||||
checkAsync(request);
|
||||
for (PullRequestBuild pullRequestBuild: build.getPullRequestBuilds()) {
|
||||
listenerRegistry.post(new PullRequestBuildEvent(pullRequestBuild));
|
||||
checkAsync(pullRequestBuild.getRequest());
|
||||
}
|
||||
}
|
||||
|
||||
@ -664,7 +665,9 @@ public class DefaultPullRequestManager extends AbstractEntityManager<PullRequest
|
||||
ThreadContext.bind(subject);
|
||||
check(load(requestId));
|
||||
} catch (Exception e) {
|
||||
logger.error("Error checking pull request status", e);
|
||||
String message = String.format("Error checking pull request (project: %s, number: %d)",
|
||||
request.getTargetProject().getName(), request.getNumber());
|
||||
logger.error(message, e);
|
||||
} finally {
|
||||
ThreadContext.unbindSubject();
|
||||
}
|
||||
@ -711,68 +714,35 @@ public class DefaultPullRequestManager extends AbstractEntityManager<PullRequest
|
||||
}
|
||||
|
||||
private void checkBuilds(PullRequest request, List<JobDependency> jobDependencies) {
|
||||
String commit;
|
||||
Collection<PullRequestBuild> prevRequirements = new ArrayList<>(request.getPullRequestBuilds());
|
||||
request.getPullRequestBuilds().clear();
|
||||
MergePreview preview = request.getMergePreview();
|
||||
if (preview != null && preview.getMerged() != null)
|
||||
commit = preview.getMerged();
|
||||
else
|
||||
commit = null;
|
||||
|
||||
List<Build> builds;
|
||||
if (commit != null)
|
||||
builds = buildManager.query(request.getTargetProject(), commit);
|
||||
else
|
||||
builds = new ArrayList<>();
|
||||
|
||||
Collection<BuildRequirement> effectiveRequirements = new HashSet<>();
|
||||
|
||||
for (JobDependency dependency: jobDependencies) {
|
||||
Map<String, List<List<String>>> paramMatrix = new HashMap<>();
|
||||
Set<String> secretParamNames = new HashSet<>();
|
||||
for (JobParam param: dependency.getJobParams()) {
|
||||
paramMatrix.put(param.getName(), param.getValuesProvider().getValues());
|
||||
if (param.isSecret())
|
||||
secretParamNames.add(param.getName());
|
||||
}
|
||||
|
||||
new MatrixRunner<List<String>>(paramMatrix) {
|
||||
|
||||
@Override
|
||||
public void run(Map<String, List<String>> params) {
|
||||
BuildRequirement requirement = request.getBuildRequirement(dependency.getJobName(), params);
|
||||
if (requirement == null) {
|
||||
requirement = new BuildRequirement();
|
||||
requirement.setJobName(dependency.getJobName());
|
||||
requirement.setBuildParams(new LinkedHashMap<>(params));
|
||||
requirement.setRequest(request);
|
||||
request.getBuildRequirements().add(requirement);
|
||||
}
|
||||
effectiveRequirements.add(requirement);
|
||||
if (preview != null && preview.getMerged() != null) {
|
||||
for (JobDependency dependency: jobDependencies) {
|
||||
new MatrixRunner<List<String>>(JobParam.getParamMatrix(dependency.getJobParams())) {
|
||||
|
||||
Build build = null;
|
||||
for (Build each: builds) {
|
||||
Map<String, List<String>> paramsWithoutSecrets = new HashMap<>(params);
|
||||
Map<String, List<String>> buildParamsWithoutSecrets = new HashMap<>(each.getParamMap());
|
||||
paramsWithoutSecrets.keySet().removeAll(secretParamNames);
|
||||
buildParamsWithoutSecrets.keySet().removeAll(secretParamNames);
|
||||
if (each.getJobName().equals(dependency.getJobName()) && buildParamsWithoutSecrets.equals(paramsWithoutSecrets)) {
|
||||
build = each;
|
||||
break;
|
||||
@Override
|
||||
public void run(Map<String, List<String>> paramMap) {
|
||||
Build build = jobManager.submit(request.getTargetProject(), preview.getMerged(),
|
||||
dependency.getJobName(), paramMap);
|
||||
PullRequestBuild pullRequestBuild = null;
|
||||
for (PullRequestBuild prevRequirement: prevRequirements) {
|
||||
if (prevRequirement.getBuild().equals(build)) {
|
||||
pullRequestBuild = prevRequirement;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pullRequestBuild == null) {
|
||||
pullRequestBuild = new PullRequestBuild();
|
||||
pullRequestBuild.setRequest(request);
|
||||
pullRequestBuild.setBuild(build);
|
||||
}
|
||||
request.getPullRequestBuilds().add(pullRequestBuild);
|
||||
}
|
||||
|
||||
requirement.setBuild(build);
|
||||
|
||||
if (commit != null) {
|
||||
jobScheduler.submit(request.getTargetProject(), commit,
|
||||
dependency.getJobName(), JobParam.getParamMatrix(params));
|
||||
}
|
||||
}
|
||||
|
||||
}.run();
|
||||
}.run();
|
||||
}
|
||||
}
|
||||
|
||||
request.getBuildRequirements().retainAll(effectiveRequirements);
|
||||
}
|
||||
|
||||
private void checkReviews(ReviewRequirement reviewRequirement, PullRequestUpdate update) {
|
||||
@ -948,18 +918,6 @@ public class DefaultPullRequestManager extends AbstractEntityManager<PullRequest
|
||||
return addedContributions;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public Collection<PullRequest> queryOpenByCommit(String commitHash) {
|
||||
EntityCriteria<PullRequest> criteria = EntityCriteria.of(PullRequest.class);
|
||||
criteria.add(PullRequest.CriterionHelper.ofOpen());
|
||||
Criterion verifyCommitCriterion = Restrictions.or(
|
||||
Restrictions.eq("headCommitHash", commitHash),
|
||||
Restrictions.eq("lastMergePreview.merged", commitHash));
|
||||
criteria.add(verifyCommitCriterion);
|
||||
return query(criteria);
|
||||
}
|
||||
|
||||
private Predicate[] getPredicates(io.onedev.server.search.entity.EntityCriteria<PullRequest> criteria,
|
||||
Project targetProject, User user, Root<PullRequest> root, CriteriaBuilder builder) {
|
||||
List<Predicate> predicates = new ArrayList<>();
|
||||
|
||||
@ -2,20 +2,19 @@ package io.onedev.server.event.pullrequest;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import io.onedev.server.model.Build;
|
||||
import io.onedev.server.model.PullRequest;
|
||||
import io.onedev.server.model.PullRequestBuild;
|
||||
|
||||
public class PullRequestBuildEvent extends PullRequestEvent {
|
||||
|
||||
private final Build build;
|
||||
private final PullRequestBuild pullRequestBuild;
|
||||
|
||||
public PullRequestBuildEvent(PullRequest request, Build build) {
|
||||
super(null, new Date(), request);
|
||||
this.build = build;
|
||||
public PullRequestBuildEvent(PullRequestBuild pullRequestBuild) {
|
||||
super(null, new Date(), pullRequestBuild.getRequest());
|
||||
this.pullRequestBuild = pullRequestBuild;
|
||||
}
|
||||
|
||||
public Build getBuild() {
|
||||
return build;
|
||||
public PullRequestBuild getPullRequestBuild() {
|
||||
return pullRequestBuild;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -18,6 +18,7 @@ import io.onedev.commons.launcher.bootstrap.Bootstrap;
|
||||
import io.onedev.server.persistence.DefaultPersistManager;
|
||||
import io.onedev.server.persistence.HibernateProperties;
|
||||
import io.onedev.server.persistence.IdManager;
|
||||
import io.onedev.server.persistence.TransactionManager;
|
||||
import io.onedev.server.persistence.dao.Dao;
|
||||
import io.onedev.server.util.validation.EntityValidator;
|
||||
|
||||
@ -31,8 +32,9 @@ public class ApplyDatabaseConstraints extends DefaultPersistManager {
|
||||
@Inject
|
||||
public ApplyDatabaseConstraints(PhysicalNamingStrategy physicalNamingStrategy,
|
||||
HibernateProperties properties, Interceptor interceptor,
|
||||
IdManager idManager, Dao dao, EntityValidator validator) {
|
||||
super(physicalNamingStrategy, properties, interceptor, idManager, dao, validator);
|
||||
IdManager idManager, Dao dao, EntityValidator validator,
|
||||
TransactionManager transactionManager) {
|
||||
super(physicalNamingStrategy, properties, interceptor, idManager, dao, validator, transactionManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -18,6 +18,7 @@ import io.onedev.commons.utils.ZipUtils;
|
||||
import io.onedev.server.persistence.DefaultPersistManager;
|
||||
import io.onedev.server.persistence.HibernateProperties;
|
||||
import io.onedev.server.persistence.IdManager;
|
||||
import io.onedev.server.persistence.TransactionManager;
|
||||
import io.onedev.server.persistence.dao.Dao;
|
||||
import io.onedev.server.util.validation.EntityValidator;
|
||||
|
||||
@ -31,8 +32,9 @@ public class BackupDatabase extends DefaultPersistManager {
|
||||
@Inject
|
||||
public BackupDatabase(PhysicalNamingStrategy physicalNamingStrategy,
|
||||
HibernateProperties properties, Interceptor interceptor,
|
||||
IdManager idManager, Dao dao, EntityValidator validator) {
|
||||
super(physicalNamingStrategy, properties, interceptor, idManager, dao, validator);
|
||||
IdManager idManager, Dao dao, EntityValidator validator,
|
||||
TransactionManager transactionManager) {
|
||||
super(physicalNamingStrategy, properties, interceptor, idManager, dao, validator, transactionManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -13,6 +13,7 @@ import io.onedev.commons.launcher.bootstrap.Bootstrap;
|
||||
import io.onedev.server.persistence.DefaultPersistManager;
|
||||
import io.onedev.server.persistence.HibernateProperties;
|
||||
import io.onedev.server.persistence.IdManager;
|
||||
import io.onedev.server.persistence.TransactionManager;
|
||||
import io.onedev.server.persistence.dao.Dao;
|
||||
import io.onedev.server.util.validation.EntityValidator;
|
||||
|
||||
@ -26,8 +27,9 @@ public class CheckDataVersion extends DefaultPersistManager {
|
||||
@Inject
|
||||
public CheckDataVersion(PhysicalNamingStrategy physicalNamingStrategy,
|
||||
HibernateProperties properties, Interceptor interceptor,
|
||||
IdManager idManager, Dao dao, EntityValidator validator) {
|
||||
super(physicalNamingStrategy, properties, interceptor, idManager, dao, validator);
|
||||
IdManager idManager, Dao dao, EntityValidator validator,
|
||||
TransactionManager transactionManager) {
|
||||
super(physicalNamingStrategy, properties, interceptor, idManager, dao, validator, transactionManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -14,6 +14,7 @@ import io.onedev.commons.launcher.bootstrap.Bootstrap;
|
||||
import io.onedev.server.persistence.DefaultPersistManager;
|
||||
import io.onedev.server.persistence.HibernateProperties;
|
||||
import io.onedev.server.persistence.IdManager;
|
||||
import io.onedev.server.persistence.TransactionManager;
|
||||
import io.onedev.server.persistence.dao.Dao;
|
||||
import io.onedev.server.util.validation.EntityValidator;
|
||||
|
||||
@ -27,8 +28,9 @@ public class CleanDatabase extends DefaultPersistManager {
|
||||
@Inject
|
||||
public CleanDatabase(PhysicalNamingStrategy physicalNamingStrategy,
|
||||
HibernateProperties properties, Interceptor interceptor,
|
||||
IdManager idManager, Dao dao, EntityValidator validator) {
|
||||
super(physicalNamingStrategy, properties, interceptor, idManager, dao, validator);
|
||||
IdManager idManager, Dao dao, EntityValidator validator,
|
||||
TransactionManager transactionManager) {
|
||||
super(physicalNamingStrategy, properties, interceptor, idManager, dao, validator, transactionManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -10,6 +10,7 @@ import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
|
||||
import io.onedev.server.persistence.DefaultPersistManager;
|
||||
import io.onedev.server.persistence.HibernateProperties;
|
||||
import io.onedev.server.persistence.IdManager;
|
||||
import io.onedev.server.persistence.TransactionManager;
|
||||
import io.onedev.server.persistence.dao.Dao;
|
||||
import io.onedev.server.util.validation.EntityValidator;
|
||||
|
||||
@ -21,8 +22,9 @@ public class DatabaseDialect extends DefaultPersistManager {
|
||||
@Inject
|
||||
public DatabaseDialect(PhysicalNamingStrategy physicalNamingStrategy,
|
||||
HibernateProperties properties, Interceptor interceptor,
|
||||
IdManager idManager, Dao dao, EntityValidator validator) {
|
||||
super(physicalNamingStrategy, properties, interceptor, idManager, dao, validator);
|
||||
IdManager idManager, Dao dao, EntityValidator validator,
|
||||
TransactionManager transactionManager) {
|
||||
super(physicalNamingStrategy, properties, interceptor, idManager, dao, validator, transactionManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -16,6 +16,7 @@ import io.onedev.server.model.User;
|
||||
import io.onedev.server.persistence.DefaultPersistManager;
|
||||
import io.onedev.server.persistence.HibernateProperties;
|
||||
import io.onedev.server.persistence.IdManager;
|
||||
import io.onedev.server.persistence.TransactionManager;
|
||||
import io.onedev.server.persistence.dao.Dao;
|
||||
import io.onedev.server.util.validation.EntityValidator;
|
||||
|
||||
@ -33,8 +34,9 @@ public class ResetAdminPassword extends DefaultPersistManager {
|
||||
@Inject
|
||||
public ResetAdminPassword(PhysicalNamingStrategy physicalNamingStrategy, HibernateProperties properties,
|
||||
Interceptor interceptor, IdManager idManager, Dao dao,
|
||||
EntityValidator validator, UserManager userManager, PasswordService passwordService) {
|
||||
super(physicalNamingStrategy, properties, interceptor, idManager, dao, validator);
|
||||
EntityValidator validator, UserManager userManager, PasswordService passwordService,
|
||||
TransactionManager transactionManager) {
|
||||
super(physicalNamingStrategy, properties, interceptor, idManager, dao, validator, transactionManager);
|
||||
this.userManager = userManager;
|
||||
this.passwordService = passwordService;
|
||||
}
|
||||
|
||||
@ -18,6 +18,7 @@ import io.onedev.commons.utils.ZipUtils;
|
||||
import io.onedev.server.persistence.DefaultPersistManager;
|
||||
import io.onedev.server.persistence.HibernateProperties;
|
||||
import io.onedev.server.persistence.IdManager;
|
||||
import io.onedev.server.persistence.TransactionManager;
|
||||
import io.onedev.server.persistence.dao.Dao;
|
||||
import io.onedev.server.util.validation.EntityValidator;
|
||||
|
||||
@ -31,8 +32,9 @@ public class RestoreDatabase extends DefaultPersistManager {
|
||||
@Inject
|
||||
public RestoreDatabase(PhysicalNamingStrategy physicalNamingStrategy,
|
||||
HibernateProperties properties, Interceptor interceptor,
|
||||
IdManager idManager, Dao dao, EntityValidator validator) {
|
||||
super(physicalNamingStrategy, properties, interceptor, idManager, dao, validator);
|
||||
IdManager idManager, Dao dao, EntityValidator validator,
|
||||
TransactionManager transactionManager) {
|
||||
super(physicalNamingStrategy, properties, interceptor, idManager, dao, validator, transactionManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -32,6 +32,7 @@ import io.onedev.server.migration.MigrationHelper;
|
||||
import io.onedev.server.persistence.DefaultPersistManager;
|
||||
import io.onedev.server.persistence.HibernateProperties;
|
||||
import io.onedev.server.persistence.IdManager;
|
||||
import io.onedev.server.persistence.TransactionManager;
|
||||
import io.onedev.server.persistence.dao.Dao;
|
||||
import io.onedev.server.util.validation.EntityValidator;
|
||||
|
||||
@ -49,8 +50,9 @@ public class Upgrade extends DefaultPersistManager {
|
||||
@Inject
|
||||
public Upgrade(PhysicalNamingStrategy physicalNamingStrategy,
|
||||
HibernateProperties properties, Interceptor interceptor,
|
||||
IdManager idManager, Dao dao, EntityValidator validator, PluginManager pluginManager) {
|
||||
super(physicalNamingStrategy, properties, interceptor, idManager, dao, validator);
|
||||
IdManager idManager, Dao dao, EntityValidator validator, PluginManager pluginManager,
|
||||
TransactionManager transactionManager) {
|
||||
super(physicalNamingStrategy, properties, interceptor, idManager, dao, validator, transactionManager);
|
||||
appName = pluginManager.getProduct().getName();
|
||||
}
|
||||
|
||||
|
||||
@ -136,6 +136,9 @@ public class Build extends AbstractEntity implements Referenceable {
|
||||
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
|
||||
private Collection<BuildDependence> dependents= new ArrayList<>();
|
||||
|
||||
@OneToMany(mappedBy="build", cascade=CascadeType.REMOVE)
|
||||
private Collection<PullRequestBuild> pullRequestBuilds = new ArrayList<>();
|
||||
|
||||
private transient Map<String, List<String>> paramMap;
|
||||
|
||||
private transient Optional<Collection<Long>> fixedIssueNumbers;
|
||||
@ -309,6 +312,14 @@ public class Build extends AbstractEntity implements Referenceable {
|
||||
this.statusMessage = statusMessage;
|
||||
}
|
||||
|
||||
public Collection<PullRequestBuild> getPullRequestBuilds() {
|
||||
return pullRequestBuilds;
|
||||
}
|
||||
|
||||
public void setPullRequestBuilds(Collection<PullRequestBuild> pullRequestBuilds) {
|
||||
this.pullRequestBuilds = pullRequestBuilds;
|
||||
}
|
||||
|
||||
public Map<String, List<String>> getParamMap() {
|
||||
if (paramMap == null) {
|
||||
paramMap = new HashMap<>();
|
||||
|
||||
@ -10,6 +10,7 @@ import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@ -435,7 +436,17 @@ public class Project extends AbstractEntity implements Validatable {
|
||||
}
|
||||
|
||||
public List<RefInfo> getBranches() {
|
||||
return getRefInfos(Constants.R_HEADS);
|
||||
List<RefInfo> refInfos = getRefInfos(Constants.R_HEADS);
|
||||
for (Iterator<RefInfo> it = refInfos.iterator(); it.hasNext();) {
|
||||
RefInfo refInfo = it.next();
|
||||
if (refInfo.getRef().getName().equals(GitUtils.branch2ref(getDefaultBranch()))) {
|
||||
it.remove();
|
||||
refInfos.add(0, refInfo);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return refInfos;
|
||||
}
|
||||
|
||||
public List<RefInfo> getTags() {
|
||||
|
||||
@ -8,7 +8,6 @@ import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
@ -156,7 +155,7 @@ public class PullRequest extends AbstractEntity implements Referenceable, Attach
|
||||
private Collection<PullRequestReview> reviews = new ArrayList<>();
|
||||
|
||||
@OneToMany(mappedBy="request", cascade=CascadeType.REMOVE)
|
||||
private Collection<BuildRequirement> buildRequirements = new ArrayList<>();
|
||||
private Collection<PullRequestBuild> pullRequestBuilds = new ArrayList<>();
|
||||
|
||||
@OneToMany(mappedBy="request", cascade=CascadeType.REMOVE)
|
||||
private Collection<PullRequestComment> comments = new ArrayList<>();
|
||||
@ -343,12 +342,12 @@ public class PullRequest extends AbstractEntity implements Referenceable, Attach
|
||||
sortedUpdates = null;
|
||||
}
|
||||
|
||||
public Collection<BuildRequirement> getBuildRequirements() {
|
||||
return buildRequirements;
|
||||
public Collection<PullRequestBuild> getPullRequestBuilds() {
|
||||
return pullRequestBuilds;
|
||||
}
|
||||
|
||||
public void setBuildRequirements(Collection<BuildRequirement> buildRequirements) {
|
||||
this.buildRequirements = buildRequirements;
|
||||
public void setPullRequestBuilds(Collection<PullRequestBuild> pullRequestBuilds) {
|
||||
this.pullRequestBuilds = pullRequestBuilds;
|
||||
}
|
||||
|
||||
public Collection<PullRequestComment> getComments() {
|
||||
@ -711,15 +710,6 @@ public class PullRequest extends AbstractEntity implements Referenceable, Attach
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public BuildRequirement getBuildRequirement(String jobName, Map<String, List<String>> buildParams) {
|
||||
for (BuildRequirement requirement: getBuildRequirements()) {
|
||||
if (requirement.getJobName().equals(jobName) && requirement.getBuildParams().equals(buildParams))
|
||||
return requirement;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PullRequestReview getReview(User user) {
|
||||
for (PullRequestReview review: getReviews()) {
|
||||
@ -819,8 +809,8 @@ public class PullRequest extends AbstractEntity implements Referenceable, Attach
|
||||
}
|
||||
|
||||
public boolean isAllBuildsSuccessful() {
|
||||
for (BuildRequirement requirement: getBuildRequirements()) {
|
||||
if (requirement.getBuild() == null || requirement.getBuild().getStatus() != Build.Status.SUCCESSFUL)
|
||||
for (PullRequestBuild requirement: getPullRequestBuilds()) {
|
||||
if (requirement.getBuild().getStatus() != Build.Status.SUCCESSFUL)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@ -1,55 +1,28 @@
|
||||
package io.onedev.server.model;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.Lob;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(indexes={@Index(columnList="o_request_id")})
|
||||
public class BuildRequirement extends AbstractEntity {
|
||||
@Table(indexes={@Index(columnList="o_request_id"), @Index(columnList="o_build_id")})
|
||||
public class PullRequestBuild extends AbstractEntity {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final String ATTR_BUILD = "build";
|
||||
|
||||
@Column(nullable=false)
|
||||
private String jobName;
|
||||
|
||||
@Column(nullable=false, length=65535)
|
||||
@Lob
|
||||
private LinkedHashMap<String, List<String>> buildParams = new LinkedHashMap<>();
|
||||
|
||||
|
||||
@ManyToOne(fetch=FetchType.LAZY)
|
||||
@JoinColumn(nullable=false)
|
||||
private PullRequest request;
|
||||
|
||||
@ManyToOne(fetch=FetchType.LAZY)
|
||||
@JoinColumn(nullable=false)
|
||||
private Build build;
|
||||
|
||||
public String getJobName() {
|
||||
return jobName;
|
||||
}
|
||||
|
||||
public void setJobName(String jobName) {
|
||||
this.jobName = jobName;
|
||||
}
|
||||
|
||||
public LinkedHashMap<String, List<String>> getBuildParams() {
|
||||
return buildParams;
|
||||
}
|
||||
|
||||
public void setBuildParams(LinkedHashMap<String, List<String>> buildParams) {
|
||||
this.buildParams = buildParams;
|
||||
}
|
||||
|
||||
public Build getBuild() {
|
||||
return build;
|
||||
}
|
||||
@ -2,6 +2,7 @@ package io.onedev.server.model.support;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@ -258,7 +259,7 @@ public class BranchProtection implements Serializable {
|
||||
if (!ReviewRequirement.fromString(getReviewRequirement()).satisfied(user))
|
||||
return false;
|
||||
|
||||
List<Build> builds = OneDev.getInstance(BuildManager.class).query(project, newObjectId.name());
|
||||
Collection<Build> builds = OneDev.getInstance(BuildManager.class).query(project, newObjectId.name());
|
||||
|
||||
for (JobDependency dependency: getJobDependencies()) {
|
||||
Map<String, List<List<String>>> paramMatrix = new HashMap<>();
|
||||
|
||||
@ -24,6 +24,12 @@ public class KubernetesExecutor extends JobExecutor {
|
||||
logger.info("run_type: " + envVars.get("run_type"));
|
||||
logger.info("deploy_to_production_environment: " + envVars.get("deploy_to_production_environment"));
|
||||
logger.info("production_token: " + envVars.get("production_token"));
|
||||
try {
|
||||
Thread.sleep(10000);
|
||||
} catch (InterruptedException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -169,7 +169,7 @@ public class PullRequestNotificationManager implements PersistListener {
|
||||
mailManager.sendMailAsync(Lists.newArrayList(request.getSubmitter().getEmail()), subject, body);
|
||||
notifiedUsers.add(request.getSubmitter());
|
||||
} else if (event instanceof PullRequestBuildEvent) {
|
||||
Build build = ((PullRequestBuildEvent) event).getBuild();
|
||||
Build build = ((PullRequestBuildEvent) event).getPullRequestBuild().getBuild();
|
||||
if (build.getStatus() == Build.Status.IN_ERROR
|
||||
|| build.getStatus() == Build.Status.FAILED
|
||||
|| build.getStatus() == Build.Status.CANCELLED
|
||||
|
||||
@ -35,7 +35,7 @@ public class DefaultIdManager implements IdManager {
|
||||
CriteriaQuery<Number> query = builder.createQuery(Number.class);
|
||||
Root<?> root = query.from(entityClass);
|
||||
query.select(builder.max(root.get("id")));
|
||||
Number result = dao.getSessionManager().getSession().createQuery(query).getSingleResult();
|
||||
Number result = dao.getSession().createQuery(query).getSingleResult();
|
||||
return result!=null?result.longValue():0;
|
||||
}
|
||||
|
||||
|
||||
@ -81,18 +81,22 @@ public class DefaultPersistManager implements PersistManager {
|
||||
|
||||
protected final StandardServiceRegistry serviceRegistry;
|
||||
|
||||
protected final TransactionManager transactionManager;
|
||||
|
||||
protected volatile SessionFactory sessionFactory;
|
||||
|
||||
@Inject
|
||||
public DefaultPersistManager(PhysicalNamingStrategy physicalNamingStrategy,
|
||||
HibernateProperties properties, Interceptor interceptor,
|
||||
IdManager idManager, Dao dao, EntityValidator validator) {
|
||||
IdManager idManager, Dao dao, EntityValidator validator,
|
||||
TransactionManager transactionManager) {
|
||||
this.physicalNamingStrategy = physicalNamingStrategy;
|
||||
this.properties = properties;
|
||||
this.interceptor = interceptor;
|
||||
this.idManager = idManager;
|
||||
this.dao = dao;
|
||||
this.validator = validator;
|
||||
this.transactionManager = transactionManager;
|
||||
serviceRegistry = new StandardServiceRegistryBuilder().applySettings(properties).build();
|
||||
}
|
||||
|
||||
@ -178,19 +182,16 @@ public class DefaultPersistManager implements PersistManager {
|
||||
|
||||
idManager.init();
|
||||
|
||||
Session session = sessionFactory.openSession();
|
||||
Transaction transaction = session.beginTransaction();
|
||||
try {
|
||||
ModelVersion dataVersion = new ModelVersion();
|
||||
dataVersion.versionColumn = MigrationHelper.getVersion(DatabaseMigrator.class);
|
||||
session.save(dataVersion);
|
||||
session.flush();
|
||||
transaction.commit();
|
||||
} catch (Exception e) {
|
||||
transaction.rollback();
|
||||
} finally {
|
||||
session.close();
|
||||
}
|
||||
transactionManager.run(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
ModelVersion dataVersion = new ModelVersion();
|
||||
dataVersion.versionColumn = MigrationHelper.getVersion(DatabaseMigrator.class);
|
||||
transactionManager.getSession().save(dataVersion);
|
||||
}
|
||||
|
||||
});
|
||||
} else {
|
||||
sessionFactory = metadata.getSessionFactoryBuilder().applyInterceptor(interceptor).build();
|
||||
idManager.init();
|
||||
@ -437,7 +438,7 @@ public class DefaultPersistManager implements PersistManager {
|
||||
@Sessional
|
||||
@Override
|
||||
public void importData(Metadata metadata, File dataDir) {
|
||||
Session session = dao.getSessionManager().getSession();
|
||||
Session session = dao.getSession();
|
||||
List<Class<?>> entityTypes = getEntityTypes(sessionFactory);
|
||||
Collections.reverse(entityTypes);
|
||||
for (Class<?> entityType: entityTypes) {
|
||||
|
||||
@ -3,6 +3,8 @@ package io.onedev.server.persistence;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.hibernate.FlushMode;
|
||||
import org.hibernate.Session;
|
||||
import org.slf4j.Logger;
|
||||
@ -19,7 +21,7 @@ public class DefaultSessionManager implements SessionManager {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DefaultSessionManager.class);
|
||||
|
||||
private final PersistManager persistManager;
|
||||
private final Provider<PersistManager> persistManagerProvider;
|
||||
|
||||
private final ExecutorService executorService;
|
||||
|
||||
@ -31,7 +33,7 @@ public class DefaultSessionManager implements SessionManager {
|
||||
|
||||
@Override
|
||||
protected Session openObject() {
|
||||
Session session = persistManager.getSessionFactory().openSession();
|
||||
Session session = persistManagerProvider.get().getSessionFactory().openSession();
|
||||
// Session is supposed to be able to write only in transactional methods
|
||||
session.setHibernateFlushMode(FlushMode.MANUAL);
|
||||
|
||||
@ -49,8 +51,8 @@ public class DefaultSessionManager implements SessionManager {
|
||||
};
|
||||
|
||||
@Inject
|
||||
public DefaultSessionManager(PersistManager persistManager, ExecutorService executorService) {
|
||||
this.persistManager = persistManager;
|
||||
public DefaultSessionManager(Provider<PersistManager> persistManagerProvider, ExecutorService executorService) {
|
||||
this.persistManagerProvider = persistManagerProvider;
|
||||
this.executorService = executorService;
|
||||
}
|
||||
|
||||
@ -71,7 +73,7 @@ public class DefaultSessionManager implements SessionManager {
|
||||
|
||||
@Override
|
||||
public <T> T call(Callable<T> callable) {
|
||||
if (persistManager.getSessionFactory() != null) {
|
||||
if (persistManagerProvider.get().getSessionFactory() != null) {
|
||||
openSession();
|
||||
try {
|
||||
return callable.call();
|
||||
|
||||
@ -155,10 +155,20 @@ public class DefaultTransactionManager implements TransactionManager {
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionManager getSessionManager() {
|
||||
return sessionManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transaction getTransaction() {
|
||||
return sessionManager.getSession().getTransaction();
|
||||
return getSession().getTransaction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Session getSession() {
|
||||
return sessionManager.getSession();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -18,12 +18,17 @@ package io.onedev.server.persistence;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.Transaction;
|
||||
|
||||
public interface TransactionManager {
|
||||
|
||||
Transaction getTransaction();
|
||||
|
||||
SessionManager getSessionManager();
|
||||
|
||||
Session getSession();
|
||||
|
||||
<T> T call(Callable<T> callable);
|
||||
|
||||
void run(Runnable runnable);
|
||||
|
||||
@ -112,7 +112,7 @@ public abstract class AbstractEntityManager<T extends AbstractEntity> implements
|
||||
}
|
||||
|
||||
protected Session getSession() {
|
||||
return dao.getSessionManager().getSession();
|
||||
return dao.getSession();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package io.onedev.server.persistence.dao;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.criterion.DetachedCriteria;
|
||||
|
||||
import io.onedev.server.model.AbstractEntity;
|
||||
@ -96,4 +97,5 @@ public interface Dao {
|
||||
|
||||
SessionManager getSessionManager();
|
||||
|
||||
Session getSession();
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.hibernate.Criteria;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.criterion.Projections;
|
||||
|
||||
import io.onedev.commons.launcher.loader.ListenerRegistry;
|
||||
@ -37,34 +38,34 @@ public class DefaultDao implements Dao, Serializable {
|
||||
@Sessional
|
||||
@Override
|
||||
public <T extends AbstractEntity> T get(Class<T> entityClass, Long entityId) {
|
||||
return (T) sessionManager.getSession().get(ClassUtils.unproxy(entityClass), entityId);
|
||||
return (T) getSession().get(ClassUtils.unproxy(entityClass), entityId);
|
||||
}
|
||||
|
||||
@Sessional
|
||||
@Override
|
||||
public <T extends AbstractEntity> T load(Class<T> entityClass, Long entityId) {
|
||||
return (T) sessionManager.getSession().load(ClassUtils.unproxy(entityClass), entityId);
|
||||
return (T) getSession().load(ClassUtils.unproxy(entityClass), entityId);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void persist(AbstractEntity entity) {
|
||||
boolean isNew = entity.isNew();
|
||||
sessionManager.getSession().saveOrUpdate(entity);
|
||||
getSession().saveOrUpdate(entity);
|
||||
listenerRegistry.post(new EntityPersisted(entity, isNew));
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void remove(AbstractEntity entity) {
|
||||
sessionManager.getSession().delete(entity);
|
||||
getSession().delete(entity);
|
||||
listenerRegistry.post(new EntityRemoved(entity));
|
||||
}
|
||||
|
||||
@Sessional
|
||||
@Override
|
||||
public <T extends AbstractEntity> List<T> query(EntityCriteria<T> entityCriteria, int firstResult, int maxResults) {
|
||||
Criteria criteria = entityCriteria.getExecutableCriteria(sessionManager.getSession());
|
||||
Criteria criteria = entityCriteria.getExecutableCriteria(getSession());
|
||||
criteria.setFirstResult(firstResult);
|
||||
criteria.setMaxResults(maxResults);
|
||||
return criteria.list();
|
||||
@ -79,7 +80,7 @@ public class DefaultDao implements Dao, Serializable {
|
||||
@Transactional
|
||||
@Override
|
||||
public <T extends AbstractEntity> T find(EntityCriteria<T> entityCriteria) {
|
||||
Criteria criteria = entityCriteria.getExecutableCriteria(sessionManager.getSession());
|
||||
Criteria criteria = entityCriteria.getExecutableCriteria(getSession());
|
||||
criteria.setFirstResult(0);
|
||||
criteria.setMaxResults(1);
|
||||
return (T) criteria.uniqueResult();
|
||||
@ -87,7 +88,7 @@ public class DefaultDao implements Dao, Serializable {
|
||||
|
||||
@Override
|
||||
public <T extends AbstractEntity> int count(EntityCriteria<T> entityCriteria) {
|
||||
Criteria criteria = entityCriteria.getExecutableCriteria(sessionManager.getSession());
|
||||
Criteria criteria = entityCriteria.getExecutableCriteria(getSession());
|
||||
criteria.setProjection(Projections.rowCount());
|
||||
return ((Long) criteria.uniqueResult()).intValue();
|
||||
}
|
||||
@ -107,4 +108,9 @@ public class DefaultDao implements Dao, Serializable {
|
||||
return sessionManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Session getSession() {
|
||||
return sessionManager.getSession();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@ import javax.persistence.criteria.Predicate;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
import io.onedev.server.model.Build;
|
||||
import io.onedev.server.model.BuildRequirement;
|
||||
import io.onedev.server.model.PullRequestBuild;
|
||||
import io.onedev.server.model.Project;
|
||||
import io.onedev.server.model.PullRequest;
|
||||
import io.onedev.server.model.User;
|
||||
@ -22,7 +22,7 @@ public class HasFailedBuildsCriteria extends PullRequestCriteria {
|
||||
public Predicate getPredicate(Project project, Root<PullRequest> root, CriteriaBuilder builder, User user) {
|
||||
From<?, ?> join = root
|
||||
.join(PullRequestConstants.ATTR_BUILDS, JoinType.LEFT)
|
||||
.join(BuildRequirement.ATTR_BUILD, JoinType.LEFT);
|
||||
.join(PullRequestBuild.ATTR_BUILD, JoinType.LEFT);
|
||||
Path<?> status = join.get(Build.STATUS);
|
||||
|
||||
return builder.or(
|
||||
@ -34,7 +34,7 @@ public class HasFailedBuildsCriteria extends PullRequestCriteria {
|
||||
|
||||
@Override
|
||||
public boolean matches(PullRequest request, User user) {
|
||||
for (BuildRequirement build: request.getBuildRequirements()) {
|
||||
for (PullRequestBuild build: request.getPullRequestBuilds()) {
|
||||
if (build.getBuild() != null &&
|
||||
(build.getBuild().getStatus() == Build.Status.IN_ERROR
|
||||
|| build.getBuild().getStatus() == Build.Status.FAILED
|
||||
|
||||
@ -8,7 +8,7 @@ import javax.persistence.criteria.Predicate;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
import io.onedev.server.model.Build;
|
||||
import io.onedev.server.model.BuildRequirement;
|
||||
import io.onedev.server.model.PullRequestBuild;
|
||||
import io.onedev.server.model.Project;
|
||||
import io.onedev.server.model.PullRequest;
|
||||
import io.onedev.server.model.User;
|
||||
@ -22,7 +22,7 @@ public class HasPendingBuildsCriteria extends PullRequestCriteria {
|
||||
public Predicate getPredicate(Project project, Root<PullRequest> root, CriteriaBuilder builder, User user) {
|
||||
From<?, ?> join = root
|
||||
.join(PullRequestConstants.ATTR_BUILDS, JoinType.LEFT)
|
||||
.join(BuildRequirement.ATTR_BUILD, JoinType.LEFT);
|
||||
.join(PullRequestBuild.ATTR_BUILD, JoinType.LEFT);
|
||||
|
||||
Path<?> status = join.get(Build.STATUS);
|
||||
|
||||
@ -35,7 +35,7 @@ public class HasPendingBuildsCriteria extends PullRequestCriteria {
|
||||
|
||||
@Override
|
||||
public boolean matches(PullRequest request, User user) {
|
||||
for (BuildRequirement build: request.getBuildRequirements()) {
|
||||
for (PullRequestBuild build: request.getPullRequestBuilds()) {
|
||||
if (build.getBuild() == null
|
||||
|| build.getBuild().getStatus() == Build.Status.RUNNING
|
||||
|| build.getBuild().getStatus() == Build.Status.QUEUEING
|
||||
|
||||
@ -6,7 +6,7 @@ import java.util.Map;
|
||||
|
||||
public abstract class MatrixRunner<T> {
|
||||
|
||||
private final Map<String, T> params;
|
||||
private final Map<String, T> paramMap;
|
||||
|
||||
private final Map<String, List<T>> paramMatrix;
|
||||
|
||||
@ -14,8 +14,8 @@ public abstract class MatrixRunner<T> {
|
||||
this(new LinkedHashMap<>(), paramMatrix);
|
||||
}
|
||||
|
||||
private MatrixRunner(Map<String, T> params, Map<String, List<T>> paramMatrix) {
|
||||
this.params = params;
|
||||
private MatrixRunner(Map<String, T> paramMap, Map<String, List<T>> paramMatrix) {
|
||||
this.paramMap = paramMap;
|
||||
this.paramMatrix = paramMatrix;
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@ public abstract class MatrixRunner<T> {
|
||||
if (!paramMatrix.isEmpty()) {
|
||||
Map.Entry<String, List<T>> entry = paramMatrix.entrySet().iterator().next();
|
||||
for (T value: entry.getValue()) {
|
||||
Map<String, T> paramsCopy = new LinkedHashMap<>(params);
|
||||
Map<String, T> paramsCopy = new LinkedHashMap<>(paramMap);
|
||||
paramsCopy.put(entry.getKey(), value);
|
||||
Map<String, List<T>> matrixCopy = new LinkedHashMap<>(paramMatrix);
|
||||
matrixCopy.remove(entry.getKey());
|
||||
@ -37,7 +37,7 @@ public abstract class MatrixRunner<T> {
|
||||
}.run();
|
||||
}
|
||||
} else {
|
||||
run(params);
|
||||
run(paramMap);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -33,7 +33,7 @@ onedev.server.codemirror = {
|
||||
onedev.server.codemirror.setMode(cm, modeInfo);
|
||||
},
|
||||
setModeByFileName: function(cm, fileName) {
|
||||
var modeInfo = CodeMirror.findModeByFileName(filePath);
|
||||
var modeInfo = CodeMirror.findModeByFileName(fileName);
|
||||
if (modeInfo)
|
||||
onedev.server.codemirror.setMode(cm, modeInfo);
|
||||
},
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
-ms-overflow-style: none;
|
||||
touch-action: auto;
|
||||
-ms-touch-action: auto;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@ -39,6 +39,7 @@ import org.apache.wicket.model.LoadableDetachableModel;
|
||||
import org.apache.wicket.model.Model;
|
||||
import org.apache.wicket.model.PropertyModel;
|
||||
import org.apache.wicket.request.mapper.parameter.PageParameters;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -329,10 +330,11 @@ public abstract class BuildListPanel extends Panel {
|
||||
|
||||
@Override
|
||||
public void populateItem(Item<ICellPopulator<Build>> cellItem, String componentId, IModel<Build> rowModel) {
|
||||
Fragment fragment = new Fragment(componentId, "statusFrag", BuildListPanel.this);
|
||||
fragment.add(new BuildStatusIcon("icon", rowModel));
|
||||
|
||||
Long buildId = rowModel.getObject().getId();
|
||||
|
||||
Fragment fragment = new Fragment(componentId, "statusFrag", BuildListPanel.this);
|
||||
fragment.add(new BuildStatusIcon("icon", buildId, true));
|
||||
|
||||
fragment.add(new Label("label", new AbstractReadOnlyModel<String>() {
|
||||
|
||||
@Override
|
||||
@ -373,7 +375,7 @@ public abstract class BuildListPanel extends Panel {
|
||||
return getProject();
|
||||
}
|
||||
|
||||
}, build.getCommitHash(), build.getJobName());
|
||||
}, ObjectId.fromString(build.getCommitHash()), build.getJobName());
|
||||
link.add(new Label("label", build.getJobName()));
|
||||
fragment.add(link);
|
||||
cellItem.add(fragment);
|
||||
|
||||
@ -23,6 +23,7 @@ import org.apache.wicket.model.LoadableDetachableModel;
|
||||
import org.apache.wicket.model.Model;
|
||||
import org.apache.wicket.request.mapper.parameter.PageParameters;
|
||||
import org.apache.wicket.util.time.Duration;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
|
||||
import io.onedev.server.OneDev;
|
||||
@ -118,7 +119,7 @@ public abstract class BuildSidePanel extends Panel {
|
||||
return getProject();
|
||||
}
|
||||
|
||||
}, getBuild().getCommitHash(), getBuild().getJobName());
|
||||
}, ObjectId.fromString(getBuild().getCommitHash()), getBuild().getJobName());
|
||||
jobLink.add(new Label("label", getBuild().getJobName()));
|
||||
general.add(jobLink);
|
||||
|
||||
|
||||
@ -1,12 +0,0 @@
|
||||
<wicket:panel>
|
||||
<table class="build-status-list">
|
||||
<tr wicket:id="requirements">
|
||||
<td class="status">
|
||||
<span wicket:id="icon"></span> <span wicket:id="name"></span>
|
||||
</td>
|
||||
<td class="title">
|
||||
<a wicket:id="title"><span wicket:id="label"></span></a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</wicket:panel>
|
||||
@ -1,144 +0,0 @@
|
||||
package io.onedev.server.web.component.build.status;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.wicket.behavior.AttributeAppender;
|
||||
import org.apache.wicket.event.IEvent;
|
||||
import org.apache.wicket.markup.ComponentTag;
|
||||
import org.apache.wicket.markup.head.CssHeaderItem;
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
import org.apache.wicket.markup.html.WebMarkupContainer;
|
||||
import org.apache.wicket.markup.html.basic.Label;
|
||||
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
|
||||
import org.apache.wicket.markup.html.link.Link;
|
||||
import org.apache.wicket.markup.html.list.ListItem;
|
||||
import org.apache.wicket.markup.html.list.ListView;
|
||||
import org.apache.wicket.markup.html.panel.GenericPanel;
|
||||
import org.apache.wicket.model.AbstractReadOnlyModel;
|
||||
import org.apache.wicket.model.IModel;
|
||||
import org.apache.wicket.model.LoadableDetachableModel;
|
||||
|
||||
import io.onedev.server.model.Build;
|
||||
import io.onedev.server.model.PullRequest;
|
||||
import io.onedev.server.model.BuildRequirement;
|
||||
import io.onedev.server.web.page.project.builds.detail.BuildLogPage;
|
||||
import io.onedev.server.web.websocket.PageDataChanged;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class BuildRequirementListPanel extends GenericPanel<PullRequest> {
|
||||
|
||||
public BuildRequirementListPanel(String id, IModel<PullRequest> model) {
|
||||
super(id, model);
|
||||
}
|
||||
|
||||
private PullRequest getPullRequest() {
|
||||
return getModelObject();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(IEvent<?> event) {
|
||||
super.onEvent(event);
|
||||
|
||||
if (event.getPayload() instanceof PageDataChanged && isVisibleInHierarchy()) {
|
||||
PageDataChanged pageDataChanged = (PageDataChanged) event.getPayload();
|
||||
pageDataChanged.getHandler().add(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
|
||||
add(new ListView<BuildRequirement>("requirements", new LoadableDetachableModel<List<BuildRequirement>>() {
|
||||
|
||||
@Override
|
||||
protected List<BuildRequirement> load() {
|
||||
List<BuildRequirement> requirements = new ArrayList<>(getPullRequest().getBuildRequirements());
|
||||
List<String> jobNames = getPullRequest().getTargetProject().getJobNames();
|
||||
Collections.sort(requirements, new Comparator<BuildRequirement>() {
|
||||
|
||||
@Override
|
||||
public int compare(BuildRequirement o1, BuildRequirement o2) {
|
||||
int index1 = jobNames.indexOf(o1.getJobName());
|
||||
int index2 = jobNames.indexOf(o2.getJobName());
|
||||
if (index1 != index2)
|
||||
return index1 - index2;
|
||||
else if (!o1.getJobName().equals(o2.getJobName()))
|
||||
return o1.getJobName().compareTo(o2.getJobName());
|
||||
else if (o1.getBuild() != null && o2.getBuild() != null)
|
||||
return (int) (o1.getBuild().getNumber() - o2.getBuild().getNumber());
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
});
|
||||
return requirements;
|
||||
}
|
||||
|
||||
}) {
|
||||
|
||||
@Override
|
||||
protected void populateItem(ListItem<BuildRequirement> item) {
|
||||
BuildRequirement requirement = item.getModelObject();
|
||||
|
||||
if (requirement.getBuild() != null) {
|
||||
item.add(new BuildStatusIcon("icon", new AbstractReadOnlyModel<Build>() {
|
||||
|
||||
@Override
|
||||
public Build getObject() {
|
||||
return item.getModelObject().getBuild();
|
||||
}
|
||||
|
||||
}));
|
||||
item.add(new Label("name", requirement.getBuild().getStatus().getDisplayName()));
|
||||
|
||||
Link<Void> link = new BookmarkablePageLink<Void>("title", BuildLogPage.class,
|
||||
BuildLogPage.paramsOf(requirement.getBuild(), null));
|
||||
StringBuilder builder = new StringBuilder("#" + requirement.getBuild().getNumber());
|
||||
if (requirement.getBuild().getVersion() != null)
|
||||
builder.append(" (" + requirement.getBuild().getVersion() + ")");
|
||||
builder.append(" : ").append(requirement.getBuild().getJobName());
|
||||
link.add(new Label("label", builder.toString()));
|
||||
item.add(link);
|
||||
} else {
|
||||
WebMarkupContainer icon = new WebMarkupContainer("icon");
|
||||
icon.add(AttributeAppender.append("class", "build-status build-status-pending fa fa-fw"));
|
||||
icon.add(AttributeAppender.append("title", "Build is pending"));
|
||||
item.add(icon);
|
||||
item.add(new Label("name", "Pending"));
|
||||
|
||||
WebMarkupContainer titleLink = new WebMarkupContainer("title") {
|
||||
|
||||
@Override
|
||||
protected void onComponentTag(ComponentTag tag) {
|
||||
super.onComponentTag(tag);
|
||||
tag.setName("span");
|
||||
}
|
||||
|
||||
};
|
||||
titleLink.add(new Label("label", requirement.getJobName()));
|
||||
item.add(titleLink);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
setOutputMarkupId(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onConfigure() {
|
||||
super.onConfigure();
|
||||
setVisible(!getPullRequest().getBuildRequirements().isEmpty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderHead(IHeaderResponse response) {
|
||||
super.renderHead(response);
|
||||
response.render(CssHeaderItem.forReference(new BuildStatusCssResourceReference()));
|
||||
}
|
||||
|
||||
}
|
||||
@ -2,16 +2,19 @@ package io.onedev.server.web.component.build.status;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
|
||||
import org.apache.wicket.markup.ComponentTag;
|
||||
import org.apache.wicket.markup.head.CssHeaderItem;
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
import org.apache.wicket.markup.html.WebMarkupContainer;
|
||||
import org.apache.wicket.markup.html.panel.GenericPanel;
|
||||
import org.apache.wicket.model.IModel;
|
||||
import org.apache.wicket.model.LoadableDetachableModel;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import io.onedev.server.OneDev;
|
||||
import io.onedev.server.entitymanager.BuildManager;
|
||||
import io.onedev.server.model.Build;
|
||||
import io.onedev.server.model.Build.Status;
|
||||
import io.onedev.server.web.behavior.WebSocketObserver;
|
||||
@ -19,8 +22,23 @@ import io.onedev.server.web.behavior.WebSocketObserver;
|
||||
@SuppressWarnings("serial")
|
||||
public class BuildStatusIcon extends GenericPanel<Build> {
|
||||
|
||||
public BuildStatusIcon(String id, IModel<Build> model) {
|
||||
super(id, model);
|
||||
private final Long buildId;
|
||||
|
||||
private final boolean withTooltip;
|
||||
|
||||
public BuildStatusIcon(String id, Long buildId, boolean withTooltip) {
|
||||
super(id);
|
||||
|
||||
this.buildId = buildId;
|
||||
setModel(new LoadableDetachableModel<Build>() {
|
||||
|
||||
@Override
|
||||
protected Build load() {
|
||||
return OneDev.getInstance(BuildManager.class).load(buildId);
|
||||
}
|
||||
|
||||
});
|
||||
this.withTooltip = withTooltip;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -35,27 +53,29 @@ public class BuildStatusIcon extends GenericPanel<Build> {
|
||||
|
||||
Build build = getModelObject();
|
||||
|
||||
String cssClass = "fa fa-fw build-status build-status-" + build.getStatus().name().toLowerCase();
|
||||
if (build.getStatus() == Status.RUNNING)
|
||||
Build.Status status = build.getStatus();
|
||||
String cssClass = "fa fa-fw build-status build-status-" + status.name().toLowerCase();
|
||||
if (status == Status.RUNNING)
|
||||
cssClass += " fa-spin";
|
||||
|
||||
String title;
|
||||
|
||||
if (build.getStatus() == Status.WAITING)
|
||||
title = "Waiting for completion of dependency builds";
|
||||
else if (build.getStatus() == Status.QUEUEING)
|
||||
title = "Build is being queued due to limited capacity";
|
||||
else
|
||||
title = "Build is " + build.getStatus().getDisplayName().toLowerCase();
|
||||
if (withTooltip) {
|
||||
String title;
|
||||
|
||||
if (status == Status.WAITING)
|
||||
title = "Waiting for completion of dependency builds";
|
||||
else if (status == Status.QUEUEING)
|
||||
title = "Queued due to limited capacity";
|
||||
else
|
||||
title = StringUtils.capitalize(status.getDisplayName().toLowerCase());
|
||||
|
||||
tag.put("title", title);
|
||||
}
|
||||
|
||||
tag.put("class", cssClass);
|
||||
tag.put("title", title);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Long buildId = getModelObject().getId();
|
||||
|
||||
add(new WebSocketObserver() {
|
||||
|
||||
@Override
|
||||
@ -77,7 +97,7 @@ public class BuildStatusIcon extends GenericPanel<Build> {
|
||||
|
||||
setOutputMarkupPlaceholderTag(true);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void renderHead(IHeaderResponse response) {
|
||||
super.renderHead(response);
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package io.onedev.server.web.component.build.status;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.wicket.Component;
|
||||
import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
|
||||
@ -26,14 +25,14 @@ import io.onedev.server.web.component.link.DropdownLink;
|
||||
import io.onedev.server.web.websocket.PageDataChanged;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public abstract class CommitStatusPanel extends GenericPanel<List<Build>> {
|
||||
public abstract class CommitStatusPanel extends GenericPanel<Collection<Build>> {
|
||||
|
||||
public CommitStatusPanel(String id) {
|
||||
super(id);
|
||||
setModel(new LoadableDetachableModel<List<Build>>() {
|
||||
setModel(new LoadableDetachableModel<Collection<Build>>() {
|
||||
|
||||
@Override
|
||||
protected List<Build> load() {
|
||||
protected Collection<Build> load() {
|
||||
return OneDev.getInstance(BuildManager.class).query(getProject(), getCommitId().name());
|
||||
}
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<table class="build-status-list">
|
||||
<tr wicket:id="builds">
|
||||
<td class="status">
|
||||
<span wicket:id="icon"></span> <span wicket:id="name"></span>
|
||||
<span wicket:id="icon"></span>
|
||||
</td>
|
||||
<td class="title">
|
||||
<a wicket:id="title"><span wicket:id="label"></span></a>
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package io.onedev.server.web.component.build.status;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
@ -14,39 +16,21 @@ import org.apache.wicket.markup.html.panel.GenericPanel;
|
||||
import org.apache.wicket.model.IModel;
|
||||
import org.apache.wicket.model.LoadableDetachableModel;
|
||||
|
||||
import edu.emory.mathcs.backport.java.util.Collections;
|
||||
import io.onedev.server.model.Build;
|
||||
import io.onedev.server.web.page.project.builds.detail.BuildLogPage;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class StatusListPanel extends GenericPanel<List<Build>> {
|
||||
public class StatusListPanel extends GenericPanel<Collection<Build>> {
|
||||
|
||||
public StatusListPanel(String id, IModel<List<Build>> model) {
|
||||
public StatusListPanel(String id, IModel<Collection<Build>> model) {
|
||||
super(id, model);
|
||||
|
||||
add(new ListView<Build>("builds", new LoadableDetachableModel<List<Build>>() {
|
||||
|
||||
@Override
|
||||
protected List<Build> load() {
|
||||
List<Build> builds = model.getObject();
|
||||
if (!builds.isEmpty()) {
|
||||
List<String> jobNames = builds.iterator().next().getProject().getJobNames();
|
||||
Collections.sort(builds, new Comparator<Build>() {
|
||||
|
||||
@Override
|
||||
public int compare(Build o1, Build o2) {
|
||||
int index1 = jobNames.indexOf(o1.getJobName());
|
||||
int index2 = jobNames.indexOf(o2.getJobName());
|
||||
if (index1 != index2)
|
||||
return index1 - index2;
|
||||
else if (!o1.getJobName().equals(o2.getJobName()))
|
||||
return o1.getJobName().compareTo(o2.getJobName());
|
||||
else
|
||||
return (int) (o1.getNumber() - o2.getNumber());
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
List<Build> builds = new ArrayList<>(model.getObject());
|
||||
builds.sort(Comparator.comparing(Build::getNumber));
|
||||
return builds;
|
||||
}
|
||||
|
||||
@ -54,11 +38,10 @@ public class StatusListPanel extends GenericPanel<List<Build>> {
|
||||
|
||||
@Override
|
||||
protected void populateItem(ListItem<Build> item) {
|
||||
item.add(new BuildStatusIcon("icon", item.getModel()));
|
||||
item.add(new Label("name", item.getModel().getObject().getStatus().getDisplayName()));
|
||||
|
||||
Build build = item.getModelObject();
|
||||
|
||||
item.add(new BuildStatusIcon("icon", build.getId(), true));
|
||||
|
||||
Link<Void> buildLink = new BookmarkablePageLink<Void>("title",
|
||||
BuildLogPage.class, BuildLogPage.paramsOf(build, null));
|
||||
|
||||
|
||||
@ -1,11 +1,17 @@
|
||||
.build-status {
|
||||
font-size: 16px;
|
||||
}
|
||||
.build-status-running {
|
||||
font-size: 14px;
|
||||
}
|
||||
.build-status-successful:before {
|
||||
content: "\f00c";
|
||||
content: "\f058";
|
||||
}
|
||||
.build-status-in_error:before {
|
||||
content: "\f071";
|
||||
content: "\f06a";
|
||||
}
|
||||
.build-status-failed:before {
|
||||
content: "\f00d";
|
||||
content: "\f057";
|
||||
}
|
||||
.build-status-cancelled:before {
|
||||
content: "\f05e";
|
||||
@ -17,10 +23,10 @@
|
||||
content: "\f1ce";
|
||||
}
|
||||
.build-status-waiting:before {
|
||||
content: "\f04c";
|
||||
content: "\f28c";
|
||||
}
|
||||
.build-status-queueing:before {
|
||||
content: "\f254";
|
||||
content: "\f192";
|
||||
}
|
||||
.build-status-successful {
|
||||
color: #06BC06 !important;
|
||||
@ -43,6 +49,15 @@
|
||||
.build-status-list {
|
||||
width: auto;
|
||||
}
|
||||
.build-status-list>tbody>tr>td {
|
||||
padding: 4px 8px;
|
||||
.build-status-list>tbody>tr>td.status {
|
||||
padding: 4px 4px 4px 0;
|
||||
}
|
||||
.build-status-list>tbody>tr>td.title {
|
||||
padding: 4px 0 4px 4px;
|
||||
}
|
||||
.floating>.content>.build-status-list>tbody>tr>td.status {
|
||||
padding-left: 8px;
|
||||
}
|
||||
.floating>.content>.build-status-list>tbody>tr>td.title {
|
||||
padding-right: 8px;
|
||||
}
|
||||
@ -5,6 +5,7 @@ import org.apache.wicket.markup.html.link.BookmarkablePageLink;
|
||||
import org.apache.wicket.model.IModel;
|
||||
import org.apache.wicket.request.mapper.parameter.PageParameters;
|
||||
import org.eclipse.jgit.lib.FileMode;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
|
||||
import io.onedev.server.ci.CISpec;
|
||||
import io.onedev.server.ci.job.Job;
|
||||
@ -19,14 +20,14 @@ public class JobLink extends BookmarkablePageLink<Void> {
|
||||
|
||||
private final IModel<Project> projectModel;
|
||||
|
||||
private final String revision;
|
||||
private final ObjectId commitId;
|
||||
|
||||
private final String jobName;
|
||||
|
||||
public JobLink(String id, IModel<Project> projectModel, String revision, String jobName) {
|
||||
public JobLink(String id, IModel<Project> projectModel, ObjectId commitId, String jobName) {
|
||||
super(id, ProjectBlobPage.class);
|
||||
this.projectModel = projectModel;
|
||||
this.revision = revision;
|
||||
this.commitId = commitId;
|
||||
this.jobName = jobName;
|
||||
}
|
||||
|
||||
@ -52,7 +53,7 @@ public class JobLink extends BookmarkablePageLink<Void> {
|
||||
@Override
|
||||
public PageParameters getPageParameters() {
|
||||
ProjectBlobPage.State state = new ProjectBlobPage.State();
|
||||
state.blobIdent = new BlobIdent(revision, CISpec.BLOB_PATH, FileMode.REGULAR_FILE.getBits());
|
||||
state.blobIdent = new BlobIdent(commitId.name(), CISpec.BLOB_PATH, FileMode.REGULAR_FILE.getBits());
|
||||
state.position = CISpecRendererProvider.getPosition(Job.SELECTION_PREFIX + jobName);
|
||||
return ProjectBlobPage.paramsOf(projectModel.getObject(), state);
|
||||
}
|
||||
|
||||
@ -0,0 +1,19 @@
|
||||
<wicket:panel>
|
||||
<div class="commit-jobs">
|
||||
<div wicket:id="jobs" class="job">
|
||||
<div class="head clearfix">
|
||||
<a wicket:id="name" class="name pull-left"><span wicket:id="label"></span></a>
|
||||
<span class="actions pull-right">
|
||||
<a wicket:id="list" class="list" title="Show builds in list"><i class="fa fa-list-ul"></i></a>
|
||||
<a wicket:id="run" class="run" title="Run this job"><i class="fa fa-play-circle"></i></a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="body">
|
||||
<wicket:container wicket:id="builds">
|
||||
<a wicket:id="build" class="build"><span wicket:id="status"></span></a>
|
||||
</wicket:container>
|
||||
<div wicket:id="noBuilds" class="no-builds">No builds</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</wicket:panel>
|
||||
@ -0,0 +1,294 @@
|
||||
package io.onedev.server.web.component.job.commit;
|
||||
|
||||
import static io.onedev.server.search.entity.EntityQuery.quote;
|
||||
import static io.onedev.server.search.entity.build.BuildQuery.getRuleName;
|
||||
import static io.onedev.server.search.entity.build.BuildQueryLexer.And;
|
||||
import static io.onedev.server.search.entity.build.BuildQueryLexer.Is;
|
||||
import static io.onedev.server.util.BuildConstants.FIELD_COMMIT;
|
||||
import static io.onedev.server.util.BuildConstants.FIELD_JOB;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.wicket.ajax.AjaxRequestTarget;
|
||||
import org.apache.wicket.ajax.markup.html.AjaxLink;
|
||||
import org.apache.wicket.behavior.AttributeAppender;
|
||||
import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
|
||||
import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
|
||||
import org.apache.wicket.markup.html.WebMarkupContainer;
|
||||
import org.apache.wicket.markup.html.basic.Label;
|
||||
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
|
||||
import org.apache.wicket.markup.html.link.Link;
|
||||
import org.apache.wicket.markup.html.list.ListItem;
|
||||
import org.apache.wicket.markup.html.list.ListView;
|
||||
import org.apache.wicket.markup.html.panel.Panel;
|
||||
import org.apache.wicket.markup.repeater.RepeatingView;
|
||||
import org.apache.wicket.model.AbstractReadOnlyModel;
|
||||
import org.apache.wicket.model.IModel;
|
||||
import org.apache.wicket.model.LoadableDetachableModel;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import edu.emory.mathcs.backport.java.util.Collections;
|
||||
import io.onedev.server.OneDev;
|
||||
import io.onedev.server.ci.CISpec;
|
||||
import io.onedev.server.ci.job.Job;
|
||||
import io.onedev.server.ci.job.JobManager;
|
||||
import io.onedev.server.ci.job.param.JobParam;
|
||||
import io.onedev.server.entitymanager.BuildManager;
|
||||
import io.onedev.server.model.Build;
|
||||
import io.onedev.server.model.Build.Status;
|
||||
import io.onedev.server.model.Project;
|
||||
import io.onedev.server.security.SecurityUtils;
|
||||
import io.onedev.server.util.inputspec.InputContext;
|
||||
import io.onedev.server.util.inputspec.InputSpec;
|
||||
import io.onedev.server.web.behavior.WebSocketObserver;
|
||||
import io.onedev.server.web.component.beaneditmodal.BeanEditModalPanel;
|
||||
import io.onedev.server.web.component.build.status.BuildStatusIcon;
|
||||
import io.onedev.server.web.component.job.JobLink;
|
||||
import io.onedev.server.web.page.base.BasePage;
|
||||
import io.onedev.server.web.page.project.builds.ProjectBuildsPage;
|
||||
import io.onedev.server.web.page.project.builds.detail.BuildLogPage;
|
||||
import io.onedev.server.web.util.QueryPosition;
|
||||
import io.onedev.server.web.websocket.WebSocketManager;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class CommitJobsPanel extends Panel {
|
||||
|
||||
private final IModel<Project> projectModel;
|
||||
|
||||
private final ObjectId commitId;
|
||||
|
||||
private final IModel<List<Build>> buildsModel = new LoadableDetachableModel<List<Build>>() {
|
||||
|
||||
@Override
|
||||
protected List<Build> load() {
|
||||
List<Build> builds = new ArrayList<>(OneDev.getInstance(BuildManager.class).query(getProject(), commitId.name()));
|
||||
Collections.sort(builds);
|
||||
return builds;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
public CommitJobsPanel(String id, IModel<Project> projectModel, ObjectId commitId) {
|
||||
super(id);
|
||||
this.projectModel = projectModel;
|
||||
this.commitId = commitId;
|
||||
}
|
||||
|
||||
private Project getProject() {
|
||||
return projectModel.getObject();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
|
||||
RepeatingView jobsView = new RepeatingView("jobs");
|
||||
CISpec ciSpec = getProject().getCISpec(commitId);
|
||||
if (ciSpec != null) {
|
||||
for (Job job: ciSpec.getSortedJobs()) {
|
||||
String query = ""
|
||||
+ quote(FIELD_COMMIT) + " " + getRuleName(Is) + " " + quote(commitId.name())
|
||||
+ " " + getRuleName(And) + " "
|
||||
+ quote(FIELD_JOB) + " " + getRuleName(Is) + " " + quote(job.getName());
|
||||
|
||||
WebMarkupContainer jobContainer = new WebMarkupContainer(jobsView.newChildId());
|
||||
jobsView.add(jobContainer);
|
||||
|
||||
Link<Void> jobLink = new JobLink("name", projectModel, commitId, job.getName());
|
||||
jobLink.add(new Label("label", job.getName()));
|
||||
jobContainer.add(jobLink);
|
||||
|
||||
jobContainer.add(new BookmarkablePageLink<Void>("list", ProjectBuildsPage.class,
|
||||
ProjectBuildsPage.paramsOf(getProject(), query, 0)));
|
||||
|
||||
jobContainer.add(new AjaxLink<Void>("run") {
|
||||
|
||||
@Override
|
||||
public void onClick(AjaxRequestTarget target) {
|
||||
if (!job.getParamSpecs().isEmpty()) {
|
||||
Serializable paramBean;
|
||||
try {
|
||||
paramBean = JobParam.defineBeanClass(job.getParamSpecs()).newInstance();
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
new ParamEditModalPanel(target, paramBean) {
|
||||
|
||||
@Override
|
||||
protected void onSave(AjaxRequestTarget target, Serializable bean) {
|
||||
Map<String, List<String>> paramMap = JobParam.getParamMap(
|
||||
job, bean, job.getParamSpecMap().keySet());
|
||||
Build build = OneDev.getInstance(JobManager.class).submit(getProject(),
|
||||
commitId.name(), job.getName(), paramMap);
|
||||
setResponsePage(BuildLogPage.class, BuildLogPage.paramsOf(build, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getInputNames() {
|
||||
return new ArrayList<>(job.getParamSpecMap().keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputSpec getInputSpec(String inputName) {
|
||||
return Preconditions.checkNotNull(job.getParamSpecMap().get(inputName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateName(String inputName) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
};
|
||||
} else {
|
||||
Build build = OneDev.getInstance(JobManager.class).submit(getProject(), commitId.name(),
|
||||
job.getName(), new HashMap<>());
|
||||
setResponsePage(BuildLogPage.class, BuildLogPage.paramsOf(build, null));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onConfigure() {
|
||||
super.onConfigure();
|
||||
setVisible(SecurityUtils.canWriteCode(getProject().getFacade()));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
IModel<List<Build>> jobBuildsModel = new LoadableDetachableModel<List<Build>>() {
|
||||
|
||||
@Override
|
||||
protected List<Build> load() {
|
||||
return buildsModel.getObject()
|
||||
.stream()
|
||||
.filter(it->it.getJobName().equals(job.getName()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
jobContainer.add(new ListView<Build>("builds", jobBuildsModel) {
|
||||
|
||||
@Override
|
||||
protected void populateItem(ListItem<Build> item) {
|
||||
Build build = item.getModelObject();
|
||||
|
||||
QueryPosition position = new QueryPosition(query, getList().size(), item.getIndex());
|
||||
Link<Void> link = new BookmarkablePageLink<Void>("build", BuildLogPage.class,
|
||||
BuildLogPage.paramsOf(build, position));
|
||||
link.add(new BuildStatusIcon("status", build.getId(), false) {
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
add(AttributeAppender.append("title", new AbstractReadOnlyModel<String>() {
|
||||
|
||||
@Override
|
||||
public String getObject() {
|
||||
Build build = getModelObject();
|
||||
StringBuilder title = new StringBuilder("Build #" + build.getNumber());
|
||||
if (build.getVersion() != null)
|
||||
title.append(" (").append(build.getVersion()).append(")");
|
||||
title.append(" is ");
|
||||
if (build.getStatus() == Status.WAITING)
|
||||
title.append("waiting for completion of dependency builds");
|
||||
else if (build.getStatus() == Status.QUEUEING)
|
||||
title.append("queued due to limited capacity");
|
||||
else
|
||||
title.append(build.getStatus().getDisplayName().toLowerCase());
|
||||
|
||||
return title.append(", click for details").toString();
|
||||
}
|
||||
|
||||
}));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
item.add(link);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
jobContainer.add(new WebMarkupContainer("noBuilds") {
|
||||
|
||||
@Override
|
||||
protected void onConfigure() {
|
||||
super.onConfigure();
|
||||
setVisible(jobBuildsModel.getObject().isEmpty());
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
add(jobsView);
|
||||
|
||||
add(new WebSocketObserver() {
|
||||
|
||||
@Override
|
||||
public void onObservableChanged(IPartialPageRequestHandler handler, String observable) {
|
||||
handler.add(component);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionOpened(IPartialPageRequestHandler handler) {
|
||||
handler.add(component);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getObservables() {
|
||||
return Sets.newHashSet("commit-builds:" + getProject().getId() + ":" + commitId.name());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
setOutputMarkupId(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderHead(IHeaderResponse response) {
|
||||
super.renderHead(response);
|
||||
response.render(JavaScriptHeaderItem.forReference(new CommitJobsResourceReference()));
|
||||
String script = String.format("onedev.server.commitJobs.onDomReady('%s');", getMarkupId());
|
||||
response.render(OnDomReadyHeaderItem.forScript(script));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onConfigure() {
|
||||
super.onConfigure();
|
||||
CISpec ciSpec = getProject().getCISpec(commitId);
|
||||
setVisible(ciSpec != null && !ciSpec.getJobs().isEmpty());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAfterRender() {
|
||||
OneDev.getInstance(WebSocketManager.class).notifyObserverChange((BasePage) getPage());
|
||||
super.onAfterRender();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetach() {
|
||||
projectModel.detach();
|
||||
buildsModel.detach();
|
||||
super.onDetach();
|
||||
}
|
||||
|
||||
private abstract class ParamEditModalPanel extends BeanEditModalPanel implements InputContext {
|
||||
|
||||
public ParamEditModalPanel(AjaxRequestTarget target, Serializable bean) {
|
||||
super(target, bean);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package io.onedev.server.web.component.job.commit;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.wicket.markup.head.CssHeaderItem;
|
||||
import org.apache.wicket.markup.head.HeaderItem;
|
||||
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
|
||||
|
||||
import io.onedev.server.web.asset.perfectscrollbar.PerfectScrollbarResourceReference;
|
||||
import io.onedev.server.web.page.base.BaseDependentCssResourceReference;
|
||||
import io.onedev.server.web.page.base.BaseDependentResourceReference;
|
||||
|
||||
public class CommitJobsResourceReference extends BaseDependentResourceReference {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public CommitJobsResourceReference() {
|
||||
super(CommitJobsResourceReference.class, "commit-jobs.js");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HeaderItem> getDependencies() {
|
||||
List<HeaderItem> dependencies = super.getDependencies();
|
||||
dependencies.add(JavaScriptHeaderItem.forReference(new PerfectScrollbarResourceReference()));
|
||||
dependencies.add(CssHeaderItem.forReference(new BaseDependentCssResourceReference(
|
||||
CommitJobsResourceReference.class, "commit-jobs.css")));
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
.commit-jobs {
|
||||
white-space: nowrap;
|
||||
}
|
||||
.commit-jobs>.job {
|
||||
display: inline-block;
|
||||
margin-right: 20px;
|
||||
border: 1px solid #BBB;
|
||||
border-radius: 4px;
|
||||
width: 200px;
|
||||
}
|
||||
.commit-jobs>.job:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
.commit-jobs>.job>.head {
|
||||
padding: 4px 8px;
|
||||
border-bottom: 1px solid #D8D8D8;
|
||||
vertical-align: middle;
|
||||
font-size: 16px;
|
||||
background: #F9F9F9;
|
||||
border-radius: 4px 4px 0 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
.commit-jobs>.job>.head>.actions a {
|
||||
color: #666;
|
||||
margin: 0 0 0 8px;
|
||||
}
|
||||
.commit-jobs>.job>.head>.actions a.run {
|
||||
line-height: 16px;
|
||||
font-size: 18px;
|
||||
}
|
||||
.commit-jobs>.job>.body {
|
||||
height: 75px;
|
||||
padding: 8px 8px 0 8px;
|
||||
white-space: normal;
|
||||
}
|
||||
.commit-jobs>.job>.body .build-status {
|
||||
margin-bottom: 8px;
|
||||
font-size: 18px;
|
||||
}
|
||||
.commit-jobs>.job>.body .build-status-running {
|
||||
font-size: 16px;
|
||||
}
|
||||
.commit-jobs>.job>.body>.no-builds {
|
||||
font-size: 16px;
|
||||
font-style: italic;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
onedev.server.commitJobs = {
|
||||
onDomReady: function(containerId) {
|
||||
$("#" + containerId + ">.commit-jobs>.job>.body").each(function() {
|
||||
var ps = new PerfectScrollbar(this);
|
||||
$(window).resize(function() {
|
||||
ps.update();
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
@ -212,7 +212,7 @@ class ParamListEditPanel extends PropertyEditor<List<Serializable>> {
|
||||
if (param.getValuesProvider() instanceof SpecifiedValues) {
|
||||
SpecifiedValues specifiedValues = (SpecifiedValues) param.getValuesProvider();
|
||||
try {
|
||||
JobParam.validateValues(specifiedValues.getValues());
|
||||
JobParam.validateParamValues(specifiedValues.getValues());
|
||||
} catch (ValidationException e) {
|
||||
RepeatingView paramsView = (RepeatingView) get("params");
|
||||
paramsView.get(index).get("values").error(e.getMessage());
|
||||
|
||||
@ -12,6 +12,6 @@
|
||||
.script-support .CodeMirror-scroll {
|
||||
min-height: 120px;
|
||||
}
|
||||
.property.viewer .CodeMirror .CodeMirror-cursor {
|
||||
.property-viewer .CodeMirror .CodeMirror-cursor {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
@ -48,6 +48,7 @@ onedev.server.scriptSupport = {
|
||||
styleSelectedText: true,
|
||||
foldGutter: true,
|
||||
matchBrackets: true,
|
||||
scrollbarStyle: "simple",
|
||||
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
|
||||
highlightIdentifiers: {delay: 500}
|
||||
});
|
||||
|
||||
@ -35,7 +35,7 @@ import com.google.common.collect.Sets;
|
||||
|
||||
import io.onedev.server.OneDev;
|
||||
import io.onedev.server.OneException;
|
||||
import io.onedev.server.ci.job.JobScheduler;
|
||||
import io.onedev.server.ci.job.JobManager;
|
||||
import io.onedev.server.ci.job.param.JobParam;
|
||||
import io.onedev.server.entitymanager.BuildManager;
|
||||
import io.onedev.server.git.GitUtils;
|
||||
@ -152,7 +152,7 @@ public abstract class BuildDetailPage extends ProjectPage implements InputContex
|
||||
|
||||
}));
|
||||
|
||||
summary.add(new BuildStatusIcon("statusIcon", buildModel));
|
||||
summary.add(new BuildStatusIcon("statusIcon", getBuild().getId(), true));
|
||||
summary.add(new Label("statusLabel", new AbstractReadOnlyModel<String>() {
|
||||
|
||||
@Override
|
||||
@ -167,9 +167,8 @@ public abstract class BuildDetailPage extends ProjectPage implements InputContex
|
||||
private void resubmit(Serializable paramBean) {
|
||||
Map<String, List<String>> paramMap = JobParam.getParamMap(getBuild().getJob(), paramBean,
|
||||
getBuild().getJob().getParamSpecMap().keySet());
|
||||
OneDev.getInstance(JobScheduler.class).resubmit(getBuild(), paramMap);
|
||||
OneDev.getInstance(JobManager.class).resubmit(getBuild(), paramMap);
|
||||
setResponsePage(BuildLogPage.class, BuildLogPage.paramsOf(getBuild(), position));
|
||||
getSession().success("Rebuild request submitted");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -232,7 +231,7 @@ public abstract class BuildDetailPage extends ProjectPage implements InputContex
|
||||
|
||||
@Override
|
||||
public void onClick() {
|
||||
OneDev.getInstance(JobScheduler.class).cancel(getBuild());
|
||||
OneDev.getInstance(JobManager.class).cancel(getBuild());
|
||||
getSession().success("Cancel request submitted");
|
||||
}
|
||||
|
||||
|
||||
@ -8,6 +8,13 @@
|
||||
position: relative;
|
||||
font-size: 24px;
|
||||
}
|
||||
#build-detail>.main>.summary .build-status {
|
||||
font-size: 24px;
|
||||
}
|
||||
#build-detail>.main>.summary .build-status-running {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
#build-detail>.main>.summary>* {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
@ -19,13 +19,13 @@
|
||||
<span wicket:id="contribution" class="name"></span>
|
||||
</div>
|
||||
<div class="commit pull-left">
|
||||
<span wicket:id="buildStatus" class="build-status"></span>
|
||||
<span wicket:id="hash" class="hash"></span>
|
||||
<a wicket:id="copyHash" class="copy"><i class="fa fa-clipboard"></i></a>
|
||||
</div>
|
||||
<div wicket:id="parents" class="parents pull-left"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div wicket:id="jobs"></div>
|
||||
<div wicket:id="revisionDiff"></div>
|
||||
</div>
|
||||
<wicket:fragment wicket:id="refsFrag">
|
||||
|
||||
@ -53,11 +53,11 @@ import io.onedev.server.util.CommitMessageTransformer;
|
||||
import io.onedev.server.util.diff.WhitespaceOption;
|
||||
import io.onedev.server.web.behavior.clipboard.CopyClipboardBehavior;
|
||||
import io.onedev.server.web.component.branch.create.CreateBranchLink;
|
||||
import io.onedev.server.web.component.build.status.CommitStatusPanel;
|
||||
import io.onedev.server.web.component.contributorpanel.ContributorPanel;
|
||||
import io.onedev.server.web.component.createtag.CreateTagLink;
|
||||
import io.onedev.server.web.component.diff.revision.CommentSupport;
|
||||
import io.onedev.server.web.component.diff.revision.RevisionDiffPanel;
|
||||
import io.onedev.server.web.component.job.commit.CommitJobsPanel;
|
||||
import io.onedev.server.web.component.link.ViewStateAwarePageLink;
|
||||
import io.onedev.server.web.component.user.contributoravatars.ContributorAvatars;
|
||||
import io.onedev.server.web.page.project.ProjectPage;
|
||||
@ -218,25 +218,13 @@ public class CommitDetailPage extends ProjectPage implements CommentSupport {
|
||||
add(new ContributorAvatars("contributorAvatars", getCommit().getAuthorIdent(), getCommit().getCommitterIdent()));
|
||||
add(new ContributorPanel("contribution", getCommit().getAuthorIdent(), getCommit().getCommitterIdent()));
|
||||
|
||||
add(new CommitStatusPanel("buildStatus") {
|
||||
|
||||
@Override
|
||||
protected Project getProject() {
|
||||
return CommitDetailPage.this.getProject();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ObjectId getCommitId() {
|
||||
return CommitDetailPage.this.getCommit().copy();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
add(new Label("hash", GitUtils.abbreviateSHA(getCommit().name())));
|
||||
add(new WebMarkupContainer("copyHash").add(new CopyClipboardBehavior(Model.of(getCommit().name()))));
|
||||
|
||||
newParentsContainer(null);
|
||||
|
||||
add(new CommitJobsPanel("jobs", projectModel, getCommit().copy()));
|
||||
|
||||
newRevisionDiff(null);
|
||||
}
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<span class="pull-left">Backlog</span>
|
||||
<span wicket:id="count" class="badge pull-left"></span>
|
||||
<a wicket:id="addCard" title="Add new card to this column" class="add-card pull-right"><i class="fa fa-plus"></i></a>
|
||||
<a wicket:id="viewAsList" title="View as issue list" class="view-list pull-right"><i class="fa fa-list-ul"></i></a>
|
||||
<a wicket:id="viewAsList" title="Show issues in list" class="view-list pull-right"><i class="fa fa-list-ul"></i></a>
|
||||
</div>
|
||||
<div wicket:id="body" class="body"></div>
|
||||
</div>
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<span wicket:id="title" class="pull-left"></span>
|
||||
<span wicket:id="count" class="badge pull-left"></span>
|
||||
<a wicket:id="addCard" title="Add new card to this column" class="add-card pull-right"><i class="fa fa-plus"></i></a>
|
||||
<a wicket:id="viewAsList" title="View as issue list" class="show-list pull-right"><i class="fa fa-list-ul"></i></a>
|
||||
<a wicket:id="viewAsList" title="Show issues in list" class="show-list pull-right"><i class="fa fa-list-ul"></i></a>
|
||||
</div>
|
||||
<div wicket:id="body" class="body"></div>
|
||||
</div>
|
||||
|
||||
@ -88,12 +88,6 @@
|
||||
<td class="name">Reviewers</td>
|
||||
<td class="value"><div wicket:id="reviewers"></div></td>
|
||||
</tr>
|
||||
<wicket:enclosure child="builds">
|
||||
<tr class="builds">
|
||||
<td class="name">Builds</td>
|
||||
<td class="value"><div wicket:id="builds"></div></td>
|
||||
</tr>
|
||||
</wicket:enclosure>
|
||||
</table>
|
||||
<div class="clearfix">
|
||||
<input wicket:id="send" type="submit" class="btn btn-primary pull-left" value="Create Pull Request">
|
||||
|
||||
@ -65,7 +65,6 @@ import io.onedev.server.util.diff.WhitespaceOption;
|
||||
import io.onedev.server.web.ajaxlistener.DisableGlobalLoadingIndicatorListener;
|
||||
import io.onedev.server.web.component.branch.BranchLink;
|
||||
import io.onedev.server.web.component.branch.picker.AffinalBranchPicker;
|
||||
import io.onedev.server.web.component.build.status.BuildRequirementListPanel;
|
||||
import io.onedev.server.web.component.commit.list.CommitListPanel;
|
||||
import io.onedev.server.web.component.diff.revision.CommentSupport;
|
||||
import io.onedev.server.web.component.diff.revision.RevisionDiffPanel;
|
||||
@ -633,8 +632,6 @@ public class NewPullRequestPage extends ProjectPage implements CommentSupport {
|
||||
form.add(newMergeStrategyContainer());
|
||||
|
||||
form.add(new ReviewListPanel("reviewers", requestModel));
|
||||
|
||||
form.add(new BuildRequirementListPanel("builds", requestModel));
|
||||
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@ -15,6 +15,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.EntityNotFoundException;
|
||||
@ -72,6 +73,7 @@ import io.onedev.server.entitymanager.PullRequestManager;
|
||||
import io.onedev.server.entitymanager.PullRequestUpdateManager;
|
||||
import io.onedev.server.entitymanager.PullRequestWatchManager;
|
||||
import io.onedev.server.model.AbstractEntity;
|
||||
import io.onedev.server.model.Build;
|
||||
import io.onedev.server.model.Project;
|
||||
import io.onedev.server.model.PullRequest;
|
||||
import io.onedev.server.model.PullRequestUpdate;
|
||||
@ -88,7 +90,7 @@ import io.onedev.server.util.facade.UserFacade;
|
||||
import io.onedev.server.util.userident.UserIdent;
|
||||
import io.onedev.server.web.ajaxlistener.ConfirmLeaveListener;
|
||||
import io.onedev.server.web.component.branch.BranchLink;
|
||||
import io.onedev.server.web.component.build.status.BuildRequirementListPanel;
|
||||
import io.onedev.server.web.component.build.status.StatusListPanel;
|
||||
import io.onedev.server.web.component.entity.nav.EntityNavPanel;
|
||||
import io.onedev.server.web.component.entity.watches.EntityWatchesPanel;
|
||||
import io.onedev.server.web.component.floating.FloatingPanel;
|
||||
@ -452,7 +454,22 @@ public abstract class PullRequestDetailPage extends ProjectPage {
|
||||
fragment.add(newMergeStrategyContainer());
|
||||
fragment.add(new ReviewListPanel("reviews", requestModel));
|
||||
|
||||
fragment.add(new BuildRequirementListPanel("builds", requestModel));
|
||||
fragment.add(new StatusListPanel("builds", new LoadableDetachableModel<Collection<Build>>() {
|
||||
|
||||
@Override
|
||||
protected Collection<Build> load() {
|
||||
return getPullRequest().getPullRequestBuilds().stream().map(it->it.getBuild()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}) {
|
||||
|
||||
@Override
|
||||
protected void onConfigure() {
|
||||
super.onConfigure();
|
||||
setVisible(!getPullRequest().getPullRequestBuilds().isEmpty());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
fragment.add(new EntityWatchesPanel("watches") {
|
||||
|
||||
|
||||
@ -1,2 +1,3 @@
|
||||
<wicket:extend>
|
||||
<a wicket:id="test">test</a>
|
||||
</wicket:extend>
|
||||
@ -3,6 +3,7 @@ package io.onedev.server.web.page.test;
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
|
||||
import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
|
||||
import org.apache.wicket.markup.html.link.Link;
|
||||
import org.apache.wicket.request.mapper.parameter.PageParameters;
|
||||
|
||||
import io.onedev.server.web.page.base.BasePage;
|
||||
@ -17,6 +18,20 @@ public class TestPage extends BasePage {
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
add(new Link<Void>("test") {
|
||||
|
||||
@Override
|
||||
public void onClick() {
|
||||
new Thread(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
}
|
||||
|
||||
}).start();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -5,6 +5,7 @@ import javax.inject.Singleton;
|
||||
|
||||
import io.onedev.commons.launcher.loader.Listen;
|
||||
import io.onedev.server.event.build.BuildEvent;
|
||||
import io.onedev.server.event.build.BuildSubmitted;
|
||||
import io.onedev.server.model.Build;
|
||||
import io.onedev.server.web.util.WicketUtils;
|
||||
|
||||
@ -20,8 +21,13 @@ public class BuildEventBroadcaster {
|
||||
|
||||
@Listen
|
||||
public void on(BuildEvent event) {
|
||||
webSocketManager.notifyObservableChange(Build.getWebSocketObservable(event.getBuild().getId()), WicketUtils.getPageKey());
|
||||
webSocketManager.notifyObservableChange("commit-status:" + event.getBuild().getCommitHash(), WicketUtils.getPageKey());
|
||||
PageKey pageKey = WicketUtils.getPageKey();
|
||||
webSocketManager.notifyObservableChange(Build.getWebSocketObservable(event.getBuild().getId()), pageKey);
|
||||
webSocketManager.notifyObservableChange("commit-status:" + event.getBuild().getCommitHash(), pageKey);
|
||||
if (event instanceof BuildSubmitted) {
|
||||
String observable = "commit-builds:" + event.getProject().getId() + ":" + event.getBuild().getCommitHash();
|
||||
webSocketManager.notifyObservableChange(observable, pageKey);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user