diff --git a/Dockerfile b/Dockerfile index 5dc3c7e4d7..832764cb3d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,11 +6,11 @@ ARG MS_VERSION=dev RUN mkdir -p /opt/apps && mkdir -p /opt/jmeter/lib/junit -COPY backend/target/backend-1.5.jar /opt/apps +COPY backend/target/backend-1.6.jar /opt/apps COPY backend/target/classes/jmeter/ /opt/jmeter/ -ENV JAVA_APP_JAR=/opt/apps/backend-1.5.jar +ENV JAVA_APP_JAR=/opt/apps/backend-1.6.jar ENV AB_OFF=true diff --git a/README.md b/README.md index b8bcefc10c..9048e41765 100755 --- a/README.md +++ b/README.md @@ -13,10 +13,10 @@ MeterSphere 是一站式开源持续测试平台,涵盖测试跟踪、接口测试、性能测试、团队协作等功能,兼容JMeter 等开源标准,有效助力开发和测试团队充分利用云弹性进行高度可扩展的自动化测试,加速高质量软件的交付。 -- 测试跟踪: 远超 TestLink 的使用体验; -- 接口测试: 类似 Postman 的体验; +- 测试跟踪: 远超 TestLink 的使用体验,覆盖从编写用例到生成测试报告的完整流程; +- 接口测试: 集 Postman 的易用与 JMeter 的灵活于一体,接口管理、多协议支持、场景自动化,你想要的全都有; - 性能测试: 兼容 JMeter,支持 Kubernetes 和云环境,轻松支持高并发、分布式的性能测试; -- 团队协作: 两级租户体系,天然支持团队协作。 +- 团队协作: 用户管理、租户管理、权限管理、资源管理,无论团队规模如何,总有适合的落地方式。 ![产品定位](https://metersphere.oss-cn-hangzhou.aliyuncs.com/img/ct-devops.png) @@ -72,12 +72,11 @@ v1.1.0 是 v1.0.0 之后的功能版本。 像其它优秀开源项目一样,MeterSphere 将每月发布一个功能版本。 -## 技术优势 +## 产品优势 -- 全生命周期: 能够覆盖从测试计划到测试执行、测试报告分析的不同阶段; -- 自动化 & 扩展性: 支持接口和性能的自动化测试,可以充分利用云弹性实现超大规模的性能测试; -- 持续测试: 能够与持续集成工具无缝集成,支撑企业实现测试左移; -- 团队协作: 支持不同规模的测试团队,小到几个人的测试团队、大到数百人的测试中心。 +- 开源:基于开源、兼容开源;按月发布新版本、日均下载安装超过100次、被大量客户验证; +- 一站式:一个产品全面涵盖测试跟踪、接口测试、性能测试等功能并形成联动:其中用例管理是底座需求、接口自动化测试是高频需求、性能测试是专家服务为主工具为辅;一个产品全满足从测试计划、测试执行到测试报告分析的全生命周期需求; +- 持续测试:能将测试融入持续交付和 DevOps 体系;无缝对接 Bug 管理工具和持续集成工具等;支持团队协作和资产沉淀。 ## 功能列表 diff --git a/backend/pom.xml b/backend/pom.xml index a227d4f89b..961d3aab62 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -7,7 +7,7 @@ <parent> <artifactId>metersphere-server</artifactId> <groupId>io.metersphere</groupId> - <version>1.5</version> + <version>1.6</version> </parent> <modelVersion>4.0.0</modelVersion> diff --git a/backend/src/main/java/io/metersphere/api/controller/APITestController.java b/backend/src/main/java/io/metersphere/api/controller/APITestController.java index 8a2beaab59..5a58efb37e 100644 --- a/backend/src/main/java/io/metersphere/api/controller/APITestController.java +++ b/backend/src/main/java/io/metersphere/api/controller/APITestController.java @@ -51,6 +51,7 @@ public class APITestController { public Pager<List<APITestResult>> list(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody QueryAPITestRequest request) { Page<Object> page = PageHelper.startPage(goPage, pageSize, true); request.setWorkspaceId(SessionUtils.getCurrentWorkspaceId()); + request.setProjectId(SessionUtils.getCurrentProjectId()); return PageUtils.setPageInfo(page, apiTestService.list(request)); } diff --git a/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java b/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java index 710f2d3aa3..2593fd31d3 100644 --- a/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java +++ b/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java @@ -34,8 +34,8 @@ public class ApiAutomationController { } @PostMapping(value = "/create") - public void create(@RequestPart("request") SaveApiScenarioRequest request, @RequestPart(value = "files") List<MultipartFile> bodyFiles) { - apiAutomationService.create(request, bodyFiles); + public ApiScenario create(@RequestPart("request") SaveApiScenarioRequest request, @RequestPart(value = "files") List<MultipartFile> bodyFiles) { + return apiAutomationService.create(request, bodyFiles); } @PostMapping(value = "/update") diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/assertions/MsAssertions.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/assertions/MsAssertions.java index f3fa1d3801..21fcf65837 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/assertions/MsAssertions.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/assertions/MsAssertions.java @@ -67,6 +67,7 @@ public class MsAssertions extends MsTestElement { assertion.setProperty(TestElement.TEST_CLASS, ResponseAssertion.class.getName()); assertion.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("AssertionGui")); assertion.setAssumeSuccess(assertionRegex.isAssumeSuccess()); + assertion.addTestString(assertionRegex.getExpression()); assertion.setToContainsType(); switch (assertionRegex.getSubject()) { case "Response Code": diff --git a/backend/src/main/java/io/metersphere/api/service/APITestService.java b/backend/src/main/java/io/metersphere/api/service/APITestService.java index 8932a52370..23ae3400e9 100644 --- a/backend/src/main/java/io/metersphere/api/service/APITestService.java +++ b/backend/src/main/java/io/metersphere/api/service/APITestService.java @@ -68,7 +68,6 @@ public class APITestService { public List<APITestResult> list(QueryAPITestRequest request) { request.setOrders(ServiceUtils.getDefaultOrder(request.getOrders())); - request.setProjectId(SessionUtils.getCurrentProjectId()); return extApiTestMapper.list(request); } diff --git a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java index ee13eb7368..ad04dbc5fd 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java @@ -100,11 +100,12 @@ public class ApiAutomationService { apiScenarioMapper.deleteByExample(example); } - public void create(SaveApiScenarioRequest request, List<MultipartFile> bodyFiles) { + public ApiScenario create(SaveApiScenarioRequest request, List<MultipartFile> bodyFiles) { + request.setId(UUID.randomUUID().toString()); checkNameExist(request); - + final ApiScenario scenario = new ApiScenario(); - scenario.setId(UUID.randomUUID().toString()); + scenario.setId(request.getId()); scenario.setName(request.getName()); scenario.setProjectId(request.getProjectId()); scenario.setTagId(request.getTagId()); @@ -132,6 +133,7 @@ public class ApiAutomationService { List<String> bodyUploadIds = request.getBodyUploadIds(); apiDefinitionService.createBodyFiles(bodyUploadIds, bodyFiles); + return scenario; } public void update(SaveApiScenarioRequest request, List<MultipartFile> bodyFiles) { @@ -248,7 +250,7 @@ public class ApiAutomationService { JSONObject element = JSON.parseObject(item.getScenarioDefinition()); MsScenario scenario = JSONObject.parseObject(item.getScenarioDefinition(), MsScenario.class); // 多态JSON普通转换会丢失内容,需要通过 ObjectMapper 获取 - if (element!= null && StringUtils.isNotEmpty(element.getString("hashTree"))) { + if (element != null && StringUtils.isNotEmpty(element.getString("hashTree"))) { LinkedList<MsTestElement> elements = mapper.readValue(element.getString("hashTree"), new TypeReference<LinkedList<MsTestElement>>() { }); diff --git a/backend/src/main/java/io/metersphere/api/service/ApiModuleService.java b/backend/src/main/java/io/metersphere/api/service/ApiModuleService.java index e0051020e4..c6acd01c8b 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiModuleService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiModuleService.java @@ -166,7 +166,9 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> { ApiModuleDTO nodeTree = request.getNodeTree(); List<ApiModule> updateNodes = new ArrayList<>(); - + if (nodeTree == null) { + return; + } buildUpdateDefinition(nodeTree, apiModule, updateNodes, "/", "0", nodeTree.getLevel()); updateNodes = updateNodes.stream() @@ -179,8 +181,7 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> { } private void buildUpdateDefinition(ApiModuleDTO rootNode, List<ApiDefinitionResult> apiDefinitions, - List<ApiModule> updateNodes, String rootPath, String pId, int level) { - + List<ApiModule> updateNodes, String rootPath, String pId, int level) { rootPath = rootPath + rootNode.getName(); if (level > 8) { diff --git a/backend/src/main/java/io/metersphere/api/service/ApiScenarioModuleService.java b/backend/src/main/java/io/metersphere/api/service/ApiScenarioModuleService.java index ce1a051acc..032257a248 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiScenarioModuleService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiScenarioModuleService.java @@ -13,7 +13,6 @@ import io.metersphere.base.mapper.ApiScenarioModuleMapper; import io.metersphere.base.mapper.ext.ExtApiScenarioModuleMapper; import io.metersphere.commons.constants.TestCaseConstants; import io.metersphere.commons.exception.MSException; -import io.metersphere.commons.utils.BeanUtils; import io.metersphere.i18n.Translator; import io.metersphere.service.NodeTreeService; import org.apache.commons.lang3.StringUtils; @@ -24,7 +23,10 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; import java.util.stream.Collectors; @Service @@ -140,7 +142,9 @@ public class ApiScenarioModuleService extends NodeTreeService<ApiScenarioModuleD ApiScenarioModuleDTO nodeTree = request.getNodeTree(); List<ApiScenarioModule> updateNodes = new ArrayList<>(); - + if (nodeTree == null) { + return; + } buildUpdateDefinition(nodeTree, apiScenarios, updateNodes, "/", "0", nodeTree.getLevel()); updateNodes = updateNodes.stream() diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionExecResultMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionExecResultMapper.xml index fec17fae05..ccc638897d 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionExecResultMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionExecResultMapper.xml @@ -7,6 +7,6 @@ <select id="selectMaxResultByResourceId" parameterType="java.lang.String" resultType="io.metersphere.base.domain.ApiDefinitionExecResult"> select * from api_definition_exec_result - where resource_id = #{resourceId,jdbcType=VARCHAR} ORDER BY update_time DESC LIMIT 1 + where resource_id = #{resourceId,jdbcType=VARCHAR} ORDER BY start_time DESC LIMIT 1 </select> </mapper> \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/xpack b/backend/src/main/java/io/metersphere/xpack index bb494fc68a..61397c1672 160000 --- a/backend/src/main/java/io/metersphere/xpack +++ b/backend/src/main/java/io/metersphere/xpack @@ -1 +1 @@ -Subproject commit bb494fc68a2367359c9048fa7250c7618de4afb6 +Subproject commit 61397c16728a63493507679f7e0940d9099f337f diff --git a/frontend/pom.xml b/frontend/pom.xml index 8a9a98a84a..43af035ce4 100644 --- a/frontend/pom.xml +++ b/frontend/pom.xml @@ -7,7 +7,7 @@ <parent> <artifactId>metersphere-server</artifactId> <groupId>io.metersphere</groupId> - <version>1.5</version> + <version>1.6</version> </parent> <modelVersion>4.0.0</modelVersion> diff --git a/frontend/src/business/components/api/automation/scenario/ApiScenarioList.vue b/frontend/src/business/components/api/automation/scenario/ApiScenarioList.vue index 20eb794b26..9f89ad79fd 100644 --- a/frontend/src/business/components/api/automation/scenario/ApiScenarioList.vue +++ b/frontend/src/business/components/api/automation/scenario/ApiScenarioList.vue @@ -240,7 +240,7 @@ }); }, copy(row) { - row.id = getUUID(); + row.copy = true; this.$emit('edit', row); }, showReport(row) { diff --git a/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue b/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue index 4c1fb5faea..3dacc7a663 100644 --- a/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue +++ b/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue @@ -493,6 +493,9 @@ request.enable === undefined ? request.enable = true : request.enable; request.active = false; request.resourceId = getUUID(); + if (!request.url) { + request.url = ""; + } if (referenced === 'REF' || !request.hashTree) { request.hashTree = []; } @@ -557,8 +560,8 @@ copyRow(row, node) { const parent = node.parent const hashTree = parent.data.hashTree || parent.data; - let obj = {}; - Object.assign(obj, row); + // 深度复制 + let obj = JSON.parse(JSON.stringify(row)); obj.resourceId = getUUID(); hashTree.push(obj); this.sort(); @@ -604,7 +607,7 @@ this.getEnvironments(); }, allowDrop(draggingNode, dropNode, type) { - if (ELEMENTS.get(dropNode.data.type).indexOf(draggingNode.data.type) != -1) { + if (dropNode.data.type === draggingNode.data.type || ELEMENTS.get(dropNode.data.type).indexOf(draggingNode.data.type) != -1) { return true; } return false; @@ -694,9 +697,12 @@ if (valid) { this.setParameter(); let bodyFiles = this.getBodyUploadFiles(this.currentScenario); - this.$fileUpload(this.path, null, bodyFiles, this.currentScenario, () => { + this.$fileUpload(this.path, null, bodyFiles, this.currentScenario, response => { this.$success(this.$t('commons.save_success')); this.path = "/api/automation/update"; + if (response.data) { + this.currentScenario.id = response.data.id; + } this.currentScenario.tagId = JSON.parse(this.currentScenario.tagId); this.$emit('refresh'); }) @@ -719,6 +725,9 @@ this.scenarioDefinition = obj.hashTree; } } + if (this.currentScenario.copy) { + this.path = "/api/automation/create"; + } } }) } diff --git a/frontend/src/business/components/api/definition/components/ApiConfig.vue b/frontend/src/business/components/api/definition/components/ApiConfig.vue index b886bf9d60..bceea6b325 100644 --- a/frontend/src/business/components/api/definition/components/ApiConfig.vue +++ b/frontend/src/business/components/api/definition/components/ApiConfig.vue @@ -67,7 +67,7 @@ if (Object.prototype.toString.call(this.currentApi.response).match(/\[object (\w+)\]/)[1].toLowerCase() === 'object') { this.response = this.currentApi.response; } else { - this.response = new ResponseFactory(JSON.parse(this.currentApi.response)); + this.response = JSON.parse(this.currentApi.response); } } else { this.response = {headers: [], body: new Body(), statusCode: [], type: "HTTP"}; diff --git a/frontend/src/business/components/api/definition/components/auth/ApiAuthConfig.vue b/frontend/src/business/components/api/definition/components/auth/ApiAuthConfig.vue index a1f5bc31b3..2fc2b7136b 100644 --- a/frontend/src/business/components/api/definition/components/auth/ApiAuthConfig.vue +++ b/frontend/src/business/components/api/definition/components/auth/ApiAuthConfig.vue @@ -26,7 +26,7 @@ <el-form-item :label="$t('commons.password')" prop="password" v-if=" authConfig.verification!=undefined && authConfig.verification !='No Auth'"> <el-input v-model="authConfig.password" :placeholder="$t('commons.password')" show-password autocomplete="off" - maxlength="20" show-word-limit/> + maxlength="50" show-word-limit/> </el-form-item> </el-form> diff --git a/frontend/src/business/components/api/definition/components/debug/DebugHttpPage.vue b/frontend/src/business/components/api/definition/components/debug/DebugHttpPage.vue index ad1404f120..d272e61ee9 100644 --- a/frontend/src/business/components/api/definition/components/debug/DebugHttpPage.vue +++ b/frontend/src/business/components/api/definition/components/debug/DebugHttpPage.vue @@ -68,7 +68,7 @@ method: [{required: true, message: this.$t('test_track.case.input_maintainer'), trigger: 'change'}], url: [{required: true, message: this.$t('api_test.definition.request.path_all_info'), trigger: 'blur'}], }, - debugForm: {method: REQ_METHOD[0].id}, + debugForm: {method: REQ_METHOD[0].id, environmentId: ""}, options: [], responseData: {type: 'HTTP', responseResult: {}, subRequestResults: []}, loading: false, diff --git a/frontend/src/business/components/api/definition/components/list/ApiList.vue b/frontend/src/business/components/api/definition/components/list/ApiList.vue index bb5d95ab67..b0049dfbb4 100644 --- a/frontend/src/business/components/api/definition/components/list/ApiList.vue +++ b/frontend/src/business/components/api/definition/components/list/ApiList.vue @@ -140,7 +140,7 @@ {name: this.$t('api_test.definition.request.batch_edit'), handleClick: this.handleEditBatch} ], typeArr: [ - {id: 'status', name: this.$t('api_test.definition.api_case_status')}, + {id: 'status', name: this.$t('api_test.definition.api_status')}, {id: 'method', name: this.$t('api_test.definition.api_type')}, {id: 'userId', name: this.$t('api_test.definition.api_principal')}, ], diff --git a/frontend/src/business/components/api/definition/components/request/database/BasisParameters.vue b/frontend/src/business/components/api/definition/components/request/database/BasisParameters.vue index 1a43a0cde1..d1ac3e96ee 100644 --- a/frontend/src/business/components/api/definition/components/request/database/BasisParameters.vue +++ b/frontend/src/business/components/api/definition/components/request/database/BasisParameters.vue @@ -167,8 +167,7 @@ this.reload(); }, copyRow(row) { - let obj = {}; - Object.assign(obj, row); + let obj =JSON.parse(JSON.stringify(row)); obj.id = getUUID(); this.request.hashTree.push(obj); this.reload(); diff --git a/frontend/src/business/components/api/definition/components/request/dubbo/BasisParameters.vue b/frontend/src/business/components/api/definition/components/request/dubbo/BasisParameters.vue index 532089f8b1..64a4065e72 100644 --- a/frontend/src/business/components/api/definition/components/request/dubbo/BasisParameters.vue +++ b/frontend/src/business/components/api/definition/components/request/dubbo/BasisParameters.vue @@ -141,8 +141,7 @@ this.reload(); }, copyRow(row) { - let obj = {}; - Object.assign(obj, row); + let obj =JSON.parse(JSON.stringify(row)); obj.id = getUUID(); this.request.hashTree.push(obj); this.reload(); diff --git a/frontend/src/business/components/api/definition/components/request/http/ApiAdvancedConfig.vue b/frontend/src/business/components/api/definition/components/request/http/ApiAdvancedConfig.vue new file mode 100644 index 0000000000..421f459749 --- /dev/null +++ b/frontend/src/business/components/api/definition/components/request/http/ApiAdvancedConfig.vue @@ -0,0 +1,42 @@ +<template> + <div> + <el-row style="margin: 20px"> + <span style="margin-right: 10px"> + {{$t('api_test.request.connect_timeout')}}: + </span> + <span style="margin-right: 10px"> + <el-input-number size="small" :disabled="isReadOnly" v-model="request.connectTimeout" :placeholder="$t('commons.millisecond')" :max="1000*10000000" :min="0"/> + </span> + <span style="margin-right: 10px"> + {{$t('api_test.request.response_timeout')}}: + </span> + <span style="margin-right: 10px"> + <el-input-number size="small" :disabled="isReadOnly" v-model="request.responseTimeout" :placeholder="$t('commons.millisecond')" :max="1000*10000000" :min="0"/> + </span> + </el-row> + <el-row style="margin: 20px"> + <span style="margin-right: 10px"> + <el-checkbox class="follow-redirects-item" v-model="request.followRedirects">{{$t('api_test.request.follow_redirects')}}</el-checkbox> + </span> + <span style="margin-right: 10px"> + <el-checkbox class="do-multipart-post" v-model="request.doMultipartPost">{{$t('api_test.request.do_multipart_post')}}</el-checkbox> + </span> + </el-row> + </div> +</template> + +<script> + export default { + name: "MsApiAdvancedConfig", + props: { + request: Object, + isReadOnly: { + type: Boolean, + default: false + } + } + } +</script> + +<style scoped> +</style> diff --git a/frontend/src/business/components/api/definition/components/request/http/ApiHttpRequestForm.vue b/frontend/src/business/components/api/definition/components/request/http/ApiHttpRequestForm.vue index c03a7320b4..bed9bd662c 100644 --- a/frontend/src/business/components/api/definition/components/request/http/ApiHttpRequestForm.vue +++ b/frontend/src/business/components/api/definition/components/request/http/ApiHttpRequestForm.vue @@ -60,6 +60,10 @@ <ms-api-auth-config :is-read-only="isReadOnly" :request="request"/> </el-tab-pane> + <el-tab-pane label="其他设置" name="advancedConfig"> + <ms-api-advanced-config :is-read-only="isReadOnly" :request="request"/> + </el-tab-pane> + </el-tabs> </div> <div v-if="!referenced"> @@ -101,13 +105,13 @@ import {REQUEST_HEADERS} from "@/common/js/constants"; import MsApiVariable from "../../ApiVariable"; import MsJsr233Processor from "../../processor/Jsr233Processor"; - import MsApiAdvancedConfig from "../../ApiAdvancedConfig"; import {createComponent} from "../../jmeter/components"; import MsApiAssertions from "../../assertion/ApiAssertions"; import MsApiExtract from "../../extract/ApiExtract"; import {Assertions, Body, Extract, KeyValue} from "../../../model/ApiTestModel"; import {getUUID} from "@/common/js/utils"; import BatchAddParameter from "../../basis/BatchAddParameter"; + import MsApiAdvancedConfig from "./ApiAdvancedConfig"; export default { @@ -200,8 +204,7 @@ this.reload(); }, copyRow(row) { - let obj = {}; - Object.assign(obj, row); + let obj =JSON.parse(JSON.stringify(row)); obj.id = getUUID(); this.request.hashTree.push(obj); this.reload(); diff --git a/frontend/src/business/components/api/definition/components/request/tcp/BasisParameters.vue b/frontend/src/business/components/api/definition/components/request/tcp/BasisParameters.vue index e456e0fbc2..bd408af00d 100644 --- a/frontend/src/business/components/api/definition/components/request/tcp/BasisParameters.vue +++ b/frontend/src/business/components/api/definition/components/request/tcp/BasisParameters.vue @@ -195,8 +195,7 @@ this.reload(); }, copyRow(row) { - let obj = {}; - Object.assign(obj, row); + let obj =JSON.parse(JSON.stringify(row)); obj.id = getUUID(); this.request.hashTree.push(obj); this.reload(); diff --git a/frontend/src/business/components/xpack b/frontend/src/business/components/xpack index a22a3005d9..d39dafaf84 160000 --- a/frontend/src/business/components/xpack +++ b/frontend/src/business/components/xpack @@ -1 +1 @@ -Subproject commit a22a3005d9bd254793fcf634d72539cbdf31be3a +Subproject commit d39dafaf84b9c7a56cb51f2caf67dd7dfde5938c diff --git a/pom.xml b/pom.xml index 568ceb82c5..dfccba1d83 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ <modelVersion>4.0.0</modelVersion> <groupId>io.metersphere</groupId> <artifactId>metersphere-server</artifactId> - <version>1.5</version> + <version>1.6</version> <packaging>pom</packaging> <parent>