mirror of
https://github.com/theonedev/onedev.git
synced 2025-12-08 18:26:30 +00:00
chore: Generate build spec schema to aid AI
This commit is contained in:
parent
2e187d3cc5
commit
8bb5dce066
@ -71,9 +71,9 @@ import io.onedev.commons.utils.ExceptionUtils;
|
||||
import io.onedev.commons.utils.StringUtils;
|
||||
import io.onedev.k8shelper.KubernetesHelper;
|
||||
import io.onedev.k8shelper.OsInfo;
|
||||
import io.onedev.server.ai.McpHelperResource;
|
||||
import io.onedev.server.attachment.AttachmentManager;
|
||||
import io.onedev.server.attachment.DefaultAttachmentManager;
|
||||
import io.onedev.server.buildspec.BuildSpecSchemaResource;
|
||||
import io.onedev.server.buildspec.job.log.instruction.LogInstruction;
|
||||
import io.onedev.server.cluster.ClusterResource;
|
||||
import io.onedev.server.codequality.CodeProblemContribution;
|
||||
@ -331,6 +331,7 @@ import io.onedev.server.rest.DefaultServletContainer;
|
||||
import io.onedev.server.rest.JerseyConfigurator;
|
||||
import io.onedev.server.rest.ResourceConfigProvider;
|
||||
import io.onedev.server.rest.WebApplicationExceptionHandler;
|
||||
import io.onedev.server.rest.resource.McpHelperResource;
|
||||
import io.onedev.server.rest.resource.ProjectResource;
|
||||
import io.onedev.server.search.code.CodeIndexManager;
|
||||
import io.onedev.server.search.code.CodeSearchManager;
|
||||
@ -655,6 +656,7 @@ public class CoreModule extends AbstractPluginModule {
|
||||
contribute(JerseyConfigurator.class, resourceConfig -> resourceConfig.packages(ProjectResource.class.getPackage().getName()));
|
||||
contribute(JerseyConfigurator.class, resourceConfig -> resourceConfig.register(ClusterResource.class));
|
||||
contribute(JerseyConfigurator.class, resourceConfig -> resourceConfig.register(McpHelperResource.class));
|
||||
contribute(JerseyConfigurator.class, resourceConfig -> resourceConfig.register(BuildSpecSchemaResource.class));
|
||||
}
|
||||
|
||||
private void configureWeb() {
|
||||
|
||||
@ -0,0 +1,17 @@
|
||||
package io.onedev.server.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||
public @interface DependsOn {
|
||||
|
||||
String property();
|
||||
|
||||
String value() default "";
|
||||
|
||||
boolean inverse() default false;
|
||||
}
|
||||
@ -284,7 +284,7 @@ public class BuildSpec implements Serializable, Validatable {
|
||||
for (ConstraintViolation<Job> violation: getValidator().validate(job)) {
|
||||
context.buildConstraintViolationWithTemplate(violation.getMessage())
|
||||
.addPropertyNode(PROP_JOBS)
|
||||
.addBeanNode()
|
||||
.addPropertyNode(violation.getPropertyPath().toString())
|
||||
.inIterable().atIndex(index)
|
||||
.addConstraintViolation();
|
||||
isValid = false;
|
||||
@ -306,7 +306,7 @@ public class BuildSpec implements Serializable, Validatable {
|
||||
for (ConstraintViolation<Service> violation: getValidator().validate(service)) {
|
||||
context.buildConstraintViolationWithTemplate(violation.getMessage())
|
||||
.addPropertyNode(PROP_SERVICES)
|
||||
.addBeanNode()
|
||||
.addPropertyNode(violation.getPropertyPath().toString())
|
||||
.inIterable().atIndex(index)
|
||||
.addConstraintViolation();
|
||||
isValid = false;
|
||||
@ -328,7 +328,7 @@ public class BuildSpec implements Serializable, Validatable {
|
||||
for (ConstraintViolation<StepTemplate> violation: getValidator().validate(stepTemplate)) {
|
||||
context.buildConstraintViolationWithTemplate(violation.getMessage())
|
||||
.addPropertyNode(PROP_STEP_TEMPLATES)
|
||||
.addBeanNode()
|
||||
.addPropertyNode(violation.getPropertyPath().toString())
|
||||
.inIterable().atIndex(index)
|
||||
.addConstraintViolation();
|
||||
isValid = false;
|
||||
@ -350,7 +350,7 @@ public class BuildSpec implements Serializable, Validatable {
|
||||
for (ConstraintViolation<JobProperty> violation: getValidator().validate(property)) {
|
||||
context.buildConstraintViolationWithTemplate(violation.getMessage())
|
||||
.addPropertyNode(PROP_PROPERTIES)
|
||||
.addBeanNode()
|
||||
.addPropertyNode(violation.getPropertyPath().toString())
|
||||
.inIterable().atIndex(index)
|
||||
.addConstraintViolation();
|
||||
isValid = false;
|
||||
@ -373,7 +373,7 @@ public class BuildSpec implements Serializable, Validatable {
|
||||
for (ConstraintViolation<Import> violation: validator.validate(aImport)) {
|
||||
context.buildConstraintViolationWithTemplate(violation.getMessage())
|
||||
.addPropertyNode(PROP_IMPORTS)
|
||||
.addBeanNode()
|
||||
.addPropertyNode(violation.getPropertyPath().toString())
|
||||
.inIterable().atIndex(index)
|
||||
.addConstraintViolation();
|
||||
isValid = false;
|
||||
@ -2312,4 +2312,27 @@ public class BuildSpec implements Serializable, Validatable {
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private void migrate41(VersionedYamlDoc doc, Stack<Integer> versions) {
|
||||
for (NodeTuple specTuple: doc.getValue()) {
|
||||
String specKey = ((ScalarNode)specTuple.getKeyNode()).getValue();
|
||||
if (specKey.equals("jobs")) {
|
||||
SequenceNode jobsNode = (SequenceNode) specTuple.getValueNode();
|
||||
for (Node jobsNodeItem: jobsNode.getValue()) {
|
||||
MappingNode jobNode = (MappingNode) jobsNodeItem;
|
||||
for (var itJobTuple = jobNode.getValue().iterator(); itJobTuple.hasNext();) {
|
||||
var jobTuple = itJobTuple.next();
|
||||
var keyNode = (ScalarNode) jobTuple.getKeyNode();
|
||||
if (keyNode.getValue().equals("retryCondition")) {
|
||||
var valueNode = (ScalarNode) jobTuple.getValueNode();
|
||||
if (valueNode.getValue().equals("never")) {
|
||||
itJobTuple.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,339 @@
|
||||
package io.onedev.server.buildspec;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
import io.onedev.commons.loader.ImplementationRegistry;
|
||||
import io.onedev.commons.utils.ClassUtils;
|
||||
import io.onedev.commons.utils.ExplicitException;
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.ImplementationProvider;
|
||||
import io.onedev.server.buildspec.job.Job;
|
||||
import io.onedev.server.data.migration.MigrationHelper;
|
||||
import io.onedev.server.model.support.build.JobProperty;
|
||||
import io.onedev.server.rest.annotation.Api;
|
||||
import io.onedev.server.util.Pair;
|
||||
import io.onedev.server.util.ReflectionUtils;
|
||||
import io.onedev.server.web.editable.BeanDescriptor;
|
||||
import io.onedev.server.web.editable.EditableUtils;
|
||||
import io.onedev.server.web.editable.PropertyDescriptor;
|
||||
|
||||
@Api(internal = true)
|
||||
@Path("/build-spec-schema.yml")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces("application/x-yaml")
|
||||
@Singleton
|
||||
public class BuildSpecSchemaResource {
|
||||
|
||||
private final ImplementationRegistry implementationRegistry;
|
||||
|
||||
private final Yaml yaml;
|
||||
|
||||
private String schema;
|
||||
|
||||
@Inject
|
||||
public BuildSpecSchemaResource(ImplementationRegistry implementationRegistry) {
|
||||
this.implementationRegistry = implementationRegistry;
|
||||
|
||||
// Configure YAML output
|
||||
DumperOptions options = new DumperOptions();
|
||||
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||
options.setPrettyFlow(true);
|
||||
this.yaml = new Yaml(options);
|
||||
}
|
||||
|
||||
private void processProperty(Map<String, Object> currentNode, PropertyDescriptor property) {
|
||||
var description = property.getDescription();
|
||||
if (description != null)
|
||||
currentNode.put("description", description);
|
||||
var returnType = property.getPropertyClass();
|
||||
|
||||
if (Collection.class.isAssignableFrom(returnType)) {
|
||||
var elementClass = ReflectionUtils.getCollectionElementClass(property.getPropertyGetter().getGenericReturnType());
|
||||
if (elementClass == null)
|
||||
throw new ExplicitException("Unknown collection element class (bean: " + property.getBeanClass() + ", property: " + property.getPropertyName() + ")");
|
||||
processCollectionProperty(currentNode, elementClass);
|
||||
} else {
|
||||
processType(currentNode, returnType);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void processBean(Map<String, Object> currentNode, Class<?> beanClass,
|
||||
Map<String, PropertyDescriptor> processedProperties) {
|
||||
var propsNode = (Map<String, Object>) currentNode.get("properties");
|
||||
if (propsNode == null) {
|
||||
propsNode = new HashMap<>();
|
||||
currentNode.put("properties", propsNode);
|
||||
}
|
||||
var requiredNode = (List<String>) currentNode.get("required");
|
||||
if (requiredNode == null) {
|
||||
requiredNode = new ArrayList<>();
|
||||
currentNode.put("required", requiredNode);
|
||||
}
|
||||
|
||||
var dependents = new ArrayList<Pair<PropertyDescriptor, DependsOn>>();
|
||||
for (var groupProperties: new BeanDescriptor(beanClass).getProperties().values()) {
|
||||
for (var property: groupProperties) {
|
||||
if (processedProperties.putIfAbsent(property.getPropertyName(), property) == null) {
|
||||
if (property.getPropertyName().equals("type"))
|
||||
throw new ExplicitException("Property 'type' is reserved (class: " + beanClass.getName() + ")");
|
||||
var dependsOn = property.getPropertyGetter().getAnnotation(DependsOn.class);
|
||||
if (dependsOn != null) {
|
||||
dependents.add(new Pair<>(property, dependsOn));
|
||||
} else {
|
||||
if (property.isPropertyRequired())
|
||||
requiredNode.add(property.getPropertyName());
|
||||
var propNode = new HashMap<String, Object>();
|
||||
propsNode.put(property.getPropertyName(), propNode);
|
||||
processProperty(propNode, property);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!dependents.isEmpty()) {
|
||||
var allOfNode = new ArrayList<Map<String, Object>>();
|
||||
currentNode.put("allOf", allOfNode);
|
||||
for (var dependent: dependents) {
|
||||
var allOfItemNode = new HashMap<String, Object>();
|
||||
allOfNode.add(allOfItemNode);
|
||||
var dependsOn = dependent.getRight();
|
||||
var dependencyProperty = processedProperties.get(dependsOn.property());
|
||||
if (dependencyProperty == null)
|
||||
throw new ExplicitException("Dependency property not found: " + dependsOn.property());
|
||||
|
||||
var ifNode = new HashMap<String, Object>();
|
||||
allOfItemNode.put("if", ifNode);
|
||||
var ifPropsNode = new HashMap<String, Object>();
|
||||
ifNode.put("properties", ifPropsNode);
|
||||
var dependencyPropertyNode = new HashMap<String, Object>();
|
||||
ifPropsNode.put(dependencyProperty.getPropertyName(), dependencyPropertyNode);
|
||||
|
||||
var inverse = dependsOn.inverse();
|
||||
var dependencyPropertyClass = dependencyProperty.getPropertyClass();
|
||||
if (dependencyPropertyClass == boolean.class) {
|
||||
if (dependsOn.value().length() != 0) {
|
||||
dependencyPropertyNode.put("const", Boolean.parseBoolean(dependsOn.value()));
|
||||
} else {
|
||||
dependencyPropertyNode.put("const", true);
|
||||
}
|
||||
} else if (dependencyPropertyClass == int.class || dependencyPropertyClass == long.class
|
||||
|| dependencyPropertyClass == double.class || dependencyPropertyClass == float.class) {
|
||||
if (dependsOn.value().length() != 0) {
|
||||
dependencyPropertyNode.put("const", Integer.parseInt(dependsOn.value()));
|
||||
} else {
|
||||
dependencyPropertyNode.put("const", 0);
|
||||
inverse = !inverse;
|
||||
}
|
||||
} else {
|
||||
if (dependsOn.value().length() != 0) {
|
||||
if (dependencyPropertyClass == Boolean.class)
|
||||
dependencyPropertyNode.put("const", Boolean.parseBoolean(dependsOn.value()));
|
||||
else if (dependencyPropertyClass == Integer.class || dependencyPropertyClass == Long.class || dependencyPropertyClass == Double.class || dependencyPropertyClass == Float.class)
|
||||
dependencyPropertyNode.put("const", Integer.parseInt(dependsOn.value()));
|
||||
else
|
||||
dependencyPropertyNode.put("const", dependsOn.value());
|
||||
} else {
|
||||
var typeList = new ArrayList<String>();
|
||||
typeList.add("object");
|
||||
typeList.add("string");
|
||||
typeList.add("integer");
|
||||
typeList.add("number");
|
||||
typeList.add("boolean");
|
||||
dependencyPropertyNode.put("type", typeList);
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Object> branchNode;
|
||||
if (!inverse) {
|
||||
branchNode = new HashMap<>();
|
||||
allOfItemNode.put("then", branchNode);
|
||||
} else {
|
||||
branchNode = new HashMap<>();
|
||||
allOfItemNode.put("else", branchNode);
|
||||
}
|
||||
|
||||
var property = dependent.getLeft();
|
||||
var branchPropsNode = new HashMap<String, Object>();
|
||||
branchNode.put("properties", branchPropsNode);
|
||||
var propNode = new HashMap<String, Object>();
|
||||
branchPropsNode.put(property.getPropertyName(), propNode);
|
||||
processProperty(propNode, property);
|
||||
if (property.isPropertyRequired()) {
|
||||
var requiredList = new ArrayList<String>();
|
||||
requiredList.add(property.getPropertyName());
|
||||
branchNode.put("required", requiredList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private void processType(Map<String, Object> currentNode, Class<?> type) {
|
||||
if (type == String.class) {
|
||||
currentNode.put("type", "string");
|
||||
} else if (type == Boolean.class || type == boolean.class) {
|
||||
currentNode.put("type", "boolean");
|
||||
} else if (type == Integer.class || type == int.class || type == Long.class || type == long.class) {
|
||||
currentNode.put("type", "integer");
|
||||
} else if (type == Float.class || type == float.class || type == Double.class || type == double.class) {
|
||||
currentNode.put("type", "number");
|
||||
} else if (Enum.class.isAssignableFrom(type)) {
|
||||
currentNode.put("type", "string");
|
||||
var enumList = new ArrayList<String>();
|
||||
var enumClass = (Class<Enum>) type;
|
||||
for (var enumValue: EnumSet.allOf(enumClass)) {
|
||||
enumList.add(((Enum) enumValue).name());
|
||||
}
|
||||
currentNode.put("enum", enumList);
|
||||
} else if (type == Date.class) {
|
||||
currentNode.put("type", "string");
|
||||
currentNode.put("format", "date-time");
|
||||
} else if (type.getAnnotation(Editable.class) != null) {
|
||||
if (ClassUtils.isConcrete(type)) {
|
||||
currentNode.put("type", "object");
|
||||
processBean(currentNode, type, new HashMap<>());
|
||||
currentNode.put("additionalProperties", false);
|
||||
} else {
|
||||
processPolymorphic(currentNode, type);
|
||||
}
|
||||
} else {
|
||||
throw new ExplicitException("Unsupported type: " + type);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void processPolymorphic(Map<String, Object> currentNode, Class<?> baseClass) {
|
||||
Collection<Class<?>> implementations = new ArrayList<>();
|
||||
var implementationProvider = baseClass.getAnnotation(ImplementationProvider.class);
|
||||
if (implementationProvider != null)
|
||||
implementations.addAll((Collection<? extends Class<? extends Serializable>>) ReflectionUtils.invokeStaticMethod(baseClass, implementationProvider.value()));
|
||||
else
|
||||
implementations.addAll(implementationRegistry.getImplementations(baseClass));
|
||||
|
||||
currentNode.put("type", "object");
|
||||
|
||||
var propsNode = new HashMap<String, Object>();
|
||||
currentNode.put("properties", propsNode);
|
||||
var typeNode = new HashMap<String, Object>();
|
||||
propsNode.put("type", typeNode);
|
||||
typeNode.put("type", "string");
|
||||
|
||||
var enumList = new ArrayList<String>();
|
||||
typeNode.put("enum", enumList);
|
||||
|
||||
var requiredList = new ArrayList<String>();
|
||||
requiredList.add("type");
|
||||
currentNode.put("required", requiredList);
|
||||
|
||||
var processedProperties = new HashMap<String, PropertyDescriptor>();
|
||||
processBean(currentNode, baseClass, processedProperties);
|
||||
|
||||
var oneOfList = new ArrayList<Map<String, Object>>();
|
||||
currentNode.put("oneOf", oneOfList);
|
||||
|
||||
for (var implementation: implementations) {
|
||||
enumList.add(implementation.getSimpleName());
|
||||
var oneOfItemNode = new HashMap<String, Object>();
|
||||
oneOfList.add(oneOfItemNode);
|
||||
var description = EditableUtils.getDescription(implementation);
|
||||
if (description != null)
|
||||
oneOfItemNode.put("description", description);
|
||||
processBean(oneOfItemNode, implementation, new HashMap<>(processedProperties));
|
||||
var implementationPropsNode = (Map<String, Object>) oneOfItemNode.get("properties");
|
||||
var typeConstNode = new HashMap<String, Object>();
|
||||
typeConstNode.put("const", implementation.getSimpleName());
|
||||
implementationPropsNode.put("type", typeConstNode);
|
||||
}
|
||||
}
|
||||
|
||||
private void processCollectionProperty(Map<String, Object> currentNode, Class<?> collectionElementClass) {
|
||||
currentNode.put("type", "array");
|
||||
var itemsNode = new HashMap<String, Object>();
|
||||
currentNode.put("items", itemsNode);
|
||||
if (Collection.class.isAssignableFrom(collectionElementClass)) {
|
||||
itemsNode.put("type", "array");
|
||||
var nestedItemsNode = new HashMap<String, Object>();
|
||||
nestedItemsNode.put("type", "string");
|
||||
itemsNode.put("items", nestedItemsNode);
|
||||
} else {
|
||||
processType(itemsNode, collectionElementClass);
|
||||
}
|
||||
}
|
||||
|
||||
@Path("/")
|
||||
@GET
|
||||
@SuppressWarnings("unchecked")
|
||||
public String getBuildSpecSchema() {
|
||||
if (schema == null) {
|
||||
var rootNode = new HashMap<String, Object>();
|
||||
rootNode.put("$schema", "https://json-schema.org/draft/2020-12/schema");
|
||||
rootNode.put("title", "YAML schema of build spec file");
|
||||
rootNode.put("type", "object");
|
||||
|
||||
var propsNode = new HashMap<String, Object>();
|
||||
rootNode.put("properties", propsNode);
|
||||
|
||||
var versionNode = new HashMap<String, Object>();
|
||||
propsNode.put("version", versionNode);
|
||||
versionNode.put("type", "integer");
|
||||
versionNode.put("const", Integer.parseInt(MigrationHelper.getVersion(BuildSpec.class)));
|
||||
|
||||
var jobsNode = new HashMap<String, Object>();
|
||||
propsNode.put("jobs", jobsNode);
|
||||
processCollectionProperty(jobsNode, Job.class);
|
||||
|
||||
var servicesNode = new HashMap<String, Object>();
|
||||
propsNode.put("services", servicesNode);
|
||||
processCollectionProperty(servicesNode, Service.class);
|
||||
|
||||
var propertiesNode = new HashMap<String, Object>();
|
||||
propsNode.put("properties", propertiesNode);
|
||||
processCollectionProperty(propertiesNode, JobProperty.class);
|
||||
|
||||
var importsNode = new HashMap<String, Object>();
|
||||
propsNode.put("imports", importsNode);
|
||||
processCollectionProperty(importsNode, Import.class);
|
||||
|
||||
var jobPropsNode = (Map<String, Object>) ((Map<String, Object>) jobsNode.get("items")).get("properties");
|
||||
|
||||
var stepTemplatesNode = new HashMap<String, Object>();
|
||||
propsNode.put("stepTemplates", stepTemplatesNode);
|
||||
stepTemplatesNode.put("type", "array");
|
||||
var stepTemplateNode = new HashMap<String, Object>();
|
||||
stepTemplatesNode.put("items", stepTemplateNode);
|
||||
stepTemplateNode.put("type", "object");
|
||||
var stepTemplatePropsNode = new HashMap<String, Object>();
|
||||
stepTemplateNode.put("properties", stepTemplatePropsNode);
|
||||
stepTemplatePropsNode.put("steps", jobPropsNode.get("steps"));
|
||||
stepTemplatePropsNode.put("paramSpecs", jobPropsNode.get("paramSpecs"));
|
||||
|
||||
var requiredList = new ArrayList<String>();
|
||||
requiredList.add("version");
|
||||
rootNode.put("required", requiredList);
|
||||
rootNode.put("additionalProperties", false);
|
||||
|
||||
schema = yaml.dump(rootNode);
|
||||
}
|
||||
return schema;
|
||||
}
|
||||
|
||||
}
|
||||
@ -32,6 +32,7 @@ import io.onedev.commons.codeassist.InputSuggestion;
|
||||
import io.onedev.server.OneDev;
|
||||
import io.onedev.server.annotation.ChoiceProvider;
|
||||
import io.onedev.server.annotation.ClassValidating;
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.Interpolative;
|
||||
import io.onedev.server.annotation.RetryCondition;
|
||||
@ -105,7 +106,7 @@ public class Job implements NamedElement, Validatable {
|
||||
|
||||
private String sequentialGroup;
|
||||
|
||||
private String retryCondition = "never";
|
||||
private String retryCondition;
|
||||
|
||||
private int maxRetries = 3;
|
||||
|
||||
@ -279,8 +280,7 @@ public class Job implements NamedElement, Validatable {
|
||||
this.sequentialGroup = sequentialGroup;
|
||||
}
|
||||
|
||||
@Editable(order=9400, group="More Settings", description="Specify condition to retry build upon failure")
|
||||
@NotEmpty
|
||||
@Editable(order=9400, placeholder="Never retry", group="More Settings", description="Specify condition to retry build upon failure")
|
||||
@RetryCondition
|
||||
public String getRetryCondition() {
|
||||
return retryCondition;
|
||||
@ -292,6 +292,7 @@ public class Job implements NamedElement, Validatable {
|
||||
|
||||
@Editable(order=9410, group="More Settings", description="Maximum of retries before giving up")
|
||||
@Min(value=1, message="This value should not be less than 1")
|
||||
@DependsOn(property="retryCondition")
|
||||
public int getMaxRetries() {
|
||||
return maxRetries;
|
||||
}
|
||||
@ -304,6 +305,7 @@ public class Job implements NamedElement, Validatable {
|
||||
"Delay of subsequent retries will be calculated using an exponential back-off based on " +
|
||||
"this value")
|
||||
@Min(value=1, message="This value should not be less than 1")
|
||||
@DependsOn(property="retryCondition")
|
||||
public int getRetryDelay() {
|
||||
return retryDelay;
|
||||
}
|
||||
|
||||
@ -1,10 +1,29 @@
|
||||
package io.onedev.server.buildspec.job.action;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.ValidationException;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
import org.apache.shiro.subject.Subject;
|
||||
|
||||
import edu.emory.mathcs.backport.java.util.Collections;
|
||||
import io.onedev.commons.codeassist.InputSuggestion;
|
||||
import io.onedev.commons.utils.ExplicitException;
|
||||
import io.onedev.server.OneDev;
|
||||
import io.onedev.server.annotation.*;
|
||||
import io.onedev.server.annotation.ChoiceProvider;
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.FieldNamesProvider;
|
||||
import io.onedev.server.annotation.Interpolative;
|
||||
import io.onedev.server.annotation.Multiline;
|
||||
import io.onedev.server.annotation.OmitName;
|
||||
import io.onedev.server.buildspec.BuildSpec;
|
||||
import io.onedev.server.buildspec.job.Job;
|
||||
import io.onedev.server.entitymanager.IssueManager;
|
||||
@ -20,18 +39,9 @@ import io.onedev.server.model.support.issue.field.instance.FieldInstance;
|
||||
import io.onedev.server.persistence.TransactionManager;
|
||||
import io.onedev.server.security.SecurityUtils;
|
||||
import io.onedev.server.security.permission.AccessProject;
|
||||
import io.onedev.server.util.EditContext;
|
||||
import io.onedev.server.util.facade.ProjectCache;
|
||||
import io.onedev.server.web.page.project.ProjectPage;
|
||||
import io.onedev.server.web.util.WicketUtils;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.ValidationException;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Editable(name="Create issue", order=300)
|
||||
public class CreateIssueAction extends PostBuildAction {
|
||||
@ -80,7 +90,7 @@ public class CreateIssueAction extends PostBuildAction {
|
||||
@Editable(order=910, description="Specify a secret to be used as access token to create issue in " +
|
||||
"above project if it is not publicly accessible")
|
||||
@ChoiceProvider("getAccessTokenSecretChoices")
|
||||
@ShowCondition("isProjectSpecified")
|
||||
@DependsOn(property="projectPath")
|
||||
@Nullable
|
||||
public String getAccessTokenSecret() {
|
||||
return accessTokenSecret;
|
||||
@ -89,11 +99,6 @@ public class CreateIssueAction extends PostBuildAction {
|
||||
public void setAccessTokenSecret(String accessTokenSecret) {
|
||||
this.accessTokenSecret = accessTokenSecret;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isProjectSpecified() {
|
||||
return EditContext.get().getInputValue("projectPath") != null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static List<String> getAccessTokenSecretChoices() {
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
package io.onedev.server.buildspec.job.retrycondition;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.From;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
|
||||
import io.onedev.server.util.ProjectScope;
|
||||
import io.onedev.server.util.criteria.Criteria;
|
||||
|
||||
public class NeverCriteria extends Criteria<RetryContext> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public Predicate getPredicate(@Nullable ProjectScope projectScope, CriteriaQuery<?> query, From<RetryContext, RetryContext> from, CriteriaBuilder builder) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(RetryContext context) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toStringWithoutParens() {
|
||||
return RetryCondition.getRuleName(RetryConditionLexer.Never);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
grammar RetryCondition;
|
||||
|
||||
condition
|
||||
: WS* (criteria|Never) WS* EOF
|
||||
: WS* criteria WS* EOF
|
||||
;
|
||||
|
||||
criteria
|
||||
@ -12,11 +12,7 @@ criteria
|
||||
| Not WS* LParens WS* criteria WS* RParens #NotCriteria
|
||||
| LParens WS* criteria WS* RParens #ParensCriteria
|
||||
;
|
||||
|
||||
Never
|
||||
: 'never'
|
||||
;
|
||||
|
||||
|
||||
Contains
|
||||
: 'contains'
|
||||
;
|
||||
|
||||
@ -87,60 +87,57 @@ public class RetryCondition extends Criteria<RetryContext> {
|
||||
|
||||
Criteria<RetryContext> criteria;
|
||||
|
||||
if (conditionContext.Never() != null) {
|
||||
criteria = new NeverCriteria();
|
||||
} else {
|
||||
criteria = new RetryConditionBaseVisitor<Criteria<RetryContext>>() {
|
||||
|
||||
@Override
|
||||
public Criteria<RetryContext> visitParensCriteria(ParensCriteriaContext ctx) {
|
||||
return visit(ctx.criteria()).withParens(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Criteria<RetryContext> visitFieldOperatorCriteria(FieldOperatorCriteriaContext ctx) {
|
||||
String fieldName = getValue(ctx.Quoted().getText());
|
||||
int operator = ctx.operator.getType();
|
||||
checkField(job, fieldName, operator);
|
||||
return new ParamEmptyCriteria(fieldName, operator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Criteria<RetryContext> visitFieldOperatorValueCriteria(FieldOperatorValueCriteriaContext ctx) {
|
||||
String fieldName = getValue(ctx.Quoted(0).getText());
|
||||
String fieldValue = getValue(ctx.Quoted(1).getText());
|
||||
int operator = ctx.operator.getType();
|
||||
checkField(job, fieldName, operator);
|
||||
criteria = new RetryConditionBaseVisitor<Criteria<RetryContext>>() {
|
||||
|
||||
if (fieldName.equals(NAME_LOG))
|
||||
return new LogCriteria(fieldValue);
|
||||
else
|
||||
return new ParamCriteria(fieldName, fieldValue, operator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Criteria<RetryContext> visitOrCriteria(OrCriteriaContext ctx) {
|
||||
List<Criteria<RetryContext>> childCriterias = new ArrayList<>();
|
||||
for (CriteriaContext childCtx: ctx.criteria())
|
||||
childCriterias.add(visit(childCtx));
|
||||
return new OrCriteria<RetryContext>(childCriterias);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Criteria<RetryContext> visitAndCriteria(AndCriteriaContext ctx) {
|
||||
List<Criteria<RetryContext>> childCriterias = new ArrayList<>();
|
||||
for (CriteriaContext childCtx: ctx.criteria())
|
||||
childCriterias.add(visit(childCtx));
|
||||
return new AndCriteria<RetryContext>(childCriterias);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Criteria<RetryContext> visitNotCriteria(NotCriteriaContext ctx) {
|
||||
return new NotCriteria<RetryContext>(visit(ctx.criteria()));
|
||||
}
|
||||
|
||||
}.visit(conditionContext.criteria());
|
||||
}
|
||||
@Override
|
||||
public Criteria<RetryContext> visitParensCriteria(ParensCriteriaContext ctx) {
|
||||
return visit(ctx.criteria()).withParens(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Criteria<RetryContext> visitFieldOperatorCriteria(FieldOperatorCriteriaContext ctx) {
|
||||
String fieldName = getValue(ctx.Quoted().getText());
|
||||
int operator = ctx.operator.getType();
|
||||
checkField(job, fieldName, operator);
|
||||
return new ParamEmptyCriteria(fieldName, operator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Criteria<RetryContext> visitFieldOperatorValueCriteria(FieldOperatorValueCriteriaContext ctx) {
|
||||
String fieldName = getValue(ctx.Quoted(0).getText());
|
||||
String fieldValue = getValue(ctx.Quoted(1).getText());
|
||||
int operator = ctx.operator.getType();
|
||||
checkField(job, fieldName, operator);
|
||||
|
||||
if (fieldName.equals(NAME_LOG))
|
||||
return new LogCriteria(fieldValue);
|
||||
else
|
||||
return new ParamCriteria(fieldName, fieldValue, operator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Criteria<RetryContext> visitOrCriteria(OrCriteriaContext ctx) {
|
||||
List<Criteria<RetryContext>> childCriterias = new ArrayList<>();
|
||||
for (CriteriaContext childCtx: ctx.criteria())
|
||||
childCriterias.add(visit(childCtx));
|
||||
return new OrCriteria<RetryContext>(childCriterias);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Criteria<RetryContext> visitAndCriteria(AndCriteriaContext ctx) {
|
||||
List<Criteria<RetryContext>> childCriterias = new ArrayList<>();
|
||||
for (CriteriaContext childCtx: ctx.criteria())
|
||||
childCriterias.add(visit(childCtx));
|
||||
return new AndCriteria<RetryContext>(childCriterias);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Criteria<RetryContext> visitNotCriteria(NotCriteriaContext ctx) {
|
||||
return new NotCriteria<RetryContext>(visit(ctx.criteria()));
|
||||
}
|
||||
|
||||
}.visit(conditionContext.criteria());
|
||||
|
||||
return new RetryCondition(criteria);
|
||||
}
|
||||
|
||||
|
||||
@ -7,15 +7,14 @@ import java.util.Map;
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.buildspec.param.spec.ParamSpec;
|
||||
import io.onedev.server.buildspec.param.spec.choiceparam.defaultmultivalueprovider.DefaultMultiValueProvider;
|
||||
import io.onedev.server.buildspec.param.spec.choiceparam.defaultvalueprovider.DefaultValueProvider;
|
||||
import io.onedev.server.buildspecmodel.inputspec.choiceinput.ChoiceInput;
|
||||
import io.onedev.server.buildspecmodel.inputspec.choiceinput.choiceprovider.ChoiceProvider;
|
||||
import io.onedev.server.buildspecmodel.inputspec.choiceinput.choiceprovider.SpecifiedChoices;
|
||||
import io.onedev.server.util.EditContext;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
|
||||
@Editable(order=145, name= ParamSpec.ENUMERATION)
|
||||
public class ChoiceParam extends ParamSpec {
|
||||
@ -39,8 +38,8 @@ public class ChoiceParam extends ParamSpec {
|
||||
this.choiceProvider = choiceProvider;
|
||||
}
|
||||
|
||||
@ShowCondition("isDefaultValueProviderVisible")
|
||||
@Editable(order=1100, name="Default Value", placeholder="No default value")
|
||||
@DependsOn(property="allowMultiple", value="false")
|
||||
@Valid
|
||||
public DefaultValueProvider getDefaultValueProvider() {
|
||||
return defaultValueProvider;
|
||||
@ -50,13 +49,8 @@ public class ChoiceParam extends ParamSpec {
|
||||
this.defaultValueProvider = defaultValueProvider;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isDefaultValueProviderVisible() {
|
||||
return EditContext.get().getInputValue("allowMultiple").equals(false);
|
||||
}
|
||||
|
||||
@ShowCondition("isDefaultMultiValueProviderVisible")
|
||||
@Editable(order=1100, name="Default Value", placeholder="No default value")
|
||||
@DependsOn(property="allowMultiple")
|
||||
@Valid
|
||||
public DefaultMultiValueProvider getDefaultMultiValueProvider() {
|
||||
return defaultMultiValueProvider;
|
||||
@ -66,11 +60,6 @@ public class ChoiceParam extends ParamSpec {
|
||||
this.defaultMultiValueProvider = defaultMultiValueProvider;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isDefaultMultiValueProviderVisible() {
|
||||
return EditContext.get().getInputValue("allowMultiple").equals(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getPossibleValues() {
|
||||
return ChoiceInput.getPossibleValues(choiceProvider);
|
||||
|
||||
@ -6,15 +6,14 @@ import java.util.Map;
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.buildspec.param.spec.ParamSpec;
|
||||
import io.onedev.server.buildspec.param.spec.userchoiceparam.defaultmultivalueprovider.DefaultMultiValueProvider;
|
||||
import io.onedev.server.buildspec.param.spec.userchoiceparam.defaultvalueprovider.DefaultValueProvider;
|
||||
import io.onedev.server.buildspecmodel.inputspec.userchoiceinput.UserChoiceInput;
|
||||
import io.onedev.server.buildspecmodel.inputspec.userchoiceinput.choiceprovider.AllUsers;
|
||||
import io.onedev.server.buildspecmodel.inputspec.userchoiceinput.choiceprovider.ChoiceProvider;
|
||||
import io.onedev.server.util.EditContext;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
|
||||
@Editable(order=150, name= ParamSpec.USER)
|
||||
public class UserChoiceParam extends ParamSpec {
|
||||
@ -39,7 +38,7 @@ public class UserChoiceParam extends ParamSpec {
|
||||
}
|
||||
|
||||
@Editable(order=1100, name="Default Value", placeholder="No default value")
|
||||
@ShowCondition("isDefaultValueProviderVisible")
|
||||
@DependsOn(property="allowMultiple", value="false")
|
||||
@Valid
|
||||
public DefaultValueProvider getDefaultValueProvider() {
|
||||
return defaultValueProvider;
|
||||
@ -49,13 +48,8 @@ public class UserChoiceParam extends ParamSpec {
|
||||
this.defaultValueProvider = defaultValueProvider;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isDefaultValueProviderVisible() {
|
||||
return EditContext.get().getInputValue("allowMultiple").equals(false);
|
||||
}
|
||||
|
||||
@ShowCondition("isDefaultMultiValueProviderVisible")
|
||||
@Editable(order=1100, name="Default Value", placeholder="No default value")
|
||||
@DependsOn(property="allowMultiple")
|
||||
@Valid
|
||||
public DefaultMultiValueProvider getDefaultMultiValueProvider() {
|
||||
return defaultMultiValueProvider;
|
||||
@ -65,11 +59,6 @@ public class UserChoiceParam extends ParamSpec {
|
||||
this.defaultMultiValueProvider = defaultMultiValueProvider;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isDefaultMultiValueProviderVisible() {
|
||||
return EditContext.get().getInputValue("allowMultiple").equals(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getPossibleValues() {
|
||||
return UserChoiceInput.getPossibleValues();
|
||||
|
||||
@ -11,10 +11,10 @@ import javax.validation.constraints.NotNull;
|
||||
|
||||
import io.onedev.commons.codeassist.InputSuggestion;
|
||||
import io.onedev.k8shelper.StepFacade;
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.Interpolative;
|
||||
import io.onedev.server.annotation.RegEx;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
import io.onedev.server.buildspec.BuildSpec;
|
||||
import io.onedev.server.buildspec.job.EnvVar;
|
||||
import io.onedev.server.buildspec.param.ParamCombination;
|
||||
@ -23,7 +23,6 @@ import io.onedev.server.buildspec.step.commandinterpreter.Interpreter;
|
||||
import io.onedev.server.model.Build;
|
||||
import io.onedev.server.model.support.administration.jobexecutor.DockerAware;
|
||||
import io.onedev.server.model.support.administration.jobexecutor.JobExecutor;
|
||||
import io.onedev.server.util.EditContext;
|
||||
|
||||
@Editable(order=100, name="Execute Commands")
|
||||
public class CommandStep extends Step {
|
||||
@ -57,14 +56,9 @@ public class CommandStep extends Step {
|
||||
public void setRunInContainer(boolean runInContainer) {
|
||||
this.runInContainer = runInContainer;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isRunInContainerEnabled() {
|
||||
return (boolean) EditContext.get().getInputValue("runInContainer");
|
||||
}
|
||||
|
||||
@Editable(order=100, name="container:image", description="Specify container image to execute commands inside")
|
||||
@ShowCondition("isRunInContainerEnabled")
|
||||
@DependsOn(property="runInContainer")
|
||||
@Interpolative(variableSuggester="suggestVariables")
|
||||
@NotEmpty
|
||||
public String getImage() {
|
||||
@ -92,7 +86,7 @@ public class CommandStep extends Step {
|
||||
@Editable(order=8000, name="Run As", group = "More Settings", placeholder = "root", description = "Optionally specify uid:gid to run container as. " +
|
||||
"<b class='text-warning'>Note:</b> This setting should be left empty if container runtime is rootless or " +
|
||||
"using user namespace remapping")
|
||||
@ShowCondition("isRunInContainerEnabled")
|
||||
@DependsOn(property="runInContainer")
|
||||
@RegEx(pattern="\\d+:\\d+", message = "Should be specified in form of <uid>:<gid>")
|
||||
public String getRunAs() {
|
||||
return runAs;
|
||||
@ -105,7 +99,7 @@ public class CommandStep extends Step {
|
||||
@Editable(order=8500, group="More Settings", description="Optionally specify registry logins to override " +
|
||||
"those defined in job executor. For built-in registry, use <code>@server_url@</code> for registry url, " +
|
||||
"<code>@job_token@</code> for user name, and access token secret for password secret")
|
||||
@ShowCondition("isRunInContainerEnabled")
|
||||
@DependsOn(property="runInContainer")
|
||||
public List<RegistryLogin> getRegistryLogins() {
|
||||
return registryLogins;
|
||||
}
|
||||
@ -125,7 +119,7 @@ public class CommandStep extends Step {
|
||||
}
|
||||
|
||||
@Editable(order=10000, name="Enable TTY Mode", group = "More Settings", description=USE_TTY_HELP)
|
||||
@ShowCondition("isRunInContainerEnabled")
|
||||
@DependsOn(property="runInContainer")
|
||||
public boolean isUseTTY() {
|
||||
return useTTY;
|
||||
}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
package io.onedev.server.buildspec.step;
|
||||
|
||||
import static io.onedev.k8shelper.SetupCacheFacade.UploadStrategy.UPLOAD_IF_CHANGED;
|
||||
import static io.onedev.k8shelper.SetupCacheFacade.UploadStrategy.UPLOAD_IF_NOT_HIT;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
@ -15,16 +14,15 @@ import io.onedev.commons.codeassist.InputSuggestion;
|
||||
import io.onedev.k8shelper.SetupCacheFacade;
|
||||
import io.onedev.k8shelper.StepFacade;
|
||||
import io.onedev.server.annotation.ChoiceProvider;
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.Interpolative;
|
||||
import io.onedev.server.annotation.ProjectChoice;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
import io.onedev.server.buildspec.BuildSpec;
|
||||
import io.onedev.server.buildspec.param.ParamCombination;
|
||||
import io.onedev.server.model.Build;
|
||||
import io.onedev.server.model.Project;
|
||||
import io.onedev.server.model.support.administration.jobexecutor.JobExecutor;
|
||||
import io.onedev.server.util.EditContext;
|
||||
|
||||
@Editable(order=55, name="Set Up Cache", description = "Set up job cache to speed up job execution. " +
|
||||
"Check <a href='https://docs.onedev.io/tutorials/cicd/job-cache' target='_blank'>this tutorial</a> " +
|
||||
@ -103,7 +101,7 @@ public class SetupCacheStep extends Step {
|
||||
"detect cache changes. Use '**', '*' or '?' for <a href='https://docs.onedev.io/appendix/path-wildcard' target='_blank'>path wildcard match</a>. " +
|
||||
"Multiple files should be separated by space, and single file containing space should be quoted")
|
||||
@Interpolative(variableSuggester="suggestVariables")
|
||||
@ShowCondition("isUploadIfChanged")
|
||||
@DependsOn(property="uploadStrategy", value="UPLOAD_IF_CHANGED")
|
||||
public String getChangeDetectionExcludes() {
|
||||
return changeDetectionExcludes;
|
||||
}
|
||||
@ -111,11 +109,6 @@ public class SetupCacheStep extends Step {
|
||||
public void setChangeDetectionExcludes(String changeDetectionExcludes) {
|
||||
this.changeDetectionExcludes = changeDetectionExcludes;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isUploadIfChanged() {
|
||||
return UPLOAD_IF_CHANGED == EditContext.get().getInputValue("uploadStrategy");
|
||||
}
|
||||
|
||||
@Editable(order=450, name="Upload to Project", placeholder = "Current project", description = "In case cache needs to be uploaded, this property " +
|
||||
"specifies target project for the upload. Leave empty for current project")
|
||||
|
||||
@ -8256,4 +8256,25 @@ public class DataMigrator {
|
||||
}
|
||||
}
|
||||
|
||||
private void migrate209(File dataDir, Stack<Integer> versions) {
|
||||
for (File file : dataDir.listFiles()) {
|
||||
if (file.getName().startsWith("Settings.xml")) {
|
||||
VersionedXmlDoc dom = VersionedXmlDoc.fromFile(file);
|
||||
for (Element element : dom.getRootElement().elements()) {
|
||||
String key = element.elementTextTrim("key");
|
||||
if (key.equals("BRANDING")) {
|
||||
Element valueElement = element.element("value");
|
||||
if (valueElement != null) {
|
||||
Element urlElement = valueElement.element("url");
|
||||
if (urlElement != null) {
|
||||
urlElement.detach();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dom.writeToFile(file, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,12 +1,22 @@
|
||||
package io.onedev.server.data.migration;
|
||||
|
||||
import edu.emory.mathcs.backport.java.util.Collections;
|
||||
import io.onedev.commons.loader.ImplementationRegistry;
|
||||
import io.onedev.commons.utils.ClassUtils;
|
||||
import io.onedev.commons.utils.ExplicitException;
|
||||
import io.onedev.server.OneDev;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.util.BeanUtils;
|
||||
import java.beans.IntrospectionException;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.proxy.HibernateProxyHelper;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.DumperOptions.FlowStyle;
|
||||
@ -18,19 +28,22 @@ import org.yaml.snakeyaml.introspector.BeanAccess;
|
||||
import org.yaml.snakeyaml.introspector.MethodProperty;
|
||||
import org.yaml.snakeyaml.introspector.Property;
|
||||
import org.yaml.snakeyaml.introspector.PropertyUtils;
|
||||
import org.yaml.snakeyaml.nodes.*;
|
||||
import org.yaml.snakeyaml.nodes.MappingNode;
|
||||
import org.yaml.snakeyaml.nodes.Node;
|
||||
import org.yaml.snakeyaml.nodes.NodeTuple;
|
||||
import org.yaml.snakeyaml.nodes.ScalarNode;
|
||||
import org.yaml.snakeyaml.nodes.Tag;
|
||||
import org.yaml.snakeyaml.representer.Representer;
|
||||
import org.yaml.snakeyaml.resolver.Resolver;
|
||||
import org.yaml.snakeyaml.serializer.Serializer;
|
||||
|
||||
import java.beans.IntrospectionException;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import edu.emory.mathcs.backport.java.util.Collections;
|
||||
import io.onedev.commons.loader.ImplementationRegistry;
|
||||
import io.onedev.commons.utils.ClassUtils;
|
||||
import io.onedev.commons.utils.ExplicitException;
|
||||
import io.onedev.server.OneDev;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.util.BeanUtils;
|
||||
|
||||
public class VersionedYamlDoc extends MappingNode {
|
||||
|
||||
@ -96,7 +109,7 @@ public class VersionedYamlDoc extends MappingNode {
|
||||
getValue().add(0, new NodeTuple(keyNode, versionNode));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String toYaml() {
|
||||
StringWriter writer = new StringWriter();
|
||||
DumperOptions dumperOptions = new DumperOptions();
|
||||
@ -122,6 +135,12 @@ public class VersionedYamlDoc extends MappingNode {
|
||||
public Object construct(Node node) {
|
||||
return constructDocument(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String constructScalar(ScalarNode node) {
|
||||
String value = super.constructScalar(node);
|
||||
return (value != null && value.isEmpty()) ? null : value;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> getClassForNode(Node node) {
|
||||
@ -191,6 +210,8 @@ public class VersionedYamlDoc extends MappingNode {
|
||||
Method setter = BeanUtils.findSetter(getter);
|
||||
if (editable != null && setter != null) {
|
||||
String propertyName = BeanUtils.getPropertyName(getter);
|
||||
if (propertyName.equals("type"))
|
||||
throw new ExplicitException("Property 'type' is reserved (class: " + type.getName() + ")");
|
||||
try {
|
||||
properties.add(new MethodProperty(new PropertyDescriptor(propertyName, getter, setter)));
|
||||
} catch (IntrospectionException e) {
|
||||
|
||||
@ -45,6 +45,9 @@ public interface BuildManager extends EntityManager<Build> {
|
||||
@Nullable String refName, @Nullable Optional<PullRequest> request,
|
||||
@Nullable Optional<Issue> issue, Map<String, List<String>> params);
|
||||
|
||||
@Nullable
|
||||
Build findPreviousSuccessfulSimilar(Build build);
|
||||
|
||||
Collection<Build> query(Project project, ObjectId commitId, @Nullable String jobName);
|
||||
|
||||
Collection<Build> query(Project project, ObjectId commitId);
|
||||
|
||||
@ -328,6 +328,32 @@ public class DefaultBuildManager extends BaseEntityManager<Build> implements Bui
|
||||
return getSession().createQuery(query).list();
|
||||
}
|
||||
|
||||
@Sessional
|
||||
@Override
|
||||
public Build findPreviousSuccessfulSimilar(Build build) {
|
||||
CriteriaBuilder builder = getSession().getCriteriaBuilder();
|
||||
CriteriaQuery<Build> query = builder.createQuery(Build.class);
|
||||
Root<Build> root = query.from(Build.class);
|
||||
|
||||
List<Predicate> predicates = new ArrayList<>();
|
||||
predicates.add(builder.equal(root.get(Build.PROP_PROJECT), build.getProject()));
|
||||
predicates.add(builder.equal(root.get(Build.PROP_JOB_NAME), build.getJobName()));
|
||||
predicates.add(builder.equal(root.get(Build.PROP_STATUS), Build.Status.SUCCESSFUL));
|
||||
predicates.add(builder.lessThan(root.get(Build.PROP_NUMBER), build.getNumber()));
|
||||
|
||||
var paramPredicate = getPredicate(root, builder, build.getParamMap());
|
||||
if (paramPredicate != null)
|
||||
predicates.add(paramPredicate);
|
||||
|
||||
query.where(predicates.toArray(new Predicate[0]));
|
||||
query.orderBy(builder.desc(root.get(Build.PROP_NUMBER)));
|
||||
|
||||
return getSession().createQuery(query)
|
||||
.setFirstResult(0)
|
||||
.setMaxResults(1)
|
||||
.uniqueResult();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Sessional
|
||||
@Override
|
||||
|
||||
@ -286,7 +286,7 @@ public class DefaultJobManager implements JobManager, Runnable, CodePullAuthoriz
|
||||
for (ConstraintViolation<?> violation : validator.validate(buildSpec)) {
|
||||
String message = String.format("Error validating build spec (project: %s, commit: %s, location: %s, message: %s)",
|
||||
project.getPath(), commitId.name(), violation.getPropertyPath(), violation.getMessage());
|
||||
throw new ExplicitException(message);
|
||||
throw new ValidationException(message);
|
||||
}
|
||||
} finally {
|
||||
Project.pop();
|
||||
@ -703,19 +703,23 @@ public class DefaultJobManager implements JobManager, Runnable, CodePullAuthoriz
|
||||
private boolean checkRetry(Job job, JobContext jobContext, TaskLogger jobLogger,
|
||||
@Nullable Throwable throwable, int retried) {
|
||||
if (retried < job.getMaxRetries() && sessionManager.call(() -> {
|
||||
RetryCondition retryCondition = RetryCondition.parse(job, job.getRetryCondition());
|
||||
AtomicReference<String> errorMessage = new AtomicReference<>(null);
|
||||
if (throwable != null) {
|
||||
log(throwable, new TaskLogger() {
|
||||
if (job.getRetryCondition() != null) {
|
||||
RetryCondition retryCondition = RetryCondition.parse(job, job.getRetryCondition());
|
||||
AtomicReference<String> errorMessage = new AtomicReference<>(null);
|
||||
if (throwable != null) {
|
||||
log(throwable, new TaskLogger() {
|
||||
|
||||
@Override
|
||||
public void log(String message, String sessionId) {
|
||||
errorMessage.set(message);
|
||||
}
|
||||
@Override
|
||||
public void log(String message, String sessionId) {
|
||||
errorMessage.set(message);
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
return retryCondition.matches(new RetryContext(buildManager.load(jobContext.getBuildId()), errorMessage.get()));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return retryCondition.matches(new RetryContext(buildManager.load(jobContext.getBuildId()), errorMessage.get()));
|
||||
})) {
|
||||
if (throwable != null)
|
||||
log(throwable, jobLogger);
|
||||
|
||||
@ -105,7 +105,6 @@ import io.onedev.server.model.PullRequestComment;
|
||||
import io.onedev.server.model.PullRequestWatch;
|
||||
import io.onedev.server.model.Setting;
|
||||
import io.onedev.server.model.User;
|
||||
import io.onedev.server.model.support.administration.BrandingSetting;
|
||||
import io.onedev.server.model.support.administration.GlobalIssueSetting;
|
||||
import io.onedev.server.model.support.administration.IssueCreationSetting;
|
||||
import io.onedev.server.model.support.administration.emailtemplates.EmailTemplates;
|
||||
@ -330,7 +329,7 @@ public class DefaultMailManager implements MailManager, Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
if (senderName == null || senderName.equalsIgnoreCase(BrandingSetting.DEFAULT_NAME))
|
||||
if (senderName == null || senderName.equalsIgnoreCase("onedev"))
|
||||
senderName = getQuoteMark();
|
||||
else
|
||||
senderName += " " + getQuoteMark();
|
||||
|
||||
@ -15,14 +15,13 @@ import org.hibernate.annotations.Cache;
|
||||
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.Multiline;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
import io.onedev.server.security.permission.BasePermission;
|
||||
import io.onedev.server.security.permission.CreateRootProjects;
|
||||
import io.onedev.server.security.permission.ProjectPermission;
|
||||
import io.onedev.server.security.permission.SystemAdministration;
|
||||
import io.onedev.server.util.EditContext;
|
||||
import io.onedev.server.util.facade.GroupFacade;
|
||||
import io.onedev.server.util.facade.UserFacade;
|
||||
|
||||
@ -91,13 +90,8 @@ public class Group extends AbstractEntity implements BasePermission {
|
||||
this.administrator = administrator;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isAdministratorDisabled() {
|
||||
return !(boolean) EditContext.get().getInputValue("administrator");
|
||||
}
|
||||
|
||||
@Editable(order=350, name="Can Create Root Projects", description="Whether or not to allow creating root projects (project without parent)")
|
||||
@ShowCondition("isAdministratorDisabled")
|
||||
@DependsOn(property="administrator", value="false")
|
||||
public boolean isCreateRootProjects() {
|
||||
return createRootProjects;
|
||||
}
|
||||
|
||||
@ -71,11 +71,11 @@ import io.onedev.commons.utils.match.Matcher;
|
||||
import io.onedev.commons.utils.match.PathMatcher;
|
||||
import io.onedev.commons.utils.match.StringMatcher;
|
||||
import io.onedev.server.OneDev;
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.Markdown;
|
||||
import io.onedev.server.annotation.ProjectKey;
|
||||
import io.onedev.server.annotation.ProjectName;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
import io.onedev.server.annotation.SubscriptionRequired;
|
||||
import io.onedev.server.buildspec.BuildSpec;
|
||||
import io.onedev.server.entitymanager.BuildManager;
|
||||
@ -129,7 +129,6 @@ import io.onedev.server.model.support.pullrequest.ProjectPullRequestSetting;
|
||||
import io.onedev.server.search.entity.SortField;
|
||||
import io.onedev.server.security.SecurityUtils;
|
||||
import io.onedev.server.util.ComponentContext;
|
||||
import io.onedev.server.util.EditContext;
|
||||
import io.onedev.server.util.StatusInfo;
|
||||
import io.onedev.server.util.diff.WhitespaceOption;
|
||||
import io.onedev.server.util.facade.ProjectFacade;
|
||||
@ -1022,7 +1021,7 @@ public class Project extends AbstractEntity implements LabelSupport<ProjectLabel
|
||||
}
|
||||
|
||||
@Editable(order=350, descriptionProvider = "getTimeTrackingDescription")
|
||||
@ShowCondition("isIssueManagementEnabled")
|
||||
@DependsOn(property="issueManagement")
|
||||
@SubscriptionRequired
|
||||
public boolean isTimeTracking() {
|
||||
return timeTracking;
|
||||
@ -1041,11 +1040,6 @@ public class Project extends AbstractEntity implements LabelSupport<ProjectLabel
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isIssueManagementEnabled() {
|
||||
return (boolean) EditContext.get().getInputValue(PROP_ISSUE_MANAGEMENT);
|
||||
}
|
||||
|
||||
@Editable(order=400, name="Package Management", descriptionProvider = "getPackManagementDescription")
|
||||
public boolean isPackManagement() {
|
||||
return packManagement;
|
||||
|
||||
@ -26,6 +26,7 @@ import com.google.common.collect.Lists;
|
||||
|
||||
import io.onedev.server.OneDev;
|
||||
import io.onedev.server.annotation.ChoiceProvider;
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.Multiline;
|
||||
import io.onedev.server.annotation.RoleName;
|
||||
@ -178,7 +179,7 @@ public class Role extends AbstractEntity implements BasePermission {
|
||||
}
|
||||
|
||||
@Editable(order=210, name="Create Child Projects", description="Create child projects under a project")
|
||||
@ShowCondition("isManageProjectDisabled")
|
||||
@DependsOn(property="manageProject", value="false")
|
||||
public boolean isCreateChildren() {
|
||||
return createChildren;
|
||||
}
|
||||
@ -187,14 +188,9 @@ public class Role extends AbstractEntity implements BasePermission {
|
||||
this.createChildren = createChildren;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isManageProjectDisabled() {
|
||||
return !(boolean)EditContext.get().getInputValue("manageProject");
|
||||
}
|
||||
|
||||
@Editable(order=250, name="Pull Request Management", description="Pull request administrative permission inside a project, "
|
||||
+ "including batch operations over multiple pull requests")
|
||||
@ShowCondition("isManageProjectDisabled")
|
||||
@DependsOn(property="manageProject", value="false")
|
||||
public boolean isManagePullRequests() {
|
||||
return managePullRequests;
|
||||
}
|
||||
@ -205,7 +201,7 @@ public class Role extends AbstractEntity implements BasePermission {
|
||||
|
||||
@Editable(order=260, name="Code Comment Management", description="Code comment administrative permission inside a project, "
|
||||
+ "including batch operations over multiple code comments")
|
||||
@ShowCondition("isManageProjectDisabled")
|
||||
@DependsOn(property="manageProject", value="false")
|
||||
public boolean isManageCodeComments() {
|
||||
return manageCodeComments;
|
||||
}
|
||||
@ -243,7 +239,7 @@ public class Role extends AbstractEntity implements BasePermission {
|
||||
|
||||
@Editable(order=400, name="Issue Management", description="Issue administrative permission inside a project, including batch "
|
||||
+ "operations over multiple issues")
|
||||
@ShowCondition("isManageProjectDisabled")
|
||||
@DependsOn(property="manageProject", value="false")
|
||||
public boolean isManageIssues() {
|
||||
return manageIssues;
|
||||
}
|
||||
@ -251,14 +247,9 @@ public class Role extends AbstractEntity implements BasePermission {
|
||||
public void setManageIssues(boolean manageIssues) {
|
||||
this.manageIssues = manageIssues;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isManageIssuesDisabled() {
|
||||
return !(boolean)EditContext.get().getInputValue("manageIssues");
|
||||
}
|
||||
|
||||
|
||||
@Editable(order=450, description="This permission enables one to access confidential issues")
|
||||
@ShowCondition("isManageIssuesDisabled")
|
||||
@DependsOn(property="manageIssues", value="false")
|
||||
public boolean isAccessConfidentialIssues() {
|
||||
return accessConfidentialIssues;
|
||||
}
|
||||
@ -278,7 +269,7 @@ public class Role extends AbstractEntity implements BasePermission {
|
||||
}
|
||||
|
||||
@Editable(order=500, description = "This permission enables one to schedule issues into iterations")
|
||||
@ShowCondition("isManageIssuesDisabled")
|
||||
@DependsOn(property="manageIssues", value="false")
|
||||
public boolean isScheduleIssues() {
|
||||
return scheduleIssues;
|
||||
}
|
||||
@ -288,7 +279,7 @@ public class Role extends AbstractEntity implements BasePermission {
|
||||
}
|
||||
|
||||
@Editable(order=600, description="Optionally specify custom fields allowed to edit when open new issues")
|
||||
@ShowCondition("isManageIssuesDisabled")
|
||||
@DependsOn(property="manageIssues", value="false")
|
||||
@NotNull
|
||||
public IssueFieldSet getEditableIssueFields() {
|
||||
return editableIssueFields;
|
||||
@ -304,7 +295,7 @@ public class Role extends AbstractEntity implements BasePermission {
|
||||
}
|
||||
|
||||
@Editable(order=625, placeholder="None", description="Optionally specify issue links allowed to edit")
|
||||
@ShowCondition("isManageIssuesDisabled")
|
||||
@DependsOn(property="manageIssues", value="false")
|
||||
@ChoiceProvider(value="getIssueLinkChoices", displayNames = "getIssueLinkDisplayNames")
|
||||
public List<String> getEditableIssueLinks() {
|
||||
return editableIssueLinks;
|
||||
@ -329,7 +320,7 @@ public class Role extends AbstractEntity implements BasePermission {
|
||||
|
||||
@Editable(order=650, name="Build Management", description="Build administrative permission for all jobs inside a project, "
|
||||
+ "including batch operations over multiple builds")
|
||||
@ShowCondition("isManageProjectDisabled")
|
||||
@DependsOn(property="manageProject", value="false")
|
||||
public boolean isManageBuilds() {
|
||||
return manageBuilds;
|
||||
}
|
||||
@ -338,14 +329,9 @@ public class Role extends AbstractEntity implements BasePermission {
|
||||
this.manageBuilds = manageBuilds;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isManageBuildsDisabled() {
|
||||
return !(boolean)EditContext.get().getInputValue("manageBuilds");
|
||||
}
|
||||
|
||||
@Editable(order=675, description = "Enable to allow to upload build cache generated during CI/CD job. " +
|
||||
"Uploaded cache can be used by subsequent builds of the project as long as cache key matches")
|
||||
@ShowCondition("isManageBuildsDisabled")
|
||||
@DependsOn(property="manageBuilds", value="false")
|
||||
public boolean isUploadCache() {
|
||||
return uploadCache;
|
||||
}
|
||||
@ -355,7 +341,7 @@ public class Role extends AbstractEntity implements BasePermission {
|
||||
}
|
||||
|
||||
@Editable(order=700)
|
||||
@ShowCondition("isManageBuildsDisabled")
|
||||
@DependsOn(property="manageBuilds", value="false")
|
||||
public List<JobPrivilege> getJobPrivileges() {
|
||||
return jobPrivileges;
|
||||
}
|
||||
|
||||
@ -38,9 +38,9 @@ import com.google.common.base.MoreObjects;
|
||||
import edu.emory.mathcs.backport.java.util.Collections;
|
||||
import io.onedev.commons.utils.ExplicitException;
|
||||
import io.onedev.server.OneDev;
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.Password;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
import io.onedev.server.annotation.SubscriptionRequired;
|
||||
import io.onedev.server.annotation.UserName;
|
||||
import io.onedev.server.entitymanager.EmailAddressManager;
|
||||
@ -54,7 +54,6 @@ import io.onedev.server.model.support.issue.NamedIssueQuery;
|
||||
import io.onedev.server.model.support.pack.NamedPackQuery;
|
||||
import io.onedev.server.model.support.pullrequest.NamedPullRequestQuery;
|
||||
import io.onedev.server.security.SecurityUtils;
|
||||
import io.onedev.server.util.EditContext;
|
||||
import io.onedev.server.util.facade.UserFacade;
|
||||
import io.onedev.server.util.watch.QuerySubscriptionSupport;
|
||||
import io.onedev.server.util.watch.QueryWatchSupport;
|
||||
@ -564,11 +563,6 @@ public class User extends AbstractEntity implements AuthenticationInfo {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isServiceAccountDisabled() {
|
||||
return !(Boolean) EditContext.get().getInputValue(PROP_SERVICE_ACCOUNT);
|
||||
}
|
||||
|
||||
@Editable(name="Login Name", order=100)
|
||||
@UserName
|
||||
@NotEmpty
|
||||
@ -586,7 +580,7 @@ public class User extends AbstractEntity implements AuthenticationInfo {
|
||||
* time
|
||||
*/
|
||||
@Editable(order=150)
|
||||
@ShowCondition("isServiceAccountDisabled")
|
||||
@DependsOn(property="serviceAccount", value="false")
|
||||
@Password(checkPolicy=true, autoComplete="new-password")
|
||||
@NotEmpty
|
||||
@Nullable
|
||||
@ -622,7 +616,7 @@ public class User extends AbstractEntity implements AuthenticationInfo {
|
||||
}
|
||||
|
||||
@Editable(order=400, name="Notify Own Events", description = "Whether or not to send notifications for events generated by yourself")
|
||||
@ShowCondition("isServiceAccountDisabled")
|
||||
@DependsOn(property="serviceAccount", value="false")
|
||||
public boolean isNotifyOwnEvents() {
|
||||
return notifyOwnEvents;
|
||||
}
|
||||
|
||||
@ -5,15 +5,9 @@ import java.io.Serializable;
|
||||
public class BrandingSetting implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final String DEFAULT_NAME = "OneDev";
|
||||
|
||||
public static final String DEFAULT_URL = "https://onedev.io";
|
||||
|
||||
private String name = DEFAULT_NAME;
|
||||
|
||||
private String url = DEFAULT_URL;
|
||||
|
||||
|
||||
private String name = "OneDev";
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
@ -21,21 +15,5 @@ public class BrandingSetting implements Serializable {
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public static boolean isOEM(String brandName) {
|
||||
return "GitOn".equals(brandName);
|
||||
}
|
||||
|
||||
public boolean isOEM() {
|
||||
return isOEM(getName());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1,18 +1,18 @@
|
||||
package io.onedev.server.model.support.administration;
|
||||
|
||||
import io.onedev.server.job.JobAuthorizationContext;
|
||||
import io.onedev.server.util.EditContext;
|
||||
import io.onedev.server.util.usage.Usage;
|
||||
import io.onedev.server.annotation.Code;
|
||||
import io.onedev.server.annotation.RegEx;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.JobMatch;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
import io.onedev.server.annotation.Code;
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.JobMatch;
|
||||
import io.onedev.server.annotation.RegEx;
|
||||
import io.onedev.server.job.JobAuthorizationContext;
|
||||
import io.onedev.server.util.usage.Usage;
|
||||
|
||||
@Editable
|
||||
public class GroovyScript implements Serializable {
|
||||
@ -60,13 +60,8 @@ public class GroovyScript implements Serializable {
|
||||
this.canBeUsedByBuildJobs = canBeUsedByBuildJobs;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isCanBeUsedByBuildJobsEnabled() {
|
||||
return (boolean) EditContext.get().getInputValue("canBeUsedByBuildJobs");
|
||||
}
|
||||
|
||||
@Editable(order=500, placeholder="Any job", description="Optionally specify jobs allowed to use this script")
|
||||
@ShowCondition("isCanBeUsedByBuildJobsEnabled")
|
||||
@DependsOn(property="canBeUsedByBuildJobs")
|
||||
@JobMatch(withProjectCriteria = true)
|
||||
public String getAuthorization() {
|
||||
return authorization;
|
||||
|
||||
@ -4,10 +4,9 @@ import io.onedev.server.OneDev;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.GroupChoice;
|
||||
import io.onedev.server.annotation.Patterns;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.entitymanager.GroupManager;
|
||||
import io.onedev.server.model.Group;
|
||||
import io.onedev.server.util.EditContext;
|
||||
import io.onedev.server.util.usage.Usage;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -60,7 +59,7 @@ public class SecuritySetting implements Serializable {
|
||||
|
||||
@Editable(order=225, name="Allowed Self Sign-Up Email Domain", placeholder = "Any domain", description = "Optionally specify allowed email domain for self sign-up users. Use '*' or '?' for pattern match")
|
||||
@Patterns
|
||||
@ShowCondition("isEnableSelfRegisterEnabled")
|
||||
@DependsOn(property="enableSelfRegister")
|
||||
public String getAllowedSelfRegisterEmailDomain() {
|
||||
return allowedSelfRegisterEmailDomain;
|
||||
}
|
||||
@ -69,11 +68,6 @@ public class SecuritySetting implements Serializable {
|
||||
this.allowedSelfRegisterEmailDomain = allowedSelfRegisterEmailDomain;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isEnableSelfRegisterEnabled() {
|
||||
return (boolean) EditContext.get().getInputValue("enableSelfRegister");
|
||||
}
|
||||
|
||||
@Editable(order=250, name="Enforce Password Policy", description="Enforce password policy for new users")
|
||||
public PasswordPolicy getPasswordPolicy() {
|
||||
return passwordPolicy;
|
||||
|
||||
@ -17,6 +17,7 @@ import com.google.common.base.Preconditions;
|
||||
import io.onedev.server.OneDev;
|
||||
import io.onedev.server.ServerConfig;
|
||||
import io.onedev.server.annotation.ClassValidating;
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
import io.onedev.server.git.location.CurlLocation;
|
||||
@ -167,7 +168,7 @@ public class SystemSetting implements Serializable, Validatable {
|
||||
}
|
||||
|
||||
@Editable(order=600, description="User avatar will be requested by appending a hash to this url")
|
||||
@ShowCondition("isUseAvatarServiceEnabled")
|
||||
@DependsOn(property="useAvatarService")
|
||||
@NotEmpty
|
||||
public String getAvatarServiceUrl() {
|
||||
return avatarServiceUrl;
|
||||
@ -177,11 +178,6 @@ public class SystemSetting implements Serializable, Validatable {
|
||||
this.avatarServiceUrl = avatarServiceUrl;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isUseAvatarServiceEnabled() {
|
||||
return (boolean) EditContext.get().getInputValue(PROP_USE_AVATAR_SERVICE);
|
||||
}
|
||||
|
||||
public String getEffectiveSshRootUrl() {
|
||||
if (getSshRootUrl() != null)
|
||||
return getSshRootUrl();
|
||||
|
||||
@ -8,10 +8,10 @@ import javax.validation.constraints.Pattern;
|
||||
import io.onedev.server.annotation.BuildQuery;
|
||||
import io.onedev.server.annotation.CodeCommentQuery;
|
||||
import io.onedev.server.annotation.CommitQuery;
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.IssueQuery;
|
||||
import io.onedev.server.annotation.PullRequestQuery;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
import io.onedev.server.event.project.ProjectEvent;
|
||||
import io.onedev.server.event.project.RefUpdated;
|
||||
import io.onedev.server.event.project.build.BuildEvent;
|
||||
@ -19,7 +19,6 @@ import io.onedev.server.event.project.codecomment.CodeCommentEvent;
|
||||
import io.onedev.server.event.project.issue.IssueEvent;
|
||||
import io.onedev.server.event.project.pullrequest.PullRequestEvent;
|
||||
import io.onedev.server.search.entity.issue.IssueQueryParseOption;
|
||||
import io.onedev.server.util.EditContext;
|
||||
|
||||
@Editable
|
||||
public class ChannelNotification implements Serializable {
|
||||
@ -70,7 +69,7 @@ public class ChannelNotification implements Serializable {
|
||||
|
||||
@Editable(order=200, name="Applicable Issues", placeholder="All")
|
||||
@IssueQuery(withOrder=false)
|
||||
@ShowCondition("isIssuesEnabled")
|
||||
@DependsOn(property="issues")
|
||||
public String getIssueQuery() {
|
||||
return issueQuery;
|
||||
}
|
||||
@ -79,11 +78,6 @@ public class ChannelNotification implements Serializable {
|
||||
this.issueQuery = issueQuery;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isIssuesEnabled() {
|
||||
return (boolean) EditContext.get().getInputValue("issues");
|
||||
}
|
||||
|
||||
@Editable(order=300, name="Notify Pull Request Events")
|
||||
public boolean isPullRequests() {
|
||||
return pullRequests;
|
||||
@ -95,7 +89,7 @@ public class ChannelNotification implements Serializable {
|
||||
|
||||
@Editable(order=400, name="Applicable Pull Requests", placeholder="All")
|
||||
@PullRequestQuery(withOrder=false)
|
||||
@ShowCondition("isPullRequestsEnabled")
|
||||
@DependsOn(property="pullRequests")
|
||||
public String getPullRequestQuery() {
|
||||
return pullRequestQuery;
|
||||
}
|
||||
@ -104,11 +98,6 @@ public class ChannelNotification implements Serializable {
|
||||
this.pullRequestQuery = pullRequestQuery;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isPullRequestsEnabled() {
|
||||
return (boolean) EditContext.get().getInputValue("pullRequests");
|
||||
}
|
||||
|
||||
@Editable(order=500, name="Notify Build Events")
|
||||
public boolean isBuilds() {
|
||||
return builds;
|
||||
@ -120,7 +109,7 @@ public class ChannelNotification implements Serializable {
|
||||
|
||||
@Editable(order=600, name="Applicable Builds", placeholder="All")
|
||||
@BuildQuery(withOrder=false, withUnfinishedCriteria=true)
|
||||
@ShowCondition("isBuildsEnabled")
|
||||
@DependsOn(property="builds")
|
||||
public String getBuildQuery() {
|
||||
return buildQuery;
|
||||
}
|
||||
@ -129,11 +118,6 @@ public class ChannelNotification implements Serializable {
|
||||
this.buildQuery = buildQuery;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isBuildsEnabled() {
|
||||
return (boolean) EditContext.get().getInputValue("builds");
|
||||
}
|
||||
|
||||
@Editable(order=700, name="Notify Code Push Events")
|
||||
public boolean isCodePush() {
|
||||
return codePush;
|
||||
@ -145,7 +129,7 @@ public class ChannelNotification implements Serializable {
|
||||
|
||||
@Editable(order=800, name="Applicable Commits", placeholder="All")
|
||||
@CommitQuery
|
||||
@ShowCondition("isCodePushEnabled")
|
||||
@DependsOn(property="codePush")
|
||||
public String getCommitQuery() {
|
||||
return commitQuery;
|
||||
}
|
||||
@ -154,11 +138,6 @@ public class ChannelNotification implements Serializable {
|
||||
this.commitQuery = commitQuery;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isCodePushEnabled() {
|
||||
return (boolean) EditContext.get().getInputValue("codePush");
|
||||
}
|
||||
|
||||
@Editable(order=900, name="Notify Code Comment Events")
|
||||
public boolean isCodeComments() {
|
||||
return codeComments;
|
||||
@ -170,7 +149,7 @@ public class ChannelNotification implements Serializable {
|
||||
|
||||
@Editable(order=1000, name="Applicable Code Comments", placeholder="All")
|
||||
@CodeCommentQuery(withOrder=false)
|
||||
@ShowCondition("isCodeCommentsEnabled")
|
||||
@DependsOn(property="codeComments")
|
||||
public String getCodeCommentQuery() {
|
||||
return codeCommentQuery;
|
||||
}
|
||||
@ -179,11 +158,6 @@ public class ChannelNotification implements Serializable {
|
||||
this.codeCommentQuery = codeCommentQuery;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isCodeCommentsEnabled() {
|
||||
return (boolean) EditContext.get().getInputValue("codeComments");
|
||||
}
|
||||
|
||||
public boolean matches(ProjectEvent event) {
|
||||
if (event instanceof IssueEvent) {
|
||||
if (isIssues()) {
|
||||
|
||||
@ -1,14 +1,36 @@
|
||||
package io.onedev.server.model.support.code;
|
||||
|
||||
import static java.util.regex.Pattern.CASE_INSENSITIVE;
|
||||
import static java.util.regex.Pattern.UNICODE_CHARACTER_CLASS;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Splitter;
|
||||
|
||||
import io.onedev.commons.codeassist.InputSuggestion;
|
||||
import io.onedev.commons.utils.match.PathMatcher;
|
||||
import io.onedev.server.OneDev;
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.JobChoice;
|
||||
import io.onedev.server.annotation.Patterns;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
import io.onedev.server.buildspec.BuildSpec;
|
||||
import io.onedev.server.entitymanager.BuildManager;
|
||||
import io.onedev.server.git.service.GitService;
|
||||
@ -16,26 +38,12 @@ import io.onedev.server.model.Build;
|
||||
import io.onedev.server.model.Build.Status;
|
||||
import io.onedev.server.model.Project;
|
||||
import io.onedev.server.model.User;
|
||||
import io.onedev.server.util.EditContext;
|
||||
import io.onedev.server.util.patternset.PatternSet;
|
||||
import io.onedev.server.util.reviewrequirement.ReviewRequirement;
|
||||
import io.onedev.server.util.usage.Usage;
|
||||
import io.onedev.server.util.usermatch.Anyone;
|
||||
import io.onedev.server.util.usermatch.UserMatch;
|
||||
import io.onedev.server.web.util.SuggestionUtils;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.regex.Pattern.CASE_INSENSITIVE;
|
||||
import static java.util.regex.Pattern.UNICODE_CHARACTER_CLASS;
|
||||
|
||||
@Editable
|
||||
public class BranchProtection implements Serializable {
|
||||
@ -166,14 +174,9 @@ public class BranchProtection implements Serializable {
|
||||
this.enforceConventionalCommits = enforceConventionalCommits;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isEnforceConventionalCommitsEnabled() {
|
||||
return (boolean) EditContext.get().getInputValue("enforceConventionalCommits");
|
||||
}
|
||||
|
||||
@Editable(order=380, placeholder = "Arbitrary type", description = "Optionally specify valid " +
|
||||
"types of conventional commits (hit ENTER to add value). Leave empty to allow arbitrary type")
|
||||
@ShowCondition("isEnforceConventionalCommitsEnabled")
|
||||
@DependsOn(property="enforceConventionalCommits")
|
||||
public List<String> getCommitTypes() {
|
||||
return commitTypes;
|
||||
}
|
||||
@ -184,7 +187,7 @@ public class BranchProtection implements Serializable {
|
||||
|
||||
@Editable(order=390, placeholder = "Arbitrary scope", description = "Optionally specify valid " +
|
||||
"scopes of conventional commits (hit ENTER to add value). Leave empty to allow arbitrary scope")
|
||||
@ShowCondition("isEnforceConventionalCommitsEnabled")
|
||||
@DependsOn(property="enforceConventionalCommits")
|
||||
public List<String> getCommitScopes() {
|
||||
return commitScopes;
|
||||
}
|
||||
@ -194,7 +197,7 @@ public class BranchProtection implements Serializable {
|
||||
}
|
||||
|
||||
@Editable(order=391)
|
||||
@ShowCondition("isEnforceConventionalCommitsEnabled")
|
||||
@DependsOn(property="enforceConventionalCommits")
|
||||
public boolean isCheckCommitMessageFooter() {
|
||||
return checkCommitMessageFooter;
|
||||
}
|
||||
@ -203,15 +206,10 @@ public class BranchProtection implements Serializable {
|
||||
this.checkCommitMessageFooter = checkCommitMessageFooter;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isCheckCommitMessageFooterEnabled() {
|
||||
return (boolean) EditContext.get().getInputValue("checkCommitMessageFooter");
|
||||
}
|
||||
|
||||
@Editable(order=393, description = "A " +
|
||||
"<a href='https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html'>Java regular expression</a> " +
|
||||
"to validate commit message footer")
|
||||
@ShowCondition("isCheckCommitMessageFooterEnabled")
|
||||
@DependsOn(property="checkCommitMessageFooter")
|
||||
@NotEmpty
|
||||
public String getCommitMessageFooterPattern() {
|
||||
return commitMessageFooterPattern;
|
||||
@ -223,7 +221,7 @@ public class BranchProtection implements Serializable {
|
||||
|
||||
@Editable(order=394, description = "Optionally specify applicable commit types for commit message footer check (hit ENTER to add value). " +
|
||||
"Leave empty to all types")
|
||||
@ShowCondition("isCheckCommitMessageFooterEnabled")
|
||||
@DependsOn(property="checkCommitMessageFooter")
|
||||
public List<String> getCommitTypesForFooterCheck() {
|
||||
return commitTypesForFooterCheck;
|
||||
}
|
||||
|
||||
@ -18,10 +18,9 @@ import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import io.onedev.server.OneDev;
|
||||
import io.onedev.server.annotation.ChoiceProvider;
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
import io.onedev.server.entitymanager.LinkSpecManager;
|
||||
import io.onedev.server.util.EditContext;
|
||||
import io.onedev.server.util.usage.Usage;
|
||||
|
||||
@Editable
|
||||
@ -51,15 +50,10 @@ public class TimeTrackingSetting implements Serializable {
|
||||
this.useHoursAndMinutesOnly = useHoursAndMinutesOnly;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isUseHoursAndMinutesOnlyDisabled() {
|
||||
return !(Boolean)EditContext.get().getInputValue("useHoursAndMinutesOnly");
|
||||
}
|
||||
|
||||
@Editable(order=100, description = "Specify working hours per day. This will affect " +
|
||||
"parsing and displaying of working periods. For instance <tt>1d</tt> is the " +
|
||||
"same as <tt>8h</tt> if this property is set to <tt>8</tt>")
|
||||
@ShowCondition("isUseHoursAndMinutesOnlyDisabled")
|
||||
@DependsOn(property="useHoursAndMinutesOnly", value="false")
|
||||
@Max(24)
|
||||
@Min(1)
|
||||
public int getHoursPerDay() {
|
||||
@ -73,7 +67,7 @@ public class TimeTrackingSetting implements Serializable {
|
||||
@Editable(order=200, description = "Specify working days per week. This will affect " +
|
||||
"parsing and displaying of working periods. For instance <tt>1w</tt> is the " +
|
||||
"same as <tt>5d</tt> if this property is set to <tt>5</tt>")
|
||||
@ShowCondition("isUseHoursAndMinutesOnlyDisabled")
|
||||
@DependsOn(property="useHoursAndMinutesOnly", value="false")
|
||||
@Max(7)
|
||||
@Min(1)
|
||||
public int getDaysPerWeek() {
|
||||
|
||||
@ -14,6 +14,7 @@ import org.apache.wicket.MarkupContainer;
|
||||
import io.onedev.commons.codeassist.InputSuggestion;
|
||||
import io.onedev.commons.utils.match.PathMatcher;
|
||||
import io.onedev.server.OneDev;
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.FieldName;
|
||||
import io.onedev.server.annotation.Multiline;
|
||||
@ -113,7 +114,7 @@ public abstract class FieldSpec extends InputSpec {
|
||||
}
|
||||
|
||||
@Editable(order=60)
|
||||
@io.onedev.server.annotation.ShowCondition("isNameOfEmptyValueVisible")
|
||||
@DependsOn(property="allowEmpty")
|
||||
@NotEmpty
|
||||
public String getNameOfEmptyValue() {
|
||||
return nameOfEmptyValue;
|
||||
@ -123,11 +124,6 @@ public abstract class FieldSpec extends InputSpec {
|
||||
this.nameOfEmptyValue = nameOfEmptyValue;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isNameOfEmptyValueVisible() {
|
||||
return (boolean) EditContext.get().getInputValue("allowEmpty");
|
||||
}
|
||||
|
||||
@Editable(order=10000, name="Include When Issue is Opened", description="Whether or not to include this field when issue is initially opened. " +
|
||||
"If not, you may include this field later when issue is transited to other states via issue transition rule")
|
||||
public boolean isPromptUponIssueOpen() {
|
||||
@ -138,16 +134,11 @@ public abstract class FieldSpec extends InputSpec {
|
||||
this.promptUponIssueOpen = promptUponIssueOpen;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isPromptUponIssueOpenEnabled() {
|
||||
return Boolean.TRUE.equals(EditContext.get().getInputValue("promptUponIssueOpen"));
|
||||
}
|
||||
|
||||
@Editable(order=10100, placeholder="All projects", description="Specify applicable projects for above option. "
|
||||
+ "Multiple projects should be separated by space. Use '**', '*' or '?' for "
|
||||
+ "<a href='https://docs.onedev.io/appendix/path-wildcard' target='_blank'>path wildcard match</a>. "
|
||||
+ "Prefix with '-' to exclude. Leave empty for all projects")
|
||||
@io.onedev.server.annotation.ShowCondition("isPromptUponIssueOpenEnabled")
|
||||
@DependsOn(property="promptUponIssueOpen")
|
||||
@Patterns(suggester="suggestProjects", path=true)
|
||||
public String getApplicableProjects() {
|
||||
return applicableProjects;
|
||||
|
||||
@ -7,16 +7,15 @@ import java.util.Map;
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.buildspecmodel.inputspec.choiceinput.ChoiceInput;
|
||||
import io.onedev.server.buildspecmodel.inputspec.choiceinput.choiceprovider.ChoiceProvider;
|
||||
import io.onedev.server.buildspecmodel.inputspec.choiceinput.choiceprovider.SpecifiedChoices;
|
||||
import io.onedev.server.model.support.issue.field.spec.FieldSpec;
|
||||
import io.onedev.server.model.support.issue.field.spec.choicefield.defaultmultivalueprovider.DefaultMultiValueProvider;
|
||||
import io.onedev.server.model.support.issue.field.spec.choicefield.defaultvalueprovider.DefaultValueProvider;
|
||||
import io.onedev.server.util.EditContext;
|
||||
import io.onedev.server.util.usage.Usage;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
|
||||
@Editable(order=145, name= FieldSpec.ENUMERATION)
|
||||
public class ChoiceField extends FieldSpec {
|
||||
@ -40,7 +39,7 @@ public class ChoiceField extends FieldSpec {
|
||||
this.choiceProvider = choiceProvider;
|
||||
}
|
||||
|
||||
@ShowCondition("isDefaultValueProviderVisible")
|
||||
@DependsOn(property="allowMultiple", value="false")
|
||||
@Editable(order=1100, name="Default Value", placeholder="No default value")
|
||||
@Valid
|
||||
public DefaultValueProvider getDefaultValueProvider() {
|
||||
@ -51,12 +50,7 @@ public class ChoiceField extends FieldSpec {
|
||||
this.defaultValueProvider = defaultValueProvider;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isDefaultValueProviderVisible() {
|
||||
return EditContext.get().getInputValue("allowMultiple").equals(false);
|
||||
}
|
||||
|
||||
@ShowCondition("isDefaultMultiValueProviderVisible")
|
||||
@DependsOn(property="allowMultiple")
|
||||
@Editable(order=1100, name="Default Value", placeholder="No default value")
|
||||
@Valid
|
||||
public DefaultMultiValueProvider getDefaultMultiValueProvider() {
|
||||
@ -67,11 +61,6 @@ public class ChoiceField extends FieldSpec {
|
||||
this.defaultMultiValueProvider = defaultMultiValueProvider;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isDefaultMultiValueProviderVisible() {
|
||||
return EditContext.get().getInputValue("allowMultiple").equals(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getPossibleValues() {
|
||||
return ChoiceInput.getPossibleValues(choiceProvider);
|
||||
|
||||
@ -1,25 +1,23 @@
|
||||
package io.onedev.server.model.support.issue.field.spec.userchoicefield;
|
||||
|
||||
import io.onedev.server.OneDev;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
import io.onedev.server.buildspecmodel.inputspec.userchoiceinput.UserChoiceInput;
|
||||
import io.onedev.server.buildspecmodel.inputspec.userchoiceinput.choiceprovider.AllUsers;
|
||||
import io.onedev.server.buildspecmodel.inputspec.userchoiceinput.choiceprovider.ChoiceProvider;
|
||||
import io.onedev.server.SubscriptionManager;
|
||||
import io.onedev.server.model.support.issue.field.spec.FieldSpec;
|
||||
import io.onedev.server.model.support.issue.field.spec.userchoicefield.defaultmultivalueprovider.DefaultMultiValueProvider;
|
||||
import io.onedev.server.model.support.issue.field.spec.userchoicefield.defaultmultivalueprovider.SpecifiedDefaultMultiValue;
|
||||
import io.onedev.server.model.support.issue.field.spec.userchoicefield.defaultvalueprovider.DefaultValueProvider;
|
||||
import io.onedev.server.model.support.issue.field.spec.userchoicefield.defaultvalueprovider.SpecifiedDefaultValue;
|
||||
import io.onedev.server.util.EditContext;
|
||||
import io.onedev.server.util.usage.Usage;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Editable(order=150, name= FieldSpec.USER)
|
||||
public class UserChoiceField extends FieldSpec {
|
||||
|
||||
@ -43,7 +41,7 @@ public class UserChoiceField extends FieldSpec {
|
||||
}
|
||||
|
||||
@Editable(order=1100, name="Default Value", placeholder="No default value")
|
||||
@ShowCondition("isDefaultValueProviderVisible")
|
||||
@DependsOn(property="allowMultiple", value="false")
|
||||
@Valid
|
||||
public DefaultValueProvider getDefaultValueProvider() {
|
||||
return defaultValueProvider;
|
||||
@ -53,13 +51,8 @@ public class UserChoiceField extends FieldSpec {
|
||||
this.defaultValueProvider = defaultValueProvider;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isDefaultValueProviderVisible() {
|
||||
return EditContext.get().getInputValue("allowMultiple").equals(false);
|
||||
}
|
||||
|
||||
@ShowCondition("isDefaultMultiValueProviderVisible")
|
||||
@Editable(order=1100, name="Default Value", placeholder="No default value")
|
||||
@DependsOn(property="allowMultiple")
|
||||
@Valid
|
||||
public DefaultMultiValueProvider getDefaultMultiValueProvider() {
|
||||
return defaultMultiValueProvider;
|
||||
@ -69,16 +62,6 @@ public class UserChoiceField extends FieldSpec {
|
||||
this.defaultMultiValueProvider = defaultMultiValueProvider;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isDefaultMultiValueProviderVisible() {
|
||||
return EditContext.get().getInputValue("allowMultiple").equals(true);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isSubscriptionActive() {
|
||||
return OneDev.getInstance(SubscriptionManager.class).isSubscriptionActive();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getPossibleValues() {
|
||||
return UserChoiceInput.getPossibleValues();
|
||||
|
||||
@ -4,17 +4,16 @@ import edu.emory.mathcs.backport.java.util.Collections;
|
||||
import io.onedev.commons.codeassist.InputSuggestion;
|
||||
import io.onedev.server.OneDev;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Patterns;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
import io.onedev.server.entitymanager.BuildManager;
|
||||
import io.onedev.server.util.EditContext;
|
||||
import io.onedev.server.web.util.SuggestionUtils;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.List;
|
||||
|
||||
@Editable
|
||||
public class JobPrivilege implements Serializable {
|
||||
@ -63,14 +62,9 @@ public class JobPrivilege implements Serializable {
|
||||
this.manageJob = manageJob;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isManageJobDisabled() {
|
||||
return !(boolean) EditContext.get().getInputValue("manageJob");
|
||||
}
|
||||
|
||||
@Editable(order=200, description="The permission to run job manually. It also implies the permission "
|
||||
+ "to access build log, build pipeline and all published reports")
|
||||
@ShowCondition("isManageJobDisabled")
|
||||
@DependsOn(property="manageJob", value="false")
|
||||
public boolean isRunJob() {
|
||||
return runJob;
|
||||
}
|
||||
@ -79,13 +73,8 @@ public class JobPrivilege implements Serializable {
|
||||
this.runJob = runJob;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isRunJobDisabled() {
|
||||
return !(boolean) EditContext.get().getInputValue("runJob");
|
||||
}
|
||||
|
||||
@Editable(order=300, name="Access Build Log", description="The permission to access build log")
|
||||
@ShowCondition("isRunJobDisabled")
|
||||
@DependsOn(property="runJob", value="false")
|
||||
public boolean isAccessLog() {
|
||||
return accessLog;
|
||||
}
|
||||
@ -95,7 +84,7 @@ public class JobPrivilege implements Serializable {
|
||||
}
|
||||
|
||||
@Editable(order=350, name="Access Build Pipeline", description="The permission to access build pipeline")
|
||||
@ShowCondition("isRunJobDisabled")
|
||||
@DependsOn(property="runJob", value="false")
|
||||
public boolean isAccessPipeline() {
|
||||
return accessPipeline;
|
||||
}
|
||||
@ -106,7 +95,7 @@ public class JobPrivilege implements Serializable {
|
||||
|
||||
@Editable(order=400, name="Access Build Reports", placeholder="No accessible reports", description="Optionally specify space-separated reports. "
|
||||
+ "Use '*' or '?' for wildcard match. Prefix with '-' to exclude")
|
||||
@ShowCondition("isRunJobDisabled")
|
||||
@DependsOn(property="runJob", value="false")
|
||||
@Patterns
|
||||
@Nullable
|
||||
public String getAccessibleReports() {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package io.onedev.server.ai;
|
||||
package io.onedev.server.rest.resource;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@ -18,6 +19,7 @@ import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import javax.persistence.EntityNotFoundException;
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.ValidationException;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
@ -40,6 +42,8 @@ import com.google.common.base.Splitter;
|
||||
|
||||
import io.onedev.commons.utils.StringUtils;
|
||||
import io.onedev.server.SubscriptionManager;
|
||||
import io.onedev.server.buildspec.BuildSpec;
|
||||
import io.onedev.server.data.migration.VersionedYamlDoc;
|
||||
import io.onedev.server.entitymanager.BuildManager;
|
||||
import io.onedev.server.entitymanager.BuildParamManager;
|
||||
import io.onedev.server.entitymanager.IssueChangeManager;
|
||||
@ -454,10 +458,8 @@ public class McpHelperResource {
|
||||
|
||||
private Project getProject(String projectPath) {
|
||||
var project = projectManager.findByPath(projectPath);
|
||||
if (project == null)
|
||||
throw new NotFoundException("Project not found: " + projectPath);
|
||||
if (!SecurityUtils.canAccessProject(project))
|
||||
throw new UnauthorizedException("Unable to access project: " + projectPath);
|
||||
if (project == null || !SecurityUtils.canAccessProject(project))
|
||||
throw new NotFoundException("Project not found or inaccessible: " + projectPath);
|
||||
return project;
|
||||
}
|
||||
|
||||
@ -1331,7 +1333,6 @@ public class McpHelperResource {
|
||||
pullRequestMap.put("status", PullRequest.Status.OPEN.name() + " (ready to merge)");
|
||||
}
|
||||
pullRequestMap.remove("uuid");
|
||||
pullRequestMap.remove("baseCommitHash");
|
||||
pullRequestMap.remove("buildCommitHash");
|
||||
pullRequestMap.remove("submitTimeGroups");
|
||||
pullRequestMap.remove("closeTimeGroups");
|
||||
@ -1439,10 +1440,10 @@ public class McpHelperResource {
|
||||
|
||||
return buildMap;
|
||||
}
|
||||
|
||||
@Path("/get-previous-successful-build")
|
||||
|
||||
@Path("/get-previous-successful-similar-build")
|
||||
@GET
|
||||
public Map<String, Object> getPreviousSuccessfulBuild(
|
||||
public Map<String, Object> getPreviousSuccessfulSimilarBuild(
|
||||
@QueryParam("currentProject") @NotNull String currentProjectPath,
|
||||
@QueryParam("reference") @NotNull String buildReference) {
|
||||
if (SecurityUtils.getAuthUser() == null)
|
||||
@ -1452,18 +1453,30 @@ public class McpHelperResource {
|
||||
|
||||
var build = getBuild(currentProject, buildReference);
|
||||
|
||||
var previousSuccessfulBuild = buildManager.findStreamPrevious(build, Build.Status.SUCCESSFUL);
|
||||
if (previousSuccessfulBuild != null) {
|
||||
var buildMap = getBuildMap(currentProject, previousSuccessfulBuild);
|
||||
buildMap.put("params", previousSuccessfulBuild.getParamMap());
|
||||
buildMap.put("labels", previousSuccessfulBuild.getLabels().stream().map(it->it.getSpec().getName()).collect(Collectors.toList()));
|
||||
buildMap.put("link", urlManager.urlFor(previousSuccessfulBuild, true));
|
||||
var foundBuild = buildManager.findPreviousSuccessfulSimilar(build);
|
||||
if (foundBuild != null) {
|
||||
var buildMap = getBuildMap(currentProject, foundBuild);
|
||||
buildMap.put("params", foundBuild.getParamMap());
|
||||
buildMap.put("labels", foundBuild.getLabels().stream().map(it->it.getSpec().getName()).collect(Collectors.toList()));
|
||||
buildMap.put("link", urlManager.urlFor(foundBuild, true));
|
||||
return buildMap;
|
||||
} else {
|
||||
throw new NotFoundException("Previous successful build not found");
|
||||
throw new NotFoundException("Previous successful similar build not found");
|
||||
}
|
||||
}
|
||||
|
||||
@Path("/migrate-build-spec")
|
||||
@POST
|
||||
@Consumes(MediaType.TEXT_PLAIN)
|
||||
@Produces(MediaType.TEXT_PLAIN)
|
||||
public String migrateBuildSpec(@NotNull String buildSpecString) {
|
||||
if (SecurityUtils.getAuthUser() == null)
|
||||
throw new UnauthenticatedException();
|
||||
|
||||
var buildSpec = BuildSpec.parse(buildSpecString.getBytes(StandardCharsets.UTF_8));
|
||||
return VersionedYamlDoc.fromBean(buildSpec).toYaml();
|
||||
}
|
||||
|
||||
@Path("/get-pull-request")
|
||||
@GET
|
||||
public Map<String, Object> getPullRequest(
|
||||
@ -1489,6 +1502,11 @@ public class McpHelperResource {
|
||||
reviews.add(reviewMap);
|
||||
}
|
||||
pullRequestMap.put("reviews", reviews);
|
||||
var builds = new ArrayList<String>();
|
||||
for (var build : pullRequest.getBuilds()) {
|
||||
builds.add(build.getReference().toString(currentProject) + " (job: " + build.getJobName() + ", status: " + build.getStatus() + ")");
|
||||
}
|
||||
pullRequestMap.put("builds", builds);
|
||||
pullRequestMap.put("labels", pullRequest.getLabels().stream().map(it->it.getSpec().getName()).collect(Collectors.toList()));
|
||||
pullRequestMap.put("link", urlManager.urlFor(pullRequest, true));
|
||||
|
||||
@ -2092,11 +2110,16 @@ public class McpHelperResource {
|
||||
if (reason == null)
|
||||
throw new NotAcceptableException("Reason is required");
|
||||
|
||||
Build build = jobManager.submit(project, ObjectId.fromString(commitHash), jobName,
|
||||
params, refName, SecurityUtils.getUser(), null,
|
||||
null, reason);
|
||||
if (build.isFinished())
|
||||
jobManager.resubmit(build, reason);
|
||||
Build build;
|
||||
try {
|
||||
build = jobManager.submit(project, ObjectId.fromString(commitHash), jobName,
|
||||
params, refName, SecurityUtils.getUser(), null,
|
||||
null, reason);
|
||||
if (build.isFinished())
|
||||
jobManager.resubmit(build, reason);
|
||||
} catch (ValidationException e) {
|
||||
throw new NotAcceptableException(e.getMessage());
|
||||
}
|
||||
|
||||
var buildMap = getBuildMap(projectInfo.currentProject, build);
|
||||
buildMap.put("id", build.getId());
|
||||
@ -4,18 +4,16 @@ import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
import io.onedev.server.OneDev;
|
||||
import io.onedev.server.entitymanager.SettingManager;
|
||||
import io.onedev.server.model.support.issue.field.spec.FieldSpec;
|
||||
import io.onedev.server.util.EditContext;
|
||||
import io.onedev.server.annotation.ChoiceProvider;
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.OmitName;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
import io.onedev.server.entitymanager.SettingManager;
|
||||
import io.onedev.server.model.support.issue.field.spec.FieldSpec;
|
||||
|
||||
@Editable
|
||||
public class UndefinedFieldResolution implements Serializable {
|
||||
@ -41,7 +39,7 @@ public class UndefinedFieldResolution implements Serializable {
|
||||
|
||||
@Editable(order=100, name="new field")
|
||||
@ChoiceProvider("getFieldChoices")
|
||||
@ShowCondition("isNewFieldVisible")
|
||||
@DependsOn(property="fixType", value="CHANGE_TO_ANOTHER_FIELD")
|
||||
@NotEmpty
|
||||
@OmitName
|
||||
public String getNewField() {
|
||||
@ -51,11 +49,6 @@ public class UndefinedFieldResolution implements Serializable {
|
||||
public void setNewField(String newField) {
|
||||
this.newField = newField;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isNewFieldVisible() {
|
||||
return EditContext.get().getInputValue("fixType") == FixType.CHANGE_TO_ANOTHER_FIELD;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static List<String> getFieldChoices() {
|
||||
|
||||
@ -4,24 +4,22 @@ import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import io.onedev.server.OneDev;
|
||||
import io.onedev.server.entitymanager.SettingManager;
|
||||
import io.onedev.server.model.support.administration.GlobalIssueSetting;
|
||||
import io.onedev.server.model.support.issue.field.spec.choicefield.ChoiceField;
|
||||
import io.onedev.server.model.support.issue.field.spec.FieldSpec;
|
||||
import io.onedev.server.util.ComponentContext;
|
||||
import io.onedev.server.util.EditContext;
|
||||
import io.onedev.server.web.component.issue.workflowreconcile.WorkflowReconcilePanel.UndefinedFieldValueContainer;
|
||||
import io.onedev.server.annotation.ChoiceProvider;
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.OmitName;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
import io.onedev.server.entitymanager.SettingManager;
|
||||
import io.onedev.server.model.support.administration.GlobalIssueSetting;
|
||||
import io.onedev.server.model.support.issue.field.spec.FieldSpec;
|
||||
import io.onedev.server.model.support.issue.field.spec.choicefield.ChoiceField;
|
||||
import io.onedev.server.util.ComponentContext;
|
||||
import io.onedev.server.web.component.issue.workflowreconcile.WorkflowReconcilePanel.UndefinedFieldValueContainer;
|
||||
|
||||
@Editable
|
||||
public class UndefinedFieldValueResolution implements Serializable {
|
||||
@ -47,7 +45,7 @@ public class UndefinedFieldValueResolution implements Serializable {
|
||||
|
||||
@Editable(order=100)
|
||||
@ChoiceProvider("getValueChoices")
|
||||
@ShowCondition("isNewValueVisible")
|
||||
@DependsOn(property="fixType", value="CHANGE_TO_ANOTHER_VALUE")
|
||||
@OmitName
|
||||
@NotEmpty
|
||||
public String getNewValue() {
|
||||
@ -58,11 +56,6 @@ public class UndefinedFieldValueResolution implements Serializable {
|
||||
this.newValue = newValue;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isNewValueVisible() {
|
||||
return EditContext.get().getInputValue("fixType") == FixType.CHANGE_TO_ANOTHER_VALUE;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static List<String> getValueChoices() {
|
||||
UndefinedFieldValueContainer container = ComponentContext.get().getComponent()
|
||||
|
||||
@ -4,18 +4,16 @@ import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
import io.onedev.server.OneDev;
|
||||
import io.onedev.server.entitymanager.SettingManager;
|
||||
import io.onedev.server.model.support.administration.GlobalIssueSetting;
|
||||
import io.onedev.server.util.EditContext;
|
||||
import io.onedev.server.annotation.ChoiceProvider;
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.OmitName;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
import io.onedev.server.entitymanager.SettingManager;
|
||||
import io.onedev.server.model.support.administration.GlobalIssueSetting;
|
||||
|
||||
@Editable
|
||||
public class UndefinedStateResolution implements Serializable {
|
||||
@ -41,7 +39,7 @@ public class UndefinedStateResolution implements Serializable {
|
||||
|
||||
@Editable(order=100)
|
||||
@ChoiceProvider("getStateChoices")
|
||||
@ShowCondition("isNewStateVisible")
|
||||
@DependsOn(property="fixType", value="CHANGE_TO_ANOTHER_STATE")
|
||||
@OmitName
|
||||
@NotEmpty
|
||||
public String getNewState() {
|
||||
@ -51,12 +49,7 @@ public class UndefinedStateResolution implements Serializable {
|
||||
public void setNewState(String newState) {
|
||||
this.newState = newState;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isNewStateVisible() {
|
||||
return EditContext.get().getInputValue("fixType") == FixType.CHANGE_TO_ANOTHER_STATE;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static List<String> getStateChoices() {
|
||||
GlobalIssueSetting issueSetting = OneDev.getInstance(SettingManager.class).getIssueSetting();
|
||||
|
||||
@ -11,15 +11,14 @@ import java.util.stream.Collectors;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.Secret;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
import io.onedev.server.model.AccessToken;
|
||||
import io.onedev.server.model.AccessTokenAuthorization;
|
||||
import io.onedev.server.model.Project;
|
||||
import io.onedev.server.model.Role;
|
||||
import io.onedev.server.security.SecurityUtils;
|
||||
import io.onedev.server.util.EditContext;
|
||||
|
||||
@Editable
|
||||
public class AccessTokenEditBean implements Serializable {
|
||||
@ -68,7 +67,7 @@ public class AccessTokenEditBean implements Serializable {
|
||||
|
||||
@Editable(order=300, name="Authorized Projects", description = "Only projects manageable by access token owner can be authorized")
|
||||
@Size(min=1, message = "At least one project should be authorized")
|
||||
@ShowCondition("isHasOwnerPermissionsDisabled")
|
||||
@DependsOn(property="hasOwnerPermissions", value="false")
|
||||
public List<AccessTokenAuthorizationBean> getAuthorizations() {
|
||||
return authorizations;
|
||||
}
|
||||
@ -77,11 +76,6 @@ public class AccessTokenEditBean implements Serializable {
|
||||
this.authorizations = authorizations;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isHasOwnerPermissionsDisabled() {
|
||||
return !(boolean) EditContext.get().getInputValue("hasOwnerPermissions");
|
||||
}
|
||||
|
||||
@Editable(order=400, placeholder = "Never expire")
|
||||
public Date getExpireDate() {
|
||||
return expireDate;
|
||||
|
||||
@ -15,10 +15,13 @@ import javax.validation.constraints.Size;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import io.onedev.commons.utils.ExplicitException;
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
import io.onedev.server.annotation.SubscriptionRequired;
|
||||
import io.onedev.server.util.BeanUtils;
|
||||
import io.onedev.server.util.ComponentContext;
|
||||
import io.onedev.server.util.EditContext;
|
||||
import io.onedev.server.util.ReflectionUtils;
|
||||
|
||||
public class PropertyDescriptor implements Serializable {
|
||||
@ -166,6 +169,35 @@ public class PropertyDescriptor implements Serializable {
|
||||
ShowCondition showCondition = getPropertyGetter().getAnnotation(ShowCondition.class);
|
||||
if (showCondition != null && !(boolean)ReflectionUtils.invokeStaticMethod(getBeanClass(), showCondition.value()))
|
||||
return false;
|
||||
DependsOn dependsOn = getPropertyGetter().getAnnotation(DependsOn.class);
|
||||
if (dependsOn != null) {
|
||||
var dependencyProperty = beanDescriptor.getProperty(dependsOn.property());
|
||||
if (dependencyProperty == null) {
|
||||
throw new ExplicitException("Dependency property not found: " + dependsOn.property());
|
||||
}
|
||||
var dependencyPropertyValue = EditContext.get().getInputValue(dependsOn.property());
|
||||
if (dependsOn.value().length() != 0) {
|
||||
if (dependencyPropertyValue != null && dependencyPropertyValue.toString().equals(dependsOn.value())) {
|
||||
if (dependsOn.inverse())
|
||||
return false;
|
||||
} else if (!dependsOn.inverse()) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (dependencyProperty.getPropertyClass() == boolean.class) {
|
||||
boolean requiredPropertyValue = !dependsOn.inverse();
|
||||
if (requiredPropertyValue != (boolean)dependencyPropertyValue)
|
||||
return false;
|
||||
} else if (dependencyProperty.getPropertyClass() == int.class || dependencyProperty.getPropertyClass() == long.class || dependencyProperty.getPropertyClass() == double.class || dependencyProperty.getPropertyClass() == float.class) {
|
||||
int dependencyPropertyIntValue = (int) dependencyPropertyValue;
|
||||
if (dependsOn.inverse() && dependencyPropertyIntValue != 0 || !dependsOn.inverse() && dependencyPropertyIntValue == 0)
|
||||
return false;
|
||||
} else {
|
||||
if (dependsOn.inverse() && dependencyPropertyValue != null || !dependsOn.inverse() && dependencyPropertyValue == null)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
getDependencyPropertyNames().remove(getPropertyName());
|
||||
for (String dependencyPropertyName: getDependencyPropertyNames()) {
|
||||
Set<String> copyOfCheckedPropertyNames = new HashSet<>(checkedPropertyNames);
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<wicket:panel>
|
||||
<form wicket:id="form" class="post-build-action-edit leave-confirm">
|
||||
<div class="modal-header">
|
||||
<h5 id="modal-title" class="modal-title">Post Build Action</h5>
|
||||
<h5 id="modal-title" class="modal-title"><wicket:t>Post Build Action</wicket:t></h5>
|
||||
<button wicket:id="close" type="button" class="close"><wicket:svg href="times" class="icon"/></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
@ -9,7 +9,7 @@
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<input wicket:id="save" type="submit" class="dirty-aware btn btn-primary" t:value="Save">
|
||||
<a wicket:id="cancel" class="btn btn-secondary">Cancel</a>
|
||||
<a wicket:id="cancel" class="btn btn-secondary"><wicket:t>Cancel</wicket:t></a>
|
||||
</div>
|
||||
</form>
|
||||
</wicket:panel>
|
||||
@ -1,21 +1,17 @@
|
||||
package io.onedev.server.web.page.admin.brandingsetting;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.Image;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
import io.onedev.server.model.support.administration.BrandingSetting;
|
||||
import io.onedev.server.util.EditContext;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import java.io.Serializable;
|
||||
|
||||
@Editable
|
||||
public class BrandSettingEditBean implements Serializable {
|
||||
|
||||
private String name;
|
||||
|
||||
private String url;
|
||||
|
||||
|
||||
private String logoData;
|
||||
|
||||
private String darkLogoData;
|
||||
@ -29,23 +25,7 @@ public class BrandSettingEditBean implements Serializable {
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isOEM() {
|
||||
return BrandingSetting.isOEM((String) EditContext.get().getInputValue("name"));
|
||||
}
|
||||
|
||||
@Editable(order=150, description = "Specify url for your brand")
|
||||
@ShowCondition("isOEM")
|
||||
@NotEmpty
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
|
||||
@Editable(order=200, name="Logo for Light Mode", description = "Upload a 128x128 transparent png file to be used " +
|
||||
"as logo for light mode")
|
||||
@Image(accept = "image/png")
|
||||
|
||||
@ -23,7 +23,6 @@ import io.onedev.server.OneDev;
|
||||
import io.onedev.server.cluster.ClusterManager;
|
||||
import io.onedev.server.cluster.ClusterTask;
|
||||
import io.onedev.server.entitymanager.SettingManager;
|
||||
import io.onedev.server.model.support.administration.BrandingSetting;
|
||||
import io.onedev.server.web.editable.BeanContext;
|
||||
import io.onedev.server.web.img.ImageScope;
|
||||
import io.onedev.server.web.page.admin.AdministrationPage;
|
||||
@ -77,7 +76,6 @@ public class BrandingSettingPage extends AdministrationPage {
|
||||
var setting = getSettingManager().getBrandingSetting();
|
||||
var bean = new BrandSettingEditBean();
|
||||
bean.setName(setting.getName());
|
||||
bean.setUrl(setting.getUrl());
|
||||
bean.setLogoData(getLogoData(false));
|
||||
bean.setDarkLogoData(getLogoData(true));
|
||||
|
||||
@ -86,7 +84,6 @@ public class BrandingSettingPage extends AdministrationPage {
|
||||
protected void onSubmit() {
|
||||
super.onSubmit();
|
||||
setting.setName(bean.getName());
|
||||
setting.setUrl(bean.getUrl());
|
||||
getSettingManager().saveBrandingSetting(setting);
|
||||
getAuditManager().audit(null, "changed branding settings", null, null);
|
||||
if (!bean.getLogoData().equals(getDefaultLogoData(false))) {
|
||||
@ -106,8 +103,7 @@ public class BrandingSettingPage extends AdministrationPage {
|
||||
|
||||
@Override
|
||||
public void onClick() {
|
||||
setting.setName(BrandingSetting.DEFAULT_NAME);
|
||||
setting.setUrl(BrandingSetting.DEFAULT_URL);
|
||||
setting.setName("OneDev");
|
||||
getSettingManager().saveBrandingSetting(setting);
|
||||
getAuditManager().audit(null, "changed branding settings", null, null);
|
||||
getClusterManager().runOnAllServers(new UpdateLogoTask(null, false));
|
||||
@ -119,7 +115,7 @@ public class BrandingSettingPage extends AdministrationPage {
|
||||
@Override
|
||||
protected void onConfigure() {
|
||||
super.onConfigure();
|
||||
setVisible(!setting.getName().equals(BrandingSetting.DEFAULT_NAME)
|
||||
setVisible(!setting.getName().equals("OneDev")
|
||||
|| getCustomLogoFile(false).exists()
|
||||
|| getCustomLogoFile(true).exists());
|
||||
}
|
||||
|
||||
@ -69,7 +69,6 @@ import io.onedev.server.entitymanager.AlertManager;
|
||||
import io.onedev.server.entitymanager.SettingManager;
|
||||
import io.onedev.server.model.Alert;
|
||||
import io.onedev.server.model.User;
|
||||
import io.onedev.server.model.support.administration.BrandingSetting;
|
||||
import io.onedev.server.persistence.dao.EntityCriteria;
|
||||
import io.onedev.server.security.SecurityUtils;
|
||||
import io.onedev.server.updatecheck.UpdateCheckManager;
|
||||
@ -512,11 +511,7 @@ public abstract class LayoutPage extends BasePage {
|
||||
});
|
||||
|
||||
var version = AppLoader.getProduct().getVersion();
|
||||
var brandingSetting = getSettingManager().getBrandingSetting();
|
||||
if (brandingSetting.isOEM())
|
||||
sidebar.add(new ExternalLink("productVersion", brandingSetting.getUrl(), brandingSetting.getName() + " " + version));
|
||||
else
|
||||
sidebar.add(new ExternalLink("productVersion", BrandingSetting.DEFAULT_URL, BrandingSetting.DEFAULT_NAME + " " + version));
|
||||
sidebar.add(new ExternalLink("productVersion", "https://onedev.io", "OneDev " + version));
|
||||
|
||||
sidebar.add(new WebMarkupContainer("tryEE") {
|
||||
@Override
|
||||
|
||||
@ -1,36 +1,20 @@
|
||||
package io.onedev.server.web.page.project.blob.render.renderers.buildspec;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import io.onedev.commons.loader.AppLoader;
|
||||
import io.onedev.server.OneDev;
|
||||
import io.onedev.server.buildspec.*;
|
||||
import io.onedev.server.buildspec.job.Job;
|
||||
import io.onedev.server.buildspec.job.JobAware;
|
||||
import io.onedev.server.buildspec.job.JobSuggestion;
|
||||
import io.onedev.server.buildspec.param.spec.ParamSpec;
|
||||
import io.onedev.server.buildspec.step.StepTemplate;
|
||||
import io.onedev.server.data.migration.VersionedYamlDoc;
|
||||
import io.onedev.server.model.support.build.JobProperty;
|
||||
import io.onedev.server.util.CollectionUtils;
|
||||
import io.onedev.server.util.Path;
|
||||
import io.onedev.server.util.PathNode;
|
||||
import io.onedev.server.util.PathNode.Indexed;
|
||||
import io.onedev.server.util.PathNode.Named;
|
||||
import io.onedev.server.util.ReflectionUtils;
|
||||
import io.onedev.server.web.behavior.sortable.SortBehavior;
|
||||
import io.onedev.server.web.behavior.sortable.SortPosition;
|
||||
import io.onedev.server.web.component.MultilineLabel;
|
||||
import io.onedev.server.web.component.floating.FloatingPanel;
|
||||
import io.onedev.server.web.component.menu.MenuItem;
|
||||
import io.onedev.server.web.component.menu.MenuLink;
|
||||
import io.onedev.server.web.component.pipeline.JobSelectionChange;
|
||||
import io.onedev.server.web.component.pipeline.PipelinePanel;
|
||||
import io.onedev.server.web.component.pipeline.Sortable;
|
||||
import io.onedev.server.web.editable.*;
|
||||
import io.onedev.server.web.page.base.BasePage;
|
||||
import io.onedev.server.web.page.project.blob.render.BlobRenderContext;
|
||||
import io.onedev.server.web.page.project.blob.render.edit.EditCompleteAware;
|
||||
import io.onedev.server.web.util.AjaxPayload;
|
||||
import static io.onedev.server.web.page.project.blob.render.renderers.buildspec.BuildSpecRenderer.getActiveElementIndex;
|
||||
import static io.onedev.server.web.page.project.blob.render.renderers.buildspec.BuildSpecRenderer.getUrlSegment;
|
||||
import static io.onedev.server.web.translation.Translation._T;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.Validator;
|
||||
|
||||
import org.apache.commons.lang3.SerializationUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.wicket.Component;
|
||||
@ -58,19 +42,48 @@ import org.apache.wicket.model.Model;
|
||||
import org.apache.wicket.request.cycle.RequestCycle;
|
||||
import org.unbescape.html.HtmlEscape;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.Validator;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import com.google.common.base.Throwables;
|
||||
|
||||
import static io.onedev.server.web.page.project.blob.render.renderers.buildspec.BuildSpecRenderer.getActiveElementIndex;
|
||||
import static io.onedev.server.web.page.project.blob.render.renderers.buildspec.BuildSpecRenderer.getUrlSegment;
|
||||
import static io.onedev.server.web.translation.Translation._T;
|
||||
import io.onedev.commons.loader.AppLoader;
|
||||
import io.onedev.server.OneDev;
|
||||
import io.onedev.server.buildspec.BuildSpec;
|
||||
import io.onedev.server.buildspec.BuildSpecAware;
|
||||
import io.onedev.server.buildspec.Import;
|
||||
import io.onedev.server.buildspec.NamedElement;
|
||||
import io.onedev.server.buildspec.ParamSpecAware;
|
||||
import io.onedev.server.buildspec.Service;
|
||||
import io.onedev.server.buildspec.job.Job;
|
||||
import io.onedev.server.buildspec.job.JobAware;
|
||||
import io.onedev.server.buildspec.job.JobSuggestion;
|
||||
import io.onedev.server.buildspec.param.spec.ParamSpec;
|
||||
import io.onedev.server.buildspec.step.StepTemplate;
|
||||
import io.onedev.server.data.migration.VersionedYamlDoc;
|
||||
import io.onedev.server.model.support.build.JobProperty;
|
||||
import io.onedev.server.util.CollectionUtils;
|
||||
import io.onedev.server.util.Path;
|
||||
import io.onedev.server.util.PathNode;
|
||||
import io.onedev.server.util.PathNode.Indexed;
|
||||
import io.onedev.server.util.PathNode.Named;
|
||||
import io.onedev.server.util.ReflectionUtils;
|
||||
import io.onedev.server.web.behavior.sortable.SortBehavior;
|
||||
import io.onedev.server.web.behavior.sortable.SortPosition;
|
||||
import io.onedev.server.web.component.MultilineLabel;
|
||||
import io.onedev.server.web.component.floating.FloatingPanel;
|
||||
import io.onedev.server.web.component.menu.MenuItem;
|
||||
import io.onedev.server.web.component.menu.MenuLink;
|
||||
import io.onedev.server.web.component.pipeline.JobSelectionChange;
|
||||
import io.onedev.server.web.component.pipeline.PipelinePanel;
|
||||
import io.onedev.server.web.component.pipeline.Sortable;
|
||||
import io.onedev.server.web.editable.BeanDescriptor;
|
||||
import io.onedev.server.web.editable.BeanEditor;
|
||||
import io.onedev.server.web.editable.BeanUpdating;
|
||||
import io.onedev.server.web.editable.PropertyContext;
|
||||
import io.onedev.server.web.editable.PropertyEditor;
|
||||
import io.onedev.server.web.editable.PropertyUpdating;
|
||||
import io.onedev.server.web.page.base.BasePage;
|
||||
import io.onedev.server.web.page.project.blob.render.BlobRenderContext;
|
||||
import io.onedev.server.web.page.project.blob.render.edit.EditCompleteAware;
|
||||
import io.onedev.server.web.util.AjaxPayload;
|
||||
|
||||
public class BuildSpecEditPanel extends FormComponentPanel<byte[]> implements BuildSpecAware, EditCompleteAware {
|
||||
|
||||
@ -836,7 +849,7 @@ public class BuildSpecEditPanel extends FormComponentPanel<byte[]> implements Bu
|
||||
} else {
|
||||
setConvertedInput(getModelObject());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void pushState(AjaxRequestTarget target, String selection) {
|
||||
String position = BuildSpecRenderer.getPosition(selection);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<wicket:extend>
|
||||
<div wicket:id="content"></div>
|
||||
<div class="foot pt-2 mt-5 border-top font-size-xs text-muted">Powered by <a wicket:id="vendor" class="text-muted text-hover-primary"></a></div>
|
||||
<div class="foot pt-2 mt-5 border-top font-size-xs text-muted">Powered by <a href="https://onedev.io" class="text-muted text-hover-primary">OneDev</a></div>
|
||||
<wicket:fragment wicket:id="passwordCheckFrag">
|
||||
<form wicket:id="form" method="post">
|
||||
<div wicket:id="feedback"></div>
|
||||
|
||||
@ -37,7 +37,6 @@ import io.onedev.server.entitymanager.SsoProviderManager;
|
||||
import io.onedev.server.entitymanager.UserManager;
|
||||
import io.onedev.server.model.SsoProvider;
|
||||
import io.onedev.server.model.User;
|
||||
import io.onedev.server.model.support.administration.BrandingSetting;
|
||||
import io.onedev.server.security.SecurityUtils;
|
||||
import io.onedev.server.security.realm.PasswordAuthenticatingRealm;
|
||||
import io.onedev.server.web.component.link.ViewStateAwarePageLink;
|
||||
@ -189,21 +188,11 @@ public class LoginPage extends SimplePage {
|
||||
fragment.add(ssoButtonsView.setVisible(!ssoProviders.isEmpty()));
|
||||
|
||||
add(fragment);
|
||||
|
||||
var brandingSetting = getSettingManager().getBrandingSetting();
|
||||
if (brandingSetting.isOEM())
|
||||
add(new ExternalLink("vendor", brandingSetting.getUrl(), brandingSetting.getName()));
|
||||
else
|
||||
add(new ExternalLink("vendor", BrandingSetting.DEFAULT_URL, BrandingSetting.DEFAULT_NAME));
|
||||
}
|
||||
|
||||
private UserManager getUserManager() {
|
||||
return OneDev.getInstance(UserManager.class);
|
||||
}
|
||||
|
||||
private SettingManager getSettingManager() {
|
||||
return OneDev.getInstance(SettingManager.class);
|
||||
}
|
||||
|
||||
private void afterLogin(User user) {
|
||||
RememberMeManager rememberMeManager = OneDev.getInstance(RememberMeManager.class);
|
||||
|
||||
@ -27,9 +27,10 @@ public class Translation_zh extends TranslationResourceBundle {
|
||||
"'image' should be translated to '图片' or '镜像' depending on context\n" +
|
||||
"'docker aware executor' should be translated to 'docker 相关执行器'\n" +
|
||||
"When used together with 'subscription', word 'active' should be translated to '有效'\n" +
|
||||
"Two factor authentication should be translated to '两阶段验证'\n" +
|
||||
"'two factor authentication' should be translated to '两阶段验证'\n" +
|
||||
"Space should be added between English words and Chinese words\n" +
|
||||
"SSO provider should be translated as SSO 提供方")
|
||||
"'SSO provider' should be translated as SSO 提供方\n" +
|
||||
"'post build' should be translated as 构建后")
|
||||
public static void init(Map<String, String> m) {
|
||||
m.clear();
|
||||
m.put(" Project path can be omitted if reference from current project", "如果从当前项目引用,则可以省略项目路径");
|
||||
@ -555,7 +556,6 @@ public class Translation_zh extends TranslationResourceBundle {
|
||||
m.put("Can not disable root account", "不能禁用根账户");
|
||||
m.put("Can not disable yourself", "不能禁用自己");
|
||||
m.put("Can not find issue board: ", "找不到工单看板:");
|
||||
m.put("Can not link to self", "不能链接到自己");
|
||||
m.put("Can not move project \"{0}\" to be under itself or its descendants", "不能将项目 \"{0}\" 移动到其自身或其子项目下");
|
||||
m.put("Can not perform this operation now", "当前无法执行此操作");
|
||||
m.put("Can not reset password for service account or disabled user", "无法重置服务账户或禁用用户的密码");
|
||||
@ -643,6 +643,7 @@ public class Translation_zh extends TranslationResourceBundle {
|
||||
m.put("Choose group...", "选择组...");
|
||||
m.put("Choose groups...", "选择组...");
|
||||
m.put("Choose issue...", "选择工单...");
|
||||
m.put("Choose issues...", "选择工单...");
|
||||
m.put("Choose iteration...", "选择迭代...");
|
||||
m.put("Choose iterations...", "选择迭代...");
|
||||
m.put("Choose job...", "选择任务...");
|
||||
@ -781,6 +782,7 @@ public class Translation_zh extends TranslationResourceBundle {
|
||||
m.put("Confirm password here", "在此确认密码");
|
||||
m.put("Confirm your action", "确认你的操作");
|
||||
m.put("Connect New Agent", "连接新代理");
|
||||
m.put("Connect with your SSO account", "使用您的 SSO 账户连接");
|
||||
m.put("Contact Email", "联系邮箱");
|
||||
m.put("Contact Name", "联系人");
|
||||
m.put("Container Image", "容器镜像");
|
||||
@ -826,6 +828,7 @@ public class Translation_zh extends TranslationResourceBundle {
|
||||
m.put("Create Merge Commit If Necessary", "仅当必要时创建合并提交");
|
||||
m.put("Create New", "新建");
|
||||
m.put("Create New File", "创建新文件");
|
||||
m.put("Create New User", "创建新用户");
|
||||
m.put("Create Project", "创建项目");
|
||||
m.put("Create Pull Request", "创建合并请求");
|
||||
m.put("Create Pull Request for This Change", "为此变更创建合并请求");
|
||||
@ -928,6 +931,8 @@ public class Translation_zh extends TranslationResourceBundle {
|
||||
m.put("Delete Build", "删除构建");
|
||||
m.put("Delete Comment", "删除评论");
|
||||
m.put("Delete Pull Request", "删除合并请求");
|
||||
m.put("Delete SSO account here to reconnect corresponding SSO subject upon next login. Note that SSO subject with verified email will be connected to user with same verified email automatically",
|
||||
"在此删除 SSO 账户以便在下次登录时重新连接相应的 SSO 主题。请注意,具有已验证电子邮件的 SSO 主题将自动连接到具有相同已验证电子邮件的用户");
|
||||
m.put("Delete Selected", "删除选中的");
|
||||
m.put("Delete Selected Builds", "删除选定的构建");
|
||||
m.put("Delete Selected Comments", "删除选中的评论");
|
||||
@ -1013,6 +1018,7 @@ public class Translation_zh extends TranslationResourceBundle {
|
||||
m.put("Do you really want to cancel this build?", "您确定要取消此构建吗?");
|
||||
m.put("Do you really want to change target branch to {0}?", "确定要将目标分支更改为 {0} 吗?");
|
||||
m.put("Do you really want to delete \"{0}\"?", "您真的要删除 \"{0}\" 吗?");
|
||||
m.put("Do you really want to delete SSO provider \"{0}\"?", "您真的想删除 SSO 提供方 \"{0}\" 吗?");
|
||||
m.put("Do you really want to delete board \"{0}\"?", "您确定要删除看板 \"{0}\" 吗?");
|
||||
m.put("Do you really want to delete build #{0}?", "您确定要删除构建 #{0} 吗?");
|
||||
m.put("Do you really want to delete group \"{0}\"?", "您真的要删除组 \"{0}\" 吗?");
|
||||
@ -1024,6 +1030,7 @@ public class Translation_zh extends TranslationResourceBundle {
|
||||
m.put("Do you really want to delete tag {0}?", "确定要删除标签 {0} 吗?");
|
||||
m.put("Do you really want to delete this GPG key?", "您确定要删除此 GPG 密钥吗?");
|
||||
m.put("Do you really want to delete this SSH key?", "您确定要删除此 SSH 密钥吗?");
|
||||
m.put("Do you really want to delete this SSO account?", "您真的想删除此 SSO 账户吗?");
|
||||
m.put("Do you really want to delete this access token?", "您确定要删除此访问令牌吗?");
|
||||
m.put("Do you really want to delete this board?", "您确定要删除此看板吗?");
|
||||
m.put("Do you really want to delete this build?", "您确定要删除此构建吗?");
|
||||
@ -1124,6 +1131,9 @@ public class Translation_zh extends TranslationResourceBundle {
|
||||
m.put("Email Verification", "邮件验证");
|
||||
m.put("Email Verification Template", "邮箱验证模板");
|
||||
m.put("Email address", "电子邮件地址");
|
||||
m.put("Email address \"{0}\" already used by another account", "电子邮件地址 \"{0}\" 已被另一个账户使用");
|
||||
m.put("Email address \"{0}\" used by account \"{1}\"", "电子邮件地址 \"{0}\" 被账户 \"{1}\" 使用");
|
||||
m.put("Email address \"{0}\" used by disabled account \"{1}\"", "电子邮件地址 \"{0}\" 被已禁用的账户 \"{1}\" 使用");
|
||||
m.put("Email address already in use: {0}", "电子邮件地址已被使用: {0}");
|
||||
m.put("Email address already invited: {0}", "电子邮件地址已被邀请: {0}");
|
||||
m.put("Email address already used by another user", "电子邮件地址已被另一个用户使用");
|
||||
@ -1184,6 +1194,7 @@ public class Translation_zh extends TranslationResourceBundle {
|
||||
m.put("Environment variable <code>serverUrl</code> in above command is taken from OneDev server url specified in <i>Administration / System Setting</i>. Change it if necessary",
|
||||
"上面的命令中的环境变量 <code>serverUrl</code> 取自 <i>管理 / 系统设置</i> 中指定的 OneDev 服务器 URL。如果需要,请更改它");
|
||||
m.put("Equal", "等于");
|
||||
m.put("Error authenticating user", "用户认证错误");
|
||||
m.put("Error calculating commits: check log for details", "计算提交时出错:请检查日志");
|
||||
m.put("Error cherry-picking to {0}: Merge conflicts detected", "cherry-pick 到 {0} 时出错:合并冲突检测到");
|
||||
m.put("Error cherry-picking to {0}: {1}", "cherry-pick 到 {0} 时出错:{1}");
|
||||
@ -1245,8 +1256,10 @@ public class Translation_zh extends TranslationResourceBundle {
|
||||
m.put("Export XLSX", "导出 XLSX");
|
||||
m.put("Export as OCI layout", "导出为 OCI 布局");
|
||||
m.put("Extend Trial Subscription", "延长试用订阅");
|
||||
m.put("External Authentication", "外部认证");
|
||||
m.put("External Issue Transformers", "外部工单转换");
|
||||
m.put("External Participants", "外部参与者");
|
||||
m.put("External Password Authenticator", "外部密码认证器");
|
||||
m.put("External System", "外部系统");
|
||||
m.put("External authenticator settings saved", "外部认证器设置已保存");
|
||||
m.put("External participants do not have accounts and involve in the issue via email", "外部参与者没有账户,通过电子邮件参与工单");
|
||||
@ -1547,6 +1560,7 @@ public class Translation_zh extends TranslationResourceBundle {
|
||||
m.put("Image URL should be specified", "图片 URL 应该指定");
|
||||
m.put("Imap Ssl Setting", "IMAP SSL 设置");
|
||||
m.put("Imap With Ssl", "IMAP 使用 SSL");
|
||||
m.put("Impersonate", "模拟");
|
||||
m.put("Implicit SSL", "隐式 SSL");
|
||||
m.put("Import", "导入");
|
||||
m.put("Import All Projects", "导入所有项目");
|
||||
@ -1699,7 +1713,6 @@ public class Translation_zh extends TranslationResourceBundle {
|
||||
m.put("Issue Votes", "工单投票");
|
||||
m.put("Issue administrative permission inside a project, including batch operations over multiple issues",
|
||||
"工单管理权限,包括对多个工单的批量操作");
|
||||
m.put("Issue already linked", "工单已链接");
|
||||
m.put("Issue count", "工单数量");
|
||||
m.put("Issue in state", "工单状态");
|
||||
m.put("Issue list", "工单列表");
|
||||
@ -1845,11 +1858,13 @@ public class Translation_zh extends TranslationResourceBundle {
|
||||
m.put("Line: ", "行:");
|
||||
m.put("Lines", "行");
|
||||
m.put("Link", "链接");
|
||||
m.put("Link Existing User", "链接现有用户");
|
||||
m.put("Link Spec", "链接规范");
|
||||
m.put("Link Spec Opposite", "链接规范相反");
|
||||
m.put("Link Text", "链接文本");
|
||||
m.put("Link URL", "链接 URL");
|
||||
m.put("Link URL should be specified", "链接 URL 应该指定");
|
||||
m.put("Link User Bean", "链接用户 Bean");
|
||||
m.put("Linkable Issues", "可链接的工单");
|
||||
m.put("Linkable Issues On the Other Side", "另一侧可链接的工单");
|
||||
m.put("Links", "链接");
|
||||
@ -1996,6 +2011,7 @@ public class Translation_zh extends TranslationResourceBundle {
|
||||
m.put("My GPG Keys", "我的 GPG 密钥");
|
||||
m.put("My Profile", "我的个人资料");
|
||||
m.put("My SSH Keys", "我的 SSH 密钥");
|
||||
m.put("My SSO Accounts", "我的 SSO 账户");
|
||||
m.put("Mypy Report", "Mypy 报告");
|
||||
m.put("N/A", "不适用");
|
||||
m.put("NPM(s)", "NPM");
|
||||
@ -2037,6 +2053,7 @@ public class Translation_zh extends TranslationResourceBundle {
|
||||
m.put("Network Options", "网络选项");
|
||||
m.put("Never", "从不");
|
||||
m.put("Never expire", "永不过期");
|
||||
m.put("Never retry", "从不重试");
|
||||
m.put("New Board", "新建看板");
|
||||
m.put("New Invitation Bean", "新邀请Bean");
|
||||
m.put("New Issue", "新工单");
|
||||
@ -2100,6 +2117,8 @@ public class Translation_zh extends TranslationResourceBundle {
|
||||
m.put("No diffs to navigate", "没有差异可导航");
|
||||
m.put("No directories to skip", "无要跳过的目录");
|
||||
m.put("No executors defined. Jobs will use auto-discovered executors instead", "未定义执行器。作业将使用自动发现的执行器");
|
||||
m.put("No external password authenticator", "没有外部密码认证器");
|
||||
m.put("No external password authenticator to authenticate user \"{0}\"", "没有外部密码认证器来认证用户 \"{0}\"");
|
||||
m.put("No fields to prompt", "无要提示的字段");
|
||||
m.put("No fields to remove", "无要删除的字段");
|
||||
m.put("No file attachments", "没有文件附件");
|
||||
@ -2234,6 +2253,7 @@ public class Translation_zh extends TranslationResourceBundle {
|
||||
m.put("Only projects manageable by access token owner can be authorized", "只有受访问令牌所有者管理的项目才能被授权");
|
||||
m.put("Only system level audit events are displayed here. To view audit events for a specific project, please visit the project audit log page",
|
||||
"这里只显示系统级别的审计事件。要查看特定项目的审计事件,请访问项目审计日志页面");
|
||||
m.put("Only users able to authenticate via password can be linked", "只有能够通过密码认证的用户才能被链接");
|
||||
m.put("Open", "打开");
|
||||
m.put("Open new pull request", "创建新的合并请求");
|
||||
m.put("Open terminal of current running step", "打开当前运行步骤的终端");
|
||||
@ -2554,6 +2574,7 @@ public class Translation_zh extends TranslationResourceBundle {
|
||||
m.put("Passcode", "Passcode");
|
||||
m.put("Passed", "通过");
|
||||
m.put("Password", "密码");
|
||||
m.put("Password Authenticator", "密码认证器");
|
||||
m.put("Password Edit Bean", "密码编辑 Bean");
|
||||
m.put("Password Must Contain Digit", "密码必须包含数字");
|
||||
m.put("Password Must Contain Lowercase", "密码必须包含小写字母");
|
||||
@ -2569,6 +2590,7 @@ public class Translation_zh extends TranslationResourceBundle {
|
||||
m.put("Password has been changed", "密码已更改");
|
||||
m.put("Password has been removed", "密码已删除");
|
||||
m.put("Password has been set", "密码已设置");
|
||||
m.put("Password of the user", "用户的密码");
|
||||
m.put("Password or Access Token for Remote Repository", "密码或远程仓库的访问令牌");
|
||||
m.put("Password reset request has been sent", "密码重置请求已发送");
|
||||
m.put("Password reset url is invalid or obsolete", "密码重置URL无效或已过期");
|
||||
@ -2678,9 +2700,9 @@ public class Translation_zh extends TranslationResourceBundle {
|
||||
m.put("Populate Tag Mappings", "填充标签映射");
|
||||
m.put("Port", "端口");
|
||||
m.put("Post", "发布");
|
||||
m.put("Post Build Action", "发布构建操作");
|
||||
m.put("Post Build Action Bean", "发布构建操作 Bean");
|
||||
m.put("Post Build Actions", "发布构建操作");
|
||||
m.put("Post Build Action", "构建后操作");
|
||||
m.put("Post Build Action Bean", "构建后操作 Bean");
|
||||
m.put("Post Build Actions", "构建后操作");
|
||||
m.put("Post Url", "发布 URL");
|
||||
m.put("PowerShell", "PowerShell");
|
||||
m.put("Prefix Pattern", "前缀模式");
|
||||
@ -3071,6 +3093,12 @@ public class Translation_zh extends TranslationResourceBundle {
|
||||
m.put("SSH key deleted", "SSH 密钥已删除");
|
||||
m.put("SSH settings have been saved and SSH server restarted", "SSH 设置已保存并重启 SSH 服务器");
|
||||
m.put("SSL Setting", "SSL 设置");
|
||||
m.put("SSO Accounts", "SSO 账户");
|
||||
m.put("SSO Providers", "SSO 提供方");
|
||||
m.put("SSO account deleted", "SSO 账户已删除");
|
||||
m.put("SSO provider \"{0}\" deleted", "SSO 提供方 \"{0}\" 已删除");
|
||||
m.put("SSO provider created", "SSO 提供方已创建");
|
||||
m.put("SSO provider updated", "SSO 提供方已更新");
|
||||
m.put("SUCCESSFUL", "成功");
|
||||
m.put("Save", "保存");
|
||||
m.put("Save Query", "保存查询");
|
||||
@ -3156,6 +3184,7 @@ public class Translation_zh extends TranslationResourceBundle {
|
||||
m.put("Service Desk Settings", "服务台设置");
|
||||
m.put("Service Locator", "服务定位器");
|
||||
m.put("Service Locators", "服务定位器");
|
||||
m.put("Service account not allowed to login", "服务账户不允许登录");
|
||||
m.put("Service desk setting", "服务台设置");
|
||||
m.put("Service desk settings have been saved", "服务台设置已保存");
|
||||
m.put("Services", "服务");
|
||||
@ -3257,6 +3286,7 @@ public class Translation_zh extends TranslationResourceBundle {
|
||||
m.put("Signing Key ID", "签署密钥 ID");
|
||||
m.put("Similar Issues", "相似工单");
|
||||
m.put("Single Sign On", "单点登录");
|
||||
m.put("Single Sign-On", "单点登录");
|
||||
m.put("Single sign on via discord.com", "通过 discord.com 单点登录");
|
||||
m.put("Single sign on via twitch.tv", "通过 twitch.tv 单点登录");
|
||||
m.put("Site", "站点");
|
||||
@ -3646,6 +3676,7 @@ public class Translation_zh extends TranslationResourceBundle {
|
||||
m.put("Ssh Setting", "SSH 设置");
|
||||
m.put("Ssl Setting", "SSL 设置");
|
||||
m.put("Sso Connector", "SSO 连接器");
|
||||
m.put("Sso Provider Bean", "Sso 提供方 Bean");
|
||||
m.put("Start At", "开始于");
|
||||
m.put("Start Date", "开始日期");
|
||||
m.put("Start Page", "起始页面");
|
||||
@ -4055,6 +4086,7 @@ public class Translation_zh extends TranslationResourceBundle {
|
||||
m.put("Unable to create protected tag", "无法创建受保护的标签");
|
||||
m.put("Unable to diff as some line is too long.", "无法比较,因为某些行太长");
|
||||
m.put("Unable to diff as the file is too large.", "无法比较,因为文件太大");
|
||||
m.put("Unable to find SSO provider: ", "无法找到 SSO 提供方:");
|
||||
m.put("Unable to find agent {0}", "无法找到代理 {0}");
|
||||
m.put("Unable to find build #{0} in project {1}", "在项目 {1} 中找不到构建 #{0}");
|
||||
m.put("Unable to find commit to import build spec (import project: {0}, import revision: {1})",
|
||||
@ -4242,6 +4274,8 @@ public class Translation_zh extends TranslationResourceBundle {
|
||||
m.put("When determine if the user is author/committer of a git commit, all emails listed here will be checked",
|
||||
"确定用户是否是 git 提交的作者/提交者时,将检查此处列出的所有电子邮件");
|
||||
m.put("When evaluating this template, below variables will be available:", "使用此模板时,以下变量将可用:");
|
||||
m.put("When login via OneDev's built-in form, submitted user credentials can be checked against authenticator defined here, besides the internal database",
|
||||
"通过 OneDev 的内置表单登录时,提交的用户凭据可以在此处定义的认证器以及内部数据库中进行检查");
|
||||
m.put("When target branch of a pull request has new commits, merge commit of the pull request will be recalculated, and this option tells whether or not to accept pull request builds ran on previous merged commit. If enabled, you will need to re-run required builds on the new merge commit. This setting takes effect only when required builds are specified",
|
||||
"当合并请求的目标分支有新提交时,合并请求的合并提交将被重新计算,此选项决定是否接受在之前合并提交上运行的合并请求构建。如果启用,您需要在新的合并提交上重新运行所需的构建。此设置仅在指定了所需构建时生效");
|
||||
m.put("When this work starts", "此工作开始时");
|
||||
@ -4588,39 +4622,6 @@ public class Translation_zh extends TranslationResourceBundle {
|
||||
m.put("{javax.validation.constraints.NotEmpty.message}", "不能为空");
|
||||
m.put("{javax.validation.constraints.NotNull.message}", "不能为空");
|
||||
m.put("{javax.validation.constraints.Size.message}", "至少需要指定一个值");
|
||||
m.put("Connect with your SSO account", "使用您的 SSO 账户连接");
|
||||
m.put("Create New User", "创建新用户");
|
||||
m.put("Delete SSO account here to reconnect corresponding SSO subject upon next login. Note that SSO subject with verified email will be connected to user with same verified email automatically",
|
||||
"在此删除 SSO 账户以便在下次登录时重新连接相应的 SSO 主题。请注意,具有已验证电子邮件的 SSO 主题将自动连接到具有相同已验证电子邮件的用户");
|
||||
m.put("Do you really want to delete SSO provider \"{0}\"?", "您真的想删除 SSO 提供方 \"{0}\" 吗?");
|
||||
m.put("Do you really want to delete this SSO account?", "您真的想删除此 SSO 账户吗?");
|
||||
m.put("Email address \"{0}\" already used by another account", "电子邮件地址 \"{0}\" 已被另一个账户使用");
|
||||
m.put("Email address \"{0}\" used by account \"{1}\"", "电子邮件地址 \"{0}\" 被账户 \"{1}\" 使用");
|
||||
m.put("Email address \"{0}\" used by disabled account \"{1}\"", "电子邮件地址 \"{0}\" 被已禁用的账户 \"{1}\" 使用");
|
||||
m.put("Error authenticating user", "用户认证错误");
|
||||
m.put("External Authentication", "外部认证");
|
||||
m.put("External Password Authenticator", "外部密码认证器");
|
||||
m.put("Impersonate", "模拟");
|
||||
m.put("Link Existing User", "链接现有用户");
|
||||
m.put("Link User Bean", "链接用户 Bean");
|
||||
m.put("My SSO Accounts", "我的 SSO 账户");
|
||||
m.put("No external password authenticator", "没有外部密码认证器");
|
||||
m.put("No external password authenticator to authenticate user \"{0}\"", "没有外部密码认证器来认证用户 \"{0}\"");
|
||||
m.put("Only users able to authenticate via password can be linked", "只有能够通过密码认证的用户才能被链接");
|
||||
m.put("Password Authenticator", "密码认证器");
|
||||
m.put("Password of the user", "用户的密码");
|
||||
m.put("SSO Accounts", "SSO 账户");
|
||||
m.put("SSO Providers", "SSO 提供方");
|
||||
m.put("SSO account deleted", "SSO 账户已删除");
|
||||
m.put("SSO provider \"{0}\" deleted", "SSO 提供方 \"{0}\" 已删除");
|
||||
m.put("SSO provider created", "SSO 提供方已创建");
|
||||
m.put("SSO provider updated", "SSO 提供方已更新");
|
||||
m.put("Service account not allowed to login", "服务账户不允许登录");
|
||||
m.put("Single Sign-On", "单点登录");
|
||||
m.put("Sso Provider Bean", "Sso 提供方 Bean");
|
||||
m.put("Unable to find SSO provider: ", "无法找到 SSO 提供方:");
|
||||
m.put("When login via OneDev's built-in form, submitted user credentials can be checked against authenticator defined here, besides the internal database",
|
||||
"通过 OneDev 的内置表单登录时,提交的用户凭据可以在此处定义的认证器以及内部数据库中进行检查");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -3,8 +3,8 @@ package io.onedev.server.web.util.editbean;
|
||||
import javax.validation.constraints.Email;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
import io.onedev.server.model.User;
|
||||
|
||||
@Editable
|
||||
@ -17,7 +17,7 @@ public class NewUserBean extends User {
|
||||
private String emailAddress;
|
||||
|
||||
@Editable(order=1000)
|
||||
@ShowCondition("isServiceAccountDisabled")
|
||||
@DependsOn(property="serviceAccount", value="false")
|
||||
@NotEmpty
|
||||
@Email
|
||||
public String getEmailAddress() {
|
||||
|
||||
@ -242,6 +242,20 @@ public abstract class BaseConstructor {
|
||||
* @return Java instance
|
||||
*/
|
||||
protected Object constructObject(Node node) {
|
||||
if (node instanceof MappingNode) {
|
||||
MappingNode mappingNode = (MappingNode) node;
|
||||
for (var it = mappingNode.getValue().iterator(); it.hasNext();) {
|
||||
var tuple = it.next();
|
||||
if (tuple.getKeyNode() instanceof ScalarNode) {
|
||||
ScalarNode keyNode = (ScalarNode) tuple.getKeyNode();
|
||||
if ("type".equals(keyNode.getValue())) {
|
||||
String implementationName = ((ScalarNode) tuple.getValueNode()).getValue();
|
||||
mappingNode.setTag(new Tag("!" + implementationName));
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (constructedObjects.containsKey(node)) {
|
||||
return constructedObjects.get(node);
|
||||
}
|
||||
|
||||
@ -22,6 +22,7 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.DumperOptions.FlowStyle;
|
||||
import org.yaml.snakeyaml.TypeDescription;
|
||||
@ -86,11 +87,7 @@ public class Representer extends SafeRepresenter {
|
||||
*/
|
||||
protected MappingNode representJavaBean(Set<Property> properties, Object javaBean) {
|
||||
List<NodeTuple> value = new ArrayList<NodeTuple>(properties.size());
|
||||
Tag tag;
|
||||
Tag customTag = classTags.get(javaBean.getClass());
|
||||
tag = customTag != null ? customTag : new Tag("!" + javaBean.getClass().getSimpleName());
|
||||
// flow style will be chosen by BaseRepresenter
|
||||
MappingNode node = new MappingNode(tag, value, FlowStyle.AUTO);
|
||||
MappingNode node = new MappingNode(Tag.MAP, value, FlowStyle.AUTO);
|
||||
representedObjects.put(javaBean, node);
|
||||
DumperOptions.FlowStyle bestStyle = FlowStyle.FLOW;
|
||||
for (Property property : properties) {
|
||||
@ -146,14 +143,13 @@ public class Representer extends SafeRepresenter {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (nodeId == NodeId.mapping) {
|
||||
if (property.getType() == propertyValue.getClass()) {
|
||||
if (!(propertyValue instanceof Map<?, ?>)) {
|
||||
if (!nodeValue.getTag().equals(Tag.SET)) {
|
||||
nodeValue.setTag(Tag.MAP);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nodeId == NodeId.mapping && !(propertyValue instanceof Map<?, ?>)
|
||||
&& !nodeValue.getTag().equals(Tag.SET)
|
||||
&& property.getType() != propertyValue.getClass()) {
|
||||
var mappingNode = (MappingNode) nodeValue;
|
||||
mappingNode.getValue().add(0, new NodeTuple(
|
||||
new ScalarNode(Tag.STR, "type"),
|
||||
new ScalarNode(Tag.STR, propertyValue.getClass().getSimpleName())));
|
||||
}
|
||||
checkGlobalTag(property, nodeValue, propertyValue);
|
||||
}
|
||||
@ -195,12 +191,13 @@ public class Representer extends SafeRepresenter {
|
||||
if (iter.hasNext()) {
|
||||
for (Node childNode : snode.getValue()) {
|
||||
Object member = iter.next();
|
||||
if (member != null) {
|
||||
if (t.equals(member.getClass())) {
|
||||
if (childNode.getNodeId() == NodeId.mapping) {
|
||||
childNode.setTag(Tag.MAP);
|
||||
}
|
||||
}
|
||||
if (member != null
|
||||
&& childNode.getNodeId() == NodeId.mapping
|
||||
&& !t.equals(member.getClass())) {
|
||||
var childMappingMode = (MappingNode) childNode;
|
||||
childMappingMode.getValue().add(0, new NodeTuple(
|
||||
new ScalarNode(Tag.STR, "type"),
|
||||
new ScalarNode(Tag.STR, member.getClass().getSimpleName())));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -212,10 +209,10 @@ public class Representer extends SafeRepresenter {
|
||||
for (Object member : set) {
|
||||
NodeTuple tuple = iter.next();
|
||||
Node keyNode = tuple.getKeyNode();
|
||||
if (t.equals(member.getClass())) {
|
||||
if (keyNode.getNodeId() == NodeId.mapping) {
|
||||
keyNode.setTag(Tag.MAP);
|
||||
}
|
||||
if (keyNode.getNodeId() == NodeId.mapping && !t.equals(member.getClass())) {
|
||||
mnode.getValue().add(0, new NodeTuple(
|
||||
new ScalarNode(Tag.STR, "type"),
|
||||
new ScalarNode(Tag.STR, member.getClass().getSimpleName())));
|
||||
}
|
||||
}
|
||||
} else if (object instanceof Map) { // NodeId.mapping ends-up here
|
||||
|
||||
@ -1 +1 @@
|
||||
Subproject commit d2d06071947cdb284f01173028b2c4281efbf036
|
||||
Subproject commit 5ec90bb5da921bbe3dbd22b6719819945d76a44b
|
||||
@ -1,12 +1,12 @@
|
||||
package io.onedev.server.plugin.authenticator.ldap;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Editable(name="Active Directory", order=100)
|
||||
public class ActiveDirectoryAuthenticator extends LdapAuthenticator {
|
||||
@ -34,7 +34,7 @@ public class ActiveDirectoryAuthenticator extends LdapAuthenticator {
|
||||
+ "Specify manager DN to authenticate OneDev itself to Active Directory. The manager DN should be specified "
|
||||
+ "in form of <i><account name>@<domain></i>, for instance: <i>manager@example.com</i>")
|
||||
@NotEmpty
|
||||
@ShowCondition("isAuthenticationRequiredEnabled")
|
||||
@DependsOn(property=PROP_AUTHENTICATION_REQUIRED)
|
||||
@Override
|
||||
public String getManagerDN() {
|
||||
return super.getManagerDN();
|
||||
|
||||
@ -1,33 +1,49 @@
|
||||
package io.onedev.server.plugin.authenticator.ldap;
|
||||
|
||||
import io.onedev.commons.utils.ExplicitException;
|
||||
import io.onedev.commons.utils.StringUtils;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.Password;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
import io.onedev.server.model.support.administration.authenticator.Authenticated;
|
||||
import io.onedev.server.model.support.administration.authenticator.Authenticator;
|
||||
import io.onedev.server.security.TrustCertsSSLSocketFactory;
|
||||
import io.onedev.server.util.EditContext;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.naming.AuthenticationException;
|
||||
import javax.naming.CompositeName;
|
||||
import javax.naming.Context;
|
||||
import javax.naming.Name;
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.PartialResultException;
|
||||
import javax.naming.directory.Attribute;
|
||||
import javax.naming.directory.Attributes;
|
||||
import javax.naming.directory.DirContext;
|
||||
import javax.naming.directory.InitialDirContext;
|
||||
import javax.naming.directory.SearchControls;
|
||||
import javax.naming.directory.SearchResult;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import org.apache.shiro.authc.UnknownAccountException;
|
||||
import org.apache.shiro.authc.UsernamePasswordToken;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.util.*;
|
||||
import io.onedev.commons.utils.ExplicitException;
|
||||
import io.onedev.commons.utils.StringUtils;
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.Password;
|
||||
import io.onedev.server.model.support.administration.authenticator.Authenticated;
|
||||
import io.onedev.server.model.support.administration.authenticator.Authenticator;
|
||||
import io.onedev.server.security.TrustCertsSSLSocketFactory;
|
||||
|
||||
@Editable(name="Generic LDAP", order=200)
|
||||
public class LdapAuthenticator extends Authenticator {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final String PROP_AUTHENTICATION_REQUIRED = "authenticationRequired";
|
||||
protected static final String PROP_AUTHENTICATION_REQUIRED = "authenticationRequired";
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(LdapAuthenticator.class);
|
||||
|
||||
@ -74,14 +90,9 @@ public class LdapAuthenticator extends Authenticator {
|
||||
public void setAuthenticationRequired(boolean authenticationRequired) {
|
||||
this.authenticationRequired = authenticationRequired;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isAuthenticationRequiredEnabled() {
|
||||
return (boolean) EditContext.get().getInputValue(PROP_AUTHENTICATION_REQUIRED);
|
||||
}
|
||||
|
||||
@Editable(order=300, description="Specify manager DN to authenticate OneDev itself to LDAP server")
|
||||
@ShowCondition("isAuthenticationRequiredEnabled")
|
||||
@DependsOn(property=PROP_AUTHENTICATION_REQUIRED)
|
||||
@NotEmpty
|
||||
public String getManagerDN() {
|
||||
return managerDN;
|
||||
@ -93,7 +104,7 @@ public class LdapAuthenticator extends Authenticator {
|
||||
|
||||
@Editable(order=400, description="Specifies password of above manager DN")
|
||||
@Password
|
||||
@ShowCondition("isAuthenticationRequiredEnabled")
|
||||
@DependsOn(property=PROP_AUTHENTICATION_REQUIRED)
|
||||
@NotEmpty
|
||||
public String getManagerPassword() {
|
||||
return managerPassword;
|
||||
|
||||
@ -1,5 +1,50 @@
|
||||
package io.onedev.server.plugin.executor.kubernetes;
|
||||
|
||||
import static com.google.common.collect.Lists.newArrayList;
|
||||
import static io.onedev.k8shelper.ExecuteCondition.ALWAYS;
|
||||
import static io.onedev.k8shelper.KubernetesHelper.ENV_JOB_TOKEN;
|
||||
import static io.onedev.k8shelper.KubernetesHelper.ENV_SERVER_URL;
|
||||
import static io.onedev.k8shelper.KubernetesHelper.IMAGE_REPO;
|
||||
import static io.onedev.k8shelper.KubernetesHelper.LOG_END_MESSAGE;
|
||||
import static io.onedev.k8shelper.KubernetesHelper.parseStepPosition;
|
||||
import static io.onedev.k8shelper.KubernetesHelper.stringifyStepPosition;
|
||||
import static io.onedev.k8shelper.RegistryLoginFacade.merge;
|
||||
import static io.onedev.server.util.CollectionUtils.newHashMap;
|
||||
import static io.onedev.server.util.CollectionUtils.newLinkedHashMap;
|
||||
import static java.lang.Integer.parseInt;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.apache.commons.codec.binary.Base64.encodeBase64String;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
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.UUID;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
import org.apache.commons.lang.SerializationUtils;
|
||||
import org.apache.commons.lang3.RandomUtils;
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
@ -7,60 +52,48 @@ import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import io.onedev.commons.bootstrap.Bootstrap;
|
||||
import io.onedev.commons.utils.*;
|
||||
import io.onedev.commons.utils.ExceptionUtils;
|
||||
import io.onedev.commons.utils.ExplicitException;
|
||||
import io.onedev.commons.utils.FileUtils;
|
||||
import io.onedev.commons.utils.StringUtils;
|
||||
import io.onedev.commons.utils.TaskLogger;
|
||||
import io.onedev.commons.utils.command.Commandline;
|
||||
import io.onedev.commons.utils.command.LineConsumer;
|
||||
import io.onedev.k8shelper.*;
|
||||
import io.onedev.k8shelper.Action;
|
||||
import io.onedev.k8shelper.BuildImageFacade;
|
||||
import io.onedev.k8shelper.CommandFacade;
|
||||
import io.onedev.k8shelper.CompositeFacade;
|
||||
import io.onedev.k8shelper.KubernetesHelper;
|
||||
import io.onedev.k8shelper.LeafFacade;
|
||||
import io.onedev.k8shelper.PruneBuilderCacheFacade;
|
||||
import io.onedev.k8shelper.RegistryLoginFacade;
|
||||
import io.onedev.k8shelper.RunContainerFacade;
|
||||
import io.onedev.k8shelper.RunImagetoolsFacade;
|
||||
import io.onedev.k8shelper.ServiceFacade;
|
||||
import io.onedev.k8shelper.SetupCacheFacade;
|
||||
import io.onedev.server.OneDev;
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.OmitName;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
import io.onedev.server.buildspecmodel.inputspec.SecretInput;
|
||||
import io.onedev.server.cluster.ClusterManager;
|
||||
import io.onedev.server.entitymanager.SettingManager;
|
||||
import io.onedev.server.job.JobContext;
|
||||
import io.onedev.server.job.JobManager;
|
||||
import io.onedev.server.job.JobRunnable;
|
||||
import io.onedev.server.model.support.administration.jobexecutor.*;
|
||||
import io.onedev.server.model.support.administration.jobexecutor.JobExecutor;
|
||||
import io.onedev.server.model.support.administration.jobexecutor.KubernetesAware;
|
||||
import io.onedev.server.model.support.administration.jobexecutor.NodeSelectorEntry;
|
||||
import io.onedev.server.model.support.administration.jobexecutor.RegistryLogin;
|
||||
import io.onedev.server.model.support.administration.jobexecutor.ServiceLocator;
|
||||
import io.onedev.server.plugin.executor.kubernetes.KubernetesExecutor.TestData;
|
||||
import io.onedev.server.terminal.CommandlineShell;
|
||||
import io.onedev.server.terminal.Shell;
|
||||
import io.onedev.server.terminal.Terminal;
|
||||
import io.onedev.server.util.EditContext;
|
||||
import io.onedev.server.util.FilenameUtils;
|
||||
import io.onedev.server.web.util.Testable;
|
||||
import org.apache.commons.lang.SerializationUtils;
|
||||
import org.apache.commons.lang3.RandomUtils;
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static com.google.common.collect.Lists.newArrayList;
|
||||
import static io.onedev.k8shelper.ExecuteCondition.ALWAYS;
|
||||
import static io.onedev.k8shelper.KubernetesHelper.*;
|
||||
import static io.onedev.k8shelper.RegistryLoginFacade.merge;
|
||||
import static io.onedev.server.util.CollectionUtils.newHashMap;
|
||||
import static io.onedev.server.util.CollectionUtils.newLinkedHashMap;
|
||||
import static java.lang.Integer.parseInt;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.apache.commons.codec.binary.Base64.encodeBase64String;
|
||||
|
||||
@Editable(order=KubernetesExecutor.ORDER, description="This executor runs build jobs as pods in a kubernetes cluster. "
|
||||
+ "No any agents are required."
|
||||
@ -130,17 +163,12 @@ public class KubernetesExecutor extends JobExecutor implements KubernetesAware,
|
||||
public void setBuildWithPV(boolean buildWithPV) {
|
||||
this.buildWithPV = buildWithPV;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isBuildWithPVEnabled() {
|
||||
return (boolean) EditContext.get().getInputValue("buildWithPV");
|
||||
}
|
||||
|
||||
@Editable(order=400, name="Build Volume Storage Class", placeholder = "Use default storage class", description = "" +
|
||||
"Optionally specify a storage class to allocate build volume dynamically. Leave empty to use default storage class. " +
|
||||
"<b class='text-warning'>NOTE:</b> Reclaim policy of the storage class should be set to <code>Delete</code>, " +
|
||||
"as the volume is only used to hold temporary build files")
|
||||
@ShowCondition("isBuildWithPVEnabled")
|
||||
@DependsOn(property="buildWithPV")
|
||||
public String getStorageClass() {
|
||||
return storageClass;
|
||||
}
|
||||
@ -152,7 +180,7 @@ public class KubernetesExecutor extends JobExecutor implements KubernetesAware,
|
||||
@Editable(order=500, name="Build Volume Storage Size", description = "Specify storage size to request " +
|
||||
"for the build volume. The size should conform to <a href='https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#setting-requests-and-limits-for-local-ephemeral-storage' target='_blank'>Kubernetes resource capacity format</a>, " +
|
||||
"for instance <i>10Gi</i>")
|
||||
@ShowCondition("isBuildWithPVEnabled")
|
||||
@DependsOn(property="buildWithPV")
|
||||
@NotEmpty
|
||||
public String getStorageSize() {
|
||||
return storageSize;
|
||||
|
||||
@ -1,9 +1,16 @@
|
||||
package io.onedev.server.plugin.imports.bitbucketcloud;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import io.onedev.server.annotation.ChoiceProvider;
|
||||
import io.onedev.server.annotation.ClassValidating;
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
import io.onedev.server.security.SecurityUtils;
|
||||
import io.onedev.server.security.permission.CreateChildren;
|
||||
import io.onedev.server.util.ComponentContext;
|
||||
@ -11,12 +18,6 @@ import io.onedev.server.util.EditContext;
|
||||
import io.onedev.server.validation.Validatable;
|
||||
import io.onedev.server.web.editable.BeanEditor;
|
||||
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Editable
|
||||
@ClassValidating
|
||||
public class ImportRepositories extends ImportWorkspace implements Validatable {
|
||||
@ -57,17 +58,8 @@ public class ImportRepositories extends ImportWorkspace implements Validatable {
|
||||
this.all = all;
|
||||
}
|
||||
|
||||
private static boolean isAllEnabled() {
|
||||
return (Boolean)EditContext.get().getInputValue("all");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isAllDisabled() {
|
||||
return !isAllEnabled();
|
||||
}
|
||||
|
||||
@Editable(order=400, description="Whether or not to import forked Bitbucket repositories")
|
||||
@ShowCondition("isAllEnabled")
|
||||
@DependsOn(property="all")
|
||||
public boolean isIncludeForks() {
|
||||
return includeForks;
|
||||
}
|
||||
@ -78,7 +70,7 @@ public class ImportRepositories extends ImportWorkspace implements Validatable {
|
||||
|
||||
@Editable(order=500, name="Bitbucket Repositories to Import")
|
||||
@ChoiceProvider("getBitbucketRepositoryChoices")
|
||||
@ShowCondition("isAllDisabled")
|
||||
@DependsOn(property="all", value="false")
|
||||
@Size(min=1, message="At least one repository should be selected")
|
||||
public List<String> getBitbucketRepositories() {
|
||||
return bitbucketRepositories;
|
||||
|
||||
@ -1,10 +1,17 @@
|
||||
package io.onedev.server.plugin.imports.gitea;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import io.onedev.server.OneDev;
|
||||
import io.onedev.server.annotation.ChoiceProvider;
|
||||
import io.onedev.server.annotation.ClassValidating;
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
import io.onedev.server.entitymanager.ProjectManager;
|
||||
import io.onedev.server.security.SecurityUtils;
|
||||
import io.onedev.server.security.permission.CreateChildren;
|
||||
@ -13,12 +20,6 @@ import io.onedev.server.util.EditContext;
|
||||
import io.onedev.server.validation.Validatable;
|
||||
import io.onedev.server.web.editable.BeanEditor;
|
||||
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Editable
|
||||
@ClassValidating
|
||||
public class ImportRepositories extends ImportOrganization implements Validatable {
|
||||
@ -59,18 +60,9 @@ public class ImportRepositories extends ImportOrganization implements Validatabl
|
||||
public void setAll(boolean all) {
|
||||
this.all = all;
|
||||
}
|
||||
|
||||
private static boolean isAllEnabled() {
|
||||
return (Boolean)EditContext.get().getInputValue("all");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isAllDisabled() {
|
||||
return !isAllEnabled();
|
||||
}
|
||||
|
||||
@Editable(order=400, description="Whether or not to import forked Gitea repositories")
|
||||
@ShowCondition("isAllEnabled")
|
||||
@DependsOn(property="all")
|
||||
public boolean isIncludeForks() {
|
||||
return includeForks;
|
||||
}
|
||||
@ -81,7 +73,7 @@ public class ImportRepositories extends ImportOrganization implements Validatabl
|
||||
|
||||
@Editable(order=500, name="Gitea Repositories to Import")
|
||||
@ChoiceProvider("getGiteaRepositoryChoices")
|
||||
@ShowCondition("isAllDisabled")
|
||||
@DependsOn(property="all", value="false")
|
||||
@Size(min=1, message="At least one repository should be selected")
|
||||
public List<String> getGiteaRepositories() {
|
||||
return giteaRepositories;
|
||||
|
||||
@ -1,9 +1,16 @@
|
||||
package io.onedev.server.plugin.imports.github;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import io.onedev.server.annotation.ChoiceProvider;
|
||||
import io.onedev.server.annotation.ClassValidating;
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
import io.onedev.server.security.SecurityUtils;
|
||||
import io.onedev.server.security.permission.CreateChildren;
|
||||
import io.onedev.server.util.ComponentContext;
|
||||
@ -11,12 +18,6 @@ import io.onedev.server.util.EditContext;
|
||||
import io.onedev.server.validation.Validatable;
|
||||
import io.onedev.server.web.editable.BeanEditor;
|
||||
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Editable
|
||||
@ClassValidating
|
||||
public class ImportRepositories extends ImportOrganization implements Validatable {
|
||||
@ -55,19 +56,10 @@ public class ImportRepositories extends ImportOrganization implements Validatabl
|
||||
|
||||
public void setAll(boolean all) {
|
||||
this.all = all;
|
||||
}
|
||||
|
||||
private static boolean isAllEnabled() {
|
||||
return (Boolean)EditContext.get().getInputValue("all");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isAllDisabled() {
|
||||
return !isAllEnabled();
|
||||
}
|
||||
}
|
||||
|
||||
@Editable(order=400, description="Whether or not to import forked GitHub repositories")
|
||||
@ShowCondition("isAllEnabled")
|
||||
@DependsOn(property="all")
|
||||
public boolean isIncludeForks() {
|
||||
return includeForks;
|
||||
}
|
||||
@ -78,7 +70,7 @@ public class ImportRepositories extends ImportOrganization implements Validatabl
|
||||
|
||||
@Editable(order=500, name="GitHub Repositories to Import")
|
||||
@ChoiceProvider("getGitHubRepositoryChoices")
|
||||
@ShowCondition("isAllDisabled")
|
||||
@DependsOn(property="all", value="false")
|
||||
@Size(min=1, message="At least one repository should be selected")
|
||||
public List<String> getGitHubRepositories() {
|
||||
return gitHubRepositories;
|
||||
|
||||
@ -1,17 +1,18 @@
|
||||
package io.onedev.server.plugin.imports.gitlab;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import io.onedev.server.annotation.ChoiceProvider;
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.ProjectChoice;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
import io.onedev.server.util.ComponentContext;
|
||||
import io.onedev.server.util.EditContext;
|
||||
import io.onedev.server.web.editable.BeanEditor;
|
||||
|
||||
import javax.validation.constraints.Size;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@Editable
|
||||
public class ImportProjects extends ImportGroup {
|
||||
|
||||
@ -44,18 +45,9 @@ public class ImportProjects extends ImportGroup {
|
||||
public void setAll(boolean all) {
|
||||
this.all = all;
|
||||
}
|
||||
|
||||
private static boolean isAllEnabled() {
|
||||
return (Boolean)EditContext.get().getInputValue("all");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isAllDisabled() {
|
||||
return !isAllEnabled();
|
||||
}
|
||||
|
||||
@Editable(order=400, description="Whether or not to import forked GitLab projects")
|
||||
@ShowCondition("isAllEnabled")
|
||||
@DependsOn(property="all")
|
||||
public boolean isIncludeForks() {
|
||||
return includeForks;
|
||||
}
|
||||
@ -66,7 +58,7 @@ public class ImportProjects extends ImportGroup {
|
||||
|
||||
@Editable(order=500, name="GitLab Projects to Import")
|
||||
@ChoiceProvider("getGitLabProjectChoices")
|
||||
@ShowCondition("isAllDisabled")
|
||||
@DependsOn(property="all", value="false")
|
||||
@Size(min=1, message="At least one project should be selected")
|
||||
public List<String> getGitLabProjects() {
|
||||
return gitLabProjects;
|
||||
|
||||
@ -1,23 +1,23 @@
|
||||
package io.onedev.server.plugin.imports.jiracloud;
|
||||
|
||||
import io.onedev.server.annotation.ChoiceProvider;
|
||||
import io.onedev.server.annotation.ClassValidating;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
import io.onedev.server.security.SecurityUtils;
|
||||
import io.onedev.server.security.permission.CreateChildren;
|
||||
import io.onedev.server.util.ComponentContext;
|
||||
import io.onedev.server.util.EditContext;
|
||||
import io.onedev.server.validation.Validatable;
|
||||
import io.onedev.server.web.editable.BeanEditor;
|
||||
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import io.onedev.server.annotation.ChoiceProvider;
|
||||
import io.onedev.server.annotation.ClassValidating;
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.security.SecurityUtils;
|
||||
import io.onedev.server.security.permission.CreateChildren;
|
||||
import io.onedev.server.util.ComponentContext;
|
||||
import io.onedev.server.validation.Validatable;
|
||||
import io.onedev.server.web.editable.BeanEditor;
|
||||
|
||||
@Editable
|
||||
@ClassValidating
|
||||
public class ImportProjects implements Serializable, Validatable {
|
||||
@ -58,14 +58,9 @@ public class ImportProjects implements Serializable, Validatable {
|
||||
this.all = all;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isAllDisabled() {
|
||||
return !(Boolean) EditContext.get().getInputValue("all");
|
||||
}
|
||||
|
||||
@Editable(order=500, name="JIRA Projects to Import")
|
||||
@ChoiceProvider("getJiraProjectChoices")
|
||||
@ShowCondition("isAllDisabled")
|
||||
@DependsOn(property="all", value="false")
|
||||
@Size(min=1, message="At least one project should be selected")
|
||||
public List<String> getJiraProjects() {
|
||||
return jiraProjects;
|
||||
|
||||
@ -10,12 +10,11 @@ import javax.validation.constraints.Size;
|
||||
|
||||
import io.onedev.server.annotation.ChoiceProvider;
|
||||
import io.onedev.server.annotation.ClassValidating;
|
||||
import io.onedev.server.annotation.DependsOn;
|
||||
import io.onedev.server.annotation.Editable;
|
||||
import io.onedev.server.annotation.ShowCondition;
|
||||
import io.onedev.server.security.SecurityUtils;
|
||||
import io.onedev.server.security.permission.CreateChildren;
|
||||
import io.onedev.server.util.ComponentContext;
|
||||
import io.onedev.server.util.EditContext;
|
||||
import io.onedev.server.validation.Validatable;
|
||||
import io.onedev.server.web.editable.BeanEditor;
|
||||
|
||||
@ -61,14 +60,9 @@ public class ImportProjects implements Serializable, Validatable {
|
||||
this.all = all;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isAllDisabled() {
|
||||
return !(Boolean) EditContext.get().getInputValue("all");
|
||||
}
|
||||
|
||||
@Editable(order=500, name="YouTrack Projects to Import")
|
||||
@ChoiceProvider("getYouTrackProjectChoices")
|
||||
@ShowCondition("isAllDisabled")
|
||||
@DependsOn(property="all", value="false")
|
||||
@Size(min=1, message="At least one project should be selected")
|
||||
public List<String> getYouTrackProjects() {
|
||||
return youTrackProjects;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user