Commit f753bb93 authored by nobodyiam's avatar nobodyiam
parent c121a9e6
...@@ -2,6 +2,7 @@ package com.ctrip.framework.apollo.biz.repository; ...@@ -2,6 +2,7 @@ package com.ctrip.framework.apollo.biz.repository;
import com.ctrip.framework.apollo.biz.entity.ReleaseHistory; import com.ctrip.framework.apollo.biz.entity.ReleaseHistory;
import java.util.Set;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Modifying;
...@@ -19,6 +20,8 @@ public interface ReleaseHistoryRepository extends PagingAndSortingRepository<Rel ...@@ -19,6 +20,8 @@ public interface ReleaseHistoryRepository extends PagingAndSortingRepository<Rel
Page<ReleaseHistory> findByPreviousReleaseIdAndOperationOrderByIdDesc(long previousReleaseId, int operation, Pageable pageable); Page<ReleaseHistory> findByPreviousReleaseIdAndOperationOrderByIdDesc(long previousReleaseId, int operation, Pageable pageable);
Page<ReleaseHistory> findByReleaseIdAndOperationInOrderByIdDesc(long releaseId, Set<Integer> operations, Pageable pageable);
@Modifying @Modifying
@Query("update ReleaseHistory set isdeleted=1,DataChange_LastModifiedBy = ?4 where appId=?1 and clusterName=?2 and namespaceName = ?3") @Query("update ReleaseHistory set isdeleted=1,DataChange_LastModifiedBy = ?4 where appId=?1 and clusterName=?2 and namespaceName = ?3")
int batchDelete(String appId, String clusterName, String namespaceName, String operator); int batchDelete(String appId, String clusterName, String namespaceName, String operator);
......
...@@ -6,6 +6,7 @@ import com.ctrip.framework.apollo.biz.entity.Audit; ...@@ -6,6 +6,7 @@ import com.ctrip.framework.apollo.biz.entity.Audit;
import com.ctrip.framework.apollo.biz.entity.ReleaseHistory; import com.ctrip.framework.apollo.biz.entity.ReleaseHistory;
import com.ctrip.framework.apollo.biz.repository.ReleaseHistoryRepository; import com.ctrip.framework.apollo.biz.repository.ReleaseHistoryRepository;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
...@@ -43,6 +44,10 @@ public class ReleaseHistoryService { ...@@ -43,6 +44,10 @@ public class ReleaseHistoryService {
return releaseHistoryRepository.findByPreviousReleaseIdAndOperationOrderByIdDesc(previousReleaseId, operation, page); return releaseHistoryRepository.findByPreviousReleaseIdAndOperationOrderByIdDesc(previousReleaseId, operation, page);
} }
public Page<ReleaseHistory> findByReleaseIdAndOperationInOrderByIdDesc(long releaseId, Set<Integer> operations, Pageable page) {
return releaseHistoryRepository.findByReleaseIdAndOperationInOrderByIdDesc(releaseId, operations, page);
}
@Transactional @Transactional
public ReleaseHistory createReleaseHistory(String appId, String clusterName, String public ReleaseHistory createReleaseHistory(String appId, String clusterName, String
namespaceName, String branchName, long releaseId, long previousReleaseId, int operation, namespaceName, String branchName, long releaseId, long previousReleaseId, int operation,
......
package com.ctrip.framework.apollo.biz.service; package com.ctrip.framework.apollo.biz.service;
import com.ctrip.framework.apollo.biz.entity.ReleaseHistory;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.ctrip.framework.apollo.biz.entity.Audit; import com.ctrip.framework.apollo.biz.entity.Audit;
...@@ -21,8 +23,12 @@ import com.ctrip.framework.apollo.common.exception.NotFoundException; ...@@ -21,8 +23,12 @@ import com.ctrip.framework.apollo.common.exception.NotFoundException;
import com.ctrip.framework.apollo.common.utils.GrayReleaseRuleItemTransformer; import com.ctrip.framework.apollo.common.utils.GrayReleaseRuleItemTransformer;
import com.ctrip.framework.apollo.core.utils.StringUtils; import com.ctrip.framework.apollo.core.utils.StringUtils;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.Collection;
import org.apache.commons.lang.time.FastDateFormat; import org.apache.commons.lang.time.FastDateFormat;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
...@@ -44,7 +50,12 @@ import java.util.Set; ...@@ -44,7 +50,12 @@ import java.util.Set;
public class ReleaseService { public class ReleaseService {
private static final FastDateFormat TIMESTAMP_FORMAT = FastDateFormat.getInstance("yyyyMMddHHmmss"); private static final FastDateFormat TIMESTAMP_FORMAT = FastDateFormat.getInstance("yyyyMMddHHmmss");
private Gson gson = new Gson(); private static final Gson gson = new Gson();
private static final Set<Integer> BRANCH_RELEASE_OPERATIONS = Sets
.newHashSet(ReleaseOperation.GRAY_RELEASE, ReleaseOperation.MASTER_NORMAL_RELEASE_MERGE_TO_GRAY,
ReleaseOperation.MATER_ROLLBACK_MERGE_TO_GRAY);
private static final Pageable FIRST_ITEM = PageRequest.of(0, 1);
private static final Type OPERATION_CONTEXT_TYPE_REFERENCE = new TypeToken<Map<String, Object>>() { }.getType();
@Autowired @Autowired
private ReleaseRepository releaseRepository; private ReleaseRepository releaseRepository;
...@@ -204,8 +215,8 @@ public class ReleaseService { ...@@ -204,8 +215,8 @@ public class ReleaseService {
} }
return branchRelease(parentNamespace, childNamespace, releaseName, releaseComment, return branchRelease(parentNamespace, childNamespace, releaseName, releaseComment,
configsToPublish, baseReleaseId, operator, configsToPublish, baseReleaseId, operator, ReleaseOperation.GRAY_RELEASE, isEmergencyPublish,
ReleaseOperation.GRAY_RELEASE, isEmergencyPublish); childNamespaceItems.keySet());
} }
...@@ -243,22 +254,51 @@ public class ReleaseService { ...@@ -243,22 +254,51 @@ public class ReleaseService {
String operator, Release masterPreviousRelease, String operator, Release masterPreviousRelease,
Release parentRelease, boolean isEmergencyPublish) { Release parentRelease, boolean isEmergencyPublish) {
//create release for child namespace //create release for child namespace
Map<String, String> childReleaseConfiguration = getNamespaceReleaseConfiguration(childNamespace); Release childNamespaceLatestActiveRelease = findLatestActiveRelease(childNamespace);
Map<String, String> childReleaseConfiguration;
Collection<String> branchReleaseKeys;
if (childNamespaceLatestActiveRelease != null) {
childReleaseConfiguration = gson.fromJson(childNamespaceLatestActiveRelease.getConfigurations(), GsonType.CONFIG);
branchReleaseKeys = getBranchReleaseKeys(childNamespaceLatestActiveRelease.getId());
} else {
childReleaseConfiguration = Collections.emptyMap();
branchReleaseKeys = null;
}
Map<String, String> parentNamespaceOldConfiguration = masterPreviousRelease == null ? Map<String, String> parentNamespaceOldConfiguration = masterPreviousRelease == null ?
null : gson.fromJson(masterPreviousRelease.getConfigurations(), null : gson.fromJson(masterPreviousRelease.getConfigurations(),
GsonType.CONFIG); GsonType.CONFIG);
Map<String, String> childNamespaceToPublishConfigs = Map<String, String> childNamespaceToPublishConfigs =
calculateChildNamespaceToPublishConfiguration(parentNamespaceOldConfiguration, calculateChildNamespaceToPublishConfiguration(parentNamespaceOldConfiguration, parentNamespaceItems,
parentNamespaceItems, childReleaseConfiguration, branchReleaseKeys);
childNamespace);
//compare //compare
if (!childNamespaceToPublishConfigs.equals(childReleaseConfiguration)) { if (!childNamespaceToPublishConfigs.equals(childReleaseConfiguration)) {
branchRelease(parentNamespace, childNamespace, releaseName, releaseComment, branchRelease(parentNamespace, childNamespace, releaseName, releaseComment,
childNamespaceToPublishConfigs, parentRelease.getId(), operator, childNamespaceToPublishConfigs, parentRelease.getId(), operator,
ReleaseOperation.MASTER_NORMAL_RELEASE_MERGE_TO_GRAY, isEmergencyPublish); ReleaseOperation.MASTER_NORMAL_RELEASE_MERGE_TO_GRAY, isEmergencyPublish, branchReleaseKeys);
}
}
private Collection<String> getBranchReleaseKeys(long releaseId) {
Page<ReleaseHistory> releaseHistories = releaseHistoryService
.findByReleaseIdAndOperationInOrderByIdDesc(releaseId, BRANCH_RELEASE_OPERATIONS, FIRST_ITEM);
if (!releaseHistories.hasContent()) {
return null;
} }
Map<String, Object> operationContext = gson
.fromJson(releaseHistories.getContent().get(0).getOperationContext(), OPERATION_CONTEXT_TYPE_REFERENCE);
if (operationContext == null || !operationContext.containsKey(ReleaseOperationContext.BRANCH_RELEASE_KEYS)) {
return null;
}
return (Collection<String>) operationContext.get(ReleaseOperationContext.BRANCH_RELEASE_KEYS);
} }
private Release publishBranchNamespace(Namespace parentNamespace, Namespace childNamespace, private Release publishBranchNamespace(Namespace parentNamespace, Namespace childNamespace,
...@@ -289,7 +329,7 @@ public class ReleaseService { ...@@ -289,7 +329,7 @@ public class ReleaseService {
private Release branchRelease(Namespace parentNamespace, Namespace childNamespace, private Release branchRelease(Namespace parentNamespace, Namespace childNamespace,
String releaseName, String releaseComment, String releaseName, String releaseComment,
Map<String, String> configurations, long baseReleaseId, Map<String, String> configurations, long baseReleaseId,
String operator, int releaseOperation, boolean isEmergencyPublish) { String operator, int releaseOperation, boolean isEmergencyPublish, Collection<String> branchReleaseKeys) {
Release previousRelease = findLatestActiveRelease(childNamespace.getAppId(), Release previousRelease = findLatestActiveRelease(childNamespace.getAppId(),
childNamespace.getClusterName(), childNamespace.getClusterName(),
childNamespace.getNamespaceName()); childNamespace.getNamespaceName());
...@@ -298,6 +338,7 @@ public class ReleaseService { ...@@ -298,6 +338,7 @@ public class ReleaseService {
Map<String, Object> releaseOperationContext = Maps.newHashMap(); Map<String, Object> releaseOperationContext = Maps.newHashMap();
releaseOperationContext.put(ReleaseOperationContext.BASE_RELEASE_ID, baseReleaseId); releaseOperationContext.put(ReleaseOperationContext.BASE_RELEASE_ID, baseReleaseId);
releaseOperationContext.put(ReleaseOperationContext.IS_EMERGENCY_PUBLISH, isEmergencyPublish); releaseOperationContext.put(ReleaseOperationContext.IS_EMERGENCY_PUBLISH, isEmergencyPublish);
releaseOperationContext.put(ReleaseOperationContext.BRANCH_RELEASE_KEYS, branchReleaseKeys);
Release release = Release release =
createRelease(childNamespace, releaseName, releaseComment, configurations, operator); createRelease(childNamespace, releaseName, releaseComment, configurations, operator);
...@@ -352,15 +393,6 @@ public class ReleaseService { ...@@ -352,15 +393,6 @@ public class ReleaseService {
return configurations; return configurations;
} }
private Map<String, String> getNamespaceReleaseConfiguration(Namespace namespace) {
Release release = findLatestActiveRelease(namespace);
Map<String, String> configuration = new HashMap<>();
if (release != null) {
configuration = new Gson().fromJson(release.getConfigurations(), GsonType.CONFIG);
}
return configuration;
}
private Release createRelease(Namespace namespace, String name, String comment, private Release createRelease(Namespace namespace, String name, String comment,
Map<String, String> configurations, String operator) { Map<String, String> configurations, String operator) {
Release release = new Release(); Release release = new Release();
...@@ -430,6 +462,17 @@ public class ReleaseService { ...@@ -430,6 +462,17 @@ public class ReleaseService {
return; return;
} }
Release childNamespaceLatestActiveRelease = findLatestActiveRelease(childNamespace);
Map<String, String> childReleaseConfiguration;
Collection<String> branchReleaseKeys;
if (childNamespaceLatestActiveRelease != null) {
childReleaseConfiguration = gson.fromJson(childNamespaceLatestActiveRelease.getConfigurations(), GsonType.CONFIG);
branchReleaseKeys = getBranchReleaseKeys(childNamespaceLatestActiveRelease.getId());
} else {
childReleaseConfiguration = Collections.emptyMap();
branchReleaseKeys = null;
}
Release abandonedRelease = parentNamespaceTwoLatestActiveRelease.get(0); Release abandonedRelease = parentNamespaceTwoLatestActiveRelease.get(0);
Release parentNamespaceNewLatestRelease = parentNamespaceTwoLatestActiveRelease.get(1); Release parentNamespaceNewLatestRelease = parentNamespaceTwoLatestActiveRelease.get(1);
...@@ -443,37 +486,32 @@ public class ReleaseService { ...@@ -443,37 +486,32 @@ public class ReleaseService {
Map<String, String> Map<String, String>
childNamespaceNewConfiguration = childNamespaceNewConfiguration =
calculateChildNamespaceToPublishConfiguration(parentNamespaceAbandonedConfiguration, calculateChildNamespaceToPublishConfiguration(parentNamespaceAbandonedConfiguration,
parentNamespaceNewLatestConfiguration, parentNamespaceNewLatestConfiguration, childReleaseConfiguration, branchReleaseKeys);
childNamespace);
branchRelease(parentNamespace, childNamespace, //compare
TIMESTAMP_FORMAT.format(new Date()) + "-master-rollback-merge-to-gray", "", if (!childNamespaceNewConfiguration.equals(childReleaseConfiguration)) {
childNamespaceNewConfiguration, parentNamespaceNewLatestRelease.getId(), operator, branchRelease(parentNamespace, childNamespace,
ReleaseOperation.MATER_ROLLBACK_MERGE_TO_GRAY, false); TIMESTAMP_FORMAT.format(new Date()) + "-master-rollback-merge-to-gray", "",
childNamespaceNewConfiguration, parentNamespaceNewLatestRelease.getId(), operator,
ReleaseOperation.MATER_ROLLBACK_MERGE_TO_GRAY, false, branchReleaseKeys);
}
} }
private Map<String, String> calculateChildNamespaceToPublishConfiguration( private Map<String, String> calculateChildNamespaceToPublishConfiguration(
Map<String, String> parentNamespaceOldConfiguration, Map<String, String> parentNamespaceOldConfiguration, Map<String, String> parentNamespaceNewConfiguration,
Map<String, String> parentNamespaceNewConfiguration, Map<String, String> childNamespaceLatestActiveConfiguration, Collection<String> branchReleaseKeys) {
Namespace childNamespace) {
//first. calculate child namespace modified configs //first. calculate child namespace modified configs
Release childNamespaceLatestActiveRelease = findLatestActiveRelease(childNamespace);
Map<String, String> childNamespaceLatestActiveConfiguration = childNamespaceLatestActiveRelease == null ? null :
gson.fromJson(childNamespaceLatestActiveRelease
.getConfigurations(),
GsonType.CONFIG);
Map<String, String> childNamespaceModifiedConfiguration = calculateBranchModifiedItemsAccordingToRelease( Map<String, String> childNamespaceModifiedConfiguration = calculateBranchModifiedItemsAccordingToRelease(
parentNamespaceOldConfiguration, childNamespaceLatestActiveConfiguration); parentNamespaceOldConfiguration, childNamespaceLatestActiveConfiguration, branchReleaseKeys);
//second. append child namespace modified configs to parent namespace new latest configuration //second. append child namespace modified configs to parent namespace new latest configuration
return mergeConfiguration(parentNamespaceNewConfiguration, childNamespaceModifiedConfiguration); return mergeConfiguration(parentNamespaceNewConfiguration, childNamespaceModifiedConfiguration);
} }
private Map<String, String> calculateBranchModifiedItemsAccordingToRelease( private Map<String, String> calculateBranchModifiedItemsAccordingToRelease(
Map<String, String> masterReleaseConfigs, Map<String, String> masterReleaseConfigs, Map<String, String> branchReleaseConfigs,
Map<String, String> branchReleaseConfigs) { Collection<String> branchReleaseKeys) {
Map<String, String> modifiedConfigs = new HashMap<>(); Map<String, String> modifiedConfigs = new HashMap<>();
...@@ -481,6 +519,18 @@ public class ReleaseService { ...@@ -481,6 +519,18 @@ public class ReleaseService {
return modifiedConfigs; return modifiedConfigs;
} }
// new logic, retrieve modified configurations based on branch release keys
if (branchReleaseKeys != null) {
for (String branchReleaseKey : branchReleaseKeys) {
if (branchReleaseConfigs.containsKey(branchReleaseKey)) {
modifiedConfigs.put(branchReleaseKey, branchReleaseConfigs.get(branchReleaseKey));
}
}
return modifiedConfigs;
}
// old logic, retrieve modified configurations by comparing branchReleaseConfigs with masterReleaseConfigs
if (CollectionUtils.isEmpty(masterReleaseConfigs)) { if (CollectionUtils.isEmpty(masterReleaseConfigs)) {
return branchReleaseConfigs; return branchReleaseConfigs;
} }
......
...@@ -96,4 +96,4 @@ INSERT INTO `namespace` (ID, `AppId`, `ClusterName`, `NamespaceName`, `IsDeleted ...@@ -96,4 +96,4 @@ INSERT INTO `namespace` (ID, `AppId`, `ClusterName`, `NamespaceName`, `IsDeleted
INSERT INTO `release` (`Id`, `ReleaseKey`, `Name`, `Comment`, `AppId`, `ClusterName`, `NamespaceName`, `Configurations`, `IsAbandoned`)VALUES(6, '20160823102253-fc0071ddf9fd3260', '20160823101703-release', '', 'test', 'default6', 'application', '{"k1":"v1-1","k2":"v2-1","k3":"v3"}', 0); INSERT INTO `release` (`Id`, `ReleaseKey`, `Name`, `Comment`, `AppId`, `ClusterName`, `NamespaceName`, `Configurations`, `IsAbandoned`)VALUES(6, '20160823102253-fc0071ddf9fd3260', '20160823101703-release', '', 'test', 'default6', 'application', '{"k1":"v1-1","k2":"v2-1","k3":"v3"}', 0);
INSERT INTO `release` (`Id`, `ReleaseKey`, `Name`, `Comment`, `AppId`, `ClusterName`, `NamespaceName`, `Configurations`, `IsAbandoned`)VALUES(7, '20160823102253-fc0071ddf9fd3260', '20160823101703-release', '', 'test', 'default6', 'application', '{"k1":"v1","k2":"v2"}', 0); INSERT INTO `release` (`Id`, `ReleaseKey`, `Name`, `Comment`, `AppId`, `ClusterName`, `NamespaceName`, `Configurations`, `IsAbandoned`)VALUES(7, '20160823102253-fc0071ddf9fd3260', '20160823101703-release', '', 'test', 'default6', 'application', '{"k1":"v1","k2":"v2"}', 0);
INSERT INTO `release` (`Id`, `ReleaseKey`, `Name`, `Comment`, `AppId`, `ClusterName`, `NamespaceName`, `Configurations`, `IsAbandoned`)VALUES(8, '20160823102253-fc0071ddf9fd3260', '20160823101703-release', '', 'test', 'child-cluster6', 'application', '{"k1":"v1-2","k2":"v2-1","k3":"v3"}', 0); INSERT INTO `release` (`Id`, `ReleaseKey`, `Name`, `Comment`, `AppId`, `ClusterName`, `NamespaceName`, `Configurations`, `IsAbandoned`)VALUES(8, '20160823102253-fc0071ddf9fd3260', '20160823101703-release', '', 'test', 'child-cluster6', 'application', '{"k1":"v1-2","k2":"v2","k3":"v3"}', 0);
package com.ctrip.framework.apollo; package com.ctrip.framework.apollo;
import java.io.File; import com.ctrip.framework.apollo.core.ConfigConsts;
import java.io.IOException; import java.io.IOException;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
...@@ -16,6 +16,7 @@ import org.eclipse.jetty.server.handler.AbstractHandler; ...@@ -16,6 +16,7 @@ import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.junit.After; import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before; import org.junit.Before;
import org.junit.BeforeClass; import org.junit.BeforeClass;
...@@ -25,9 +26,7 @@ import com.ctrip.framework.apollo.core.enums.Env; ...@@ -25,9 +26,7 @@ import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.core.utils.ClassLoaderUtil; import com.ctrip.framework.apollo.core.utils.ClassLoaderUtil;
import com.ctrip.framework.apollo.internals.DefaultInjector; import com.ctrip.framework.apollo.internals.DefaultInjector;
import com.ctrip.framework.apollo.util.ConfigUtil; import com.ctrip.framework.apollo.util.ConfigUtil;
import com.google.common.base.Charsets;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.io.Files;
import com.google.gson.Gson; import com.google.gson.Gson;
/** /**
...@@ -49,9 +48,12 @@ public abstract class BaseIntegrationTest{ ...@@ -49,9 +48,12 @@ public abstract class BaseIntegrationTest{
@BeforeClass @BeforeClass
public static void beforeClass() throws Exception { public static void beforeClass() throws Exception {
File apolloEnvPropertiesFile = new File(ClassLoaderUtil.getClassPath(), "apollo-env.properties"); System.setProperty(ConfigConsts.APOLLO_META_KEY, metaServiceUrl);
Files.write("dev.meta=" + metaServiceUrl, apolloEnvPropertiesFile, Charsets.UTF_8); }
apolloEnvPropertiesFile.deleteOnExit();
@AfterClass
public static void afterClass() throws Exception {
System.clearProperty(ConfigConsts.APOLLO_META_KEY);
} }
@Before @Before
......
...@@ -27,12 +27,4 @@ public class DefaultMetaServerProviderTest { ...@@ -27,12 +27,4 @@ public class DefaultMetaServerProviderTest {
assertEquals(someMetaAddress, defaultMetaServerProvider.getMetaServerAddress(someEnv)); assertEquals(someMetaAddress, defaultMetaServerProvider.getMetaServerAddress(someEnv));
} }
@Test
public void testWithNoSystemProperty() throws Exception {
Env someEnv = Env.DEV;
DefaultMetaServerProvider defaultMetaServerProvider = new DefaultMetaServerProvider();
assertNull(defaultMetaServerProvider.getMetaServerAddress(someEnv));
}
} }
...@@ -9,4 +9,5 @@ public interface ReleaseOperationContext { ...@@ -9,4 +9,5 @@ public interface ReleaseOperationContext {
String OLD_RULES = "oldRules"; String OLD_RULES = "oldRules";
String BASE_RELEASE_ID = "baseReleaseId"; String BASE_RELEASE_ID = "baseReleaseId";
String IS_EMERGENCY_PUBLISH = "isEmergencyPublish"; String IS_EMERGENCY_PUBLISH = "isEmergencyPublish";
String BRANCH_RELEASE_KEYS = "branchReleaseKeys";
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment