All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jfrog.hudson.release.ReleaseAction Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2011 JFrog Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.jfrog.hudson.release;

import com.google.common.collect.Maps;
import hudson.Util;
import hudson.model.AbstractProject;
import hudson.model.Action;
import hudson.model.BuildableItemWithBuildWrappers;
import hudson.model.Cause;
import hudson.model.Cause.UserCause;
import hudson.tasks.BuildWrapper;
import org.apache.commons.lang.StringUtils;
import org.jfrog.hudson.ArtifactoryPlugin;
import org.jfrog.hudson.ArtifactoryServer;
import org.jfrog.hudson.PluginSettings;
import org.jfrog.hudson.UserPluginInfo;
import org.jfrog.hudson.action.ActionableHelper;
import org.jfrog.hudson.release.scm.AbstractScmCoordinator;
import org.jfrog.hudson.release.scm.svn.SubversionManager;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;

import javax.servlet.ServletException;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * This action leads to execution of the release wrapper. It will collect information from the user about the release
 * and will trigger the release build. This action is not saved in the job xml file.
 *
 * @author Yossi Shaul
 */
public abstract class ReleaseAction

implements Action { private static final Logger log = Logger.getLogger(ReleaseAction.class.getName()); protected final transient P project; private Class wrapperClass; protected VERSIONING versioning; /** * The next release version to change the model to if using one global version. */ protected String releaseVersion; /** * Next (development) version to change the model to if using one global version. */ protected String nextVersion; Boolean pro; boolean createVcsTag; String tagUrl; String tagComment; String nextDevelCommitComment; String stagingRepositoryKey; String stagingComment; boolean createReleaseBranch; String releaseBranch; protected transient boolean strategyRequestFailed = false; protected transient String strategyRequestErrorMessage = null; protected transient boolean strategyPluginExists; protected transient Map stagingStrategy; protected transient String defaultVersioning; protected transient VersionedModule defaultGlobalModule; protected transient Map defaultModules; protected transient VcsConfig defaultVcsConfig; protected transient PromotionConfig defaultPromotionConfig; public enum VERSIONING { GLOBAL("One version for all modules"), PER_MODULE("Version per module"), NONE("Use existing module versions"); // The description to display in the UI private final String displayMessage; VERSIONING(String displayMessage) { this.displayMessage = displayMessage; } public String getDisplayMessage() { return displayMessage; } } public ReleaseAction(P project, Class wrapperClass) { this.project = project; this.wrapperClass = wrapperClass; } /** * invoked from the jelly file * * @throws Exception Any exception */ @SuppressWarnings("UnusedDeclaration") public void init() throws Exception { initBuilderSpecific(); resetFields(); PluginSettings selectedStagingPluginSettings = getSelectedStagingPlugin(); if ((selectedStagingPluginSettings != null) && !UserPluginInfo.NO_PLUGIN_KEY.equals(selectedStagingPluginSettings.getPluginName())) { try { stagingStrategy = getArtifactoryServer().getStagingStrategy(selectedStagingPluginSettings, Util.rawEncode(project.getName())); } catch (Exception e) { log.log(Level.WARNING, "Failed to obtain staging strategy: " + e.getMessage(), e); strategyRequestFailed = true; strategyRequestErrorMessage = "Failed to obtain staging strategy '" + selectedStagingPluginSettings.getPluginName() + "': " + e.getMessage() + ".\nPlease review the log for further information."; stagingStrategy = null; } strategyPluginExists = (stagingStrategy != null) && !stagingStrategy.isEmpty(); } prepareDefaultVersioning(); prepareDefaultGlobalModule(); prepareDefaultModules(); prepareDefaultVcsSettings(); prepareDefaultPromotionConfig(); } private void resetFields() { strategyRequestFailed = false; strategyRequestErrorMessage = null; strategyPluginExists = false; stagingStrategy = null; defaultVersioning = null; defaultGlobalModule = null; defaultModules = null; defaultVcsConfig = null; defaultPromotionConfig = null; } public boolean isStrategyRequestFailed() { return strategyRequestFailed; } public String getStrategyRequestErrorMessage() { return strategyRequestErrorMessage; } public String getTitle() { StringBuilder titleBuilder = new StringBuilder("Artifactory Pro Release Staging"); if (strategyPluginExists && StringUtils.isNotBlank(getSelectedStagingPlugin().getPluginName())) { titleBuilder.append(" - Using the '").append(getSelectedStagingPlugin().getPluginName()) .append("' staging plugin."); } return titleBuilder.toString(); } public String getIconFileName() { if (project.hasPermission(ArtifactoryPlugin.RELEASE)) { return "/plugin/artifactory/images/artifactory-release.png"; } // return null to hide the action (doSubmit will also perform permission check if someone tries direct link) return null; } /** * @return The message to display on the left panel for the perform release action. */ public String getDisplayName() { return "Artifactory Release Staging"; } public String getUrlName() { return "release"; } public VERSIONING getVersioning() { return versioning; } public String getReleaseVersion() { return releaseVersion; } public String getNextVersion() { return nextVersion; } public boolean isCreateVcsTag() { return createVcsTag; } public String getTagUrl() { return tagUrl; } public String getTagComment() { return tagComment; } public String getNextDevelCommitComment() { return nextDevelCommitComment; } public boolean isCreateReleaseBranch() { return createReleaseBranch; } public String getReleaseBranch() { return releaseBranch; } public String getStagingComment() { return stagingComment; } public String getStagingRepositoryKey() { return stagingRepositoryKey; } public String latestVersioningSelection() { return VERSIONING.GLOBAL.name(); } public boolean isArtifactoryPro() { return getArtifactoryServer().isArtifactoryPro(); } public String getDefaultGlobalReleaseVersion() { return (defaultGlobalModule != null) ? defaultGlobalModule.getReleaseVersion() : null; } public String getDefaultGlobalNextDevelopmentVersion() { return (defaultGlobalModule != null) ? defaultGlobalModule.getNextDevelopmentVersion() : null; } public Collection getDefaultModules() { return defaultModules.values(); } public boolean isGit() { return AbstractScmCoordinator.isGitScm(project); } public VcsConfig getDefaultVcsConfig() { return defaultVcsConfig; } public PromotionConfig getDefaultPromotionConfig() { return defaultPromotionConfig; } /** * @return List of target repositories for deployment (release repositories first). Called from the UI. */ @SuppressWarnings({"UnusedDeclaration"}) public abstract List getRepositoryKeys(); public abstract ArtifactoryServer getArtifactoryServer(); /** * Form submission is calling this method */ @SuppressWarnings({"UnusedDeclaration"}) public void doSubmit(StaplerRequest req, StaplerResponse resp) throws IOException, ServletException { // enforce release permissions project.checkPermission(ArtifactoryPlugin.RELEASE); req.bindParameters(this); String versioningStr = req.getParameter("versioning"); versioning = VERSIONING.valueOf(versioningStr); switch (versioning) { case GLOBAL: doGlobalVersioning(req); break; case PER_MODULE: doPerModuleVersioning(req); } createVcsTag = req.getParameter("createVcsTag") != null; if (createVcsTag) { tagUrl = req.getParameter("tagUrl"); tagComment = req.getParameter("tagComment"); } nextDevelCommitComment = req.getParameter("nextDevelCommitComment"); createReleaseBranch = req.getParameter("createReleaseBranch") != null; if (createReleaseBranch) { releaseBranch = req.getParameter("releaseBranch"); } stagingRepositoryKey = req.getParameter("repositoryKey"); stagingComment = req.getParameter("stagingComment"); // schedule release build if (project.scheduleBuild(0, new UserCause(), this)) { // redirect to the project page resp.sendRedirect(project.getAbsoluteUrl()); } } public abstract String getReleaseVersionFor(Object moduleName); public abstract String getNextVersionFor(Object moduleName); protected void initBuilderSpecific() throws Exception { } protected String getDefaultNextDevelCommitMessage() { return SubversionManager.COMMENT_PREFIX + "Next development version"; } protected String getBaseTagUrlAccordingToScm(String baseTagUrl) { if (AbstractScmCoordinator.isSvn(project) && !baseTagUrl.endsWith("/")) { return baseTagUrl + "/"; } return baseTagUrl; } /** * Execute the {@link VERSIONING#GLOBAL} strategy of the versioning mechanism, which assigns all modules the same * version for the release and for the next development version. * * @param req The request that is coming from the form when staging. */ protected void doGlobalVersioning(StaplerRequest req) { releaseVersion = req.getParameter("releaseVersion"); nextVersion = req.getParameter("nextVersion"); } protected W getWrapper() { return ActionableHelper.getBuildWrapper(project, wrapperClass); } protected String calculateReleaseVersion(String fromVersion) { return fromVersion.replace("-SNAPSHOT", ""); } /** * Calculates the next snapshot version based on the current release version * * @param fromVersion The version to bump to next development version * @return The next calculated development (snapshot) version */ protected String calculateNextVersion(String fromVersion) { // first turn it to release version fromVersion = calculateReleaseVersion(fromVersion); String nextVersion; int lastDotIndex = fromVersion.lastIndexOf('.'); try { if (lastDotIndex != -1) { // probably a major minor version e.g., 2.1.1 String minorVersionToken = fromVersion.substring(lastDotIndex + 1); String nextMinorVersion; int lastDashIndex = minorVersionToken.lastIndexOf('-'); if (lastDashIndex != -1) { // probably a minor-buildNum e.g., 2.1.1-4 (should change to 2.1.1-5) String buildNumber = minorVersionToken.substring(lastDashIndex + 1); int nextBuildNumber = Integer.parseInt(buildNumber) + 1; nextMinorVersion = minorVersionToken.substring(0, lastDashIndex + 1) + nextBuildNumber; } else { nextMinorVersion = Integer.parseInt(minorVersionToken) + 1 + ""; } nextVersion = fromVersion.substring(0, lastDotIndex + 1) + nextMinorVersion; } else { // maybe it's just a major version; try to parse as an int int nextMajorVersion = Integer.parseInt(fromVersion) + 1; nextVersion = nextMajorVersion + ""; } } catch (NumberFormatException e) { return fromVersion; } return nextVersion + "-SNAPSHOT"; } /** * Execute the {@link VERSIONING#PER_MODULE} strategy of the versioning mechanism, which assigns each module its own * version for release and for the next development version * * @param req The request that is coming from the form when staging. */ protected abstract void doPerModuleVersioning(StaplerRequest req); protected abstract PluginSettings getSelectedStagingPlugin(); protected abstract void prepareBuilderSpecificDefaultGlobalModule(); protected abstract void prepareBuilderSpecificDefaultModules(); protected abstract void prepareBuilderSpecificDefaultVcsConfig(); protected abstract void prepareBuilderSpecificDefaultPromotionConfig(); protected void prepareBuilderSpecificDefaultVersioning() { } private void prepareDefaultVersioning() { if (strategyPluginExists) { if (stagingStrategy.containsKey("defaultModuleVersion")) { defaultVersioning = VERSIONING.GLOBAL.name(); } else if (stagingStrategy.containsKey("moduleVersionsMap")) { defaultVersioning = VERSIONING.PER_MODULE.name(); } } if (StringUtils.isBlank(defaultVersioning)) { prepareBuilderSpecificDefaultVersioning(); } } private void prepareDefaultGlobalModule() { if (strategyPluginExists) { if (stagingStrategy.containsKey("defaultModuleVersion")) { Map defaultModuleVersion = (Map) stagingStrategy.get("defaultModuleVersion"); defaultGlobalModule = new VersionedModule(defaultModuleVersion.get("moduleId"), defaultModuleVersion.get("nextRelease"), defaultModuleVersion.get("nextDevelopment")); } } if (defaultGlobalModule == null) { prepareBuilderSpecificDefaultGlobalModule(); } } private void prepareDefaultModules() { if (strategyPluginExists) { if (stagingStrategy.containsKey("moduleVersionsMap")) { Map> moduleVersionsMap = (Map>) stagingStrategy.get("moduleVersionsMap"); defaultModules = Maps.newHashMap(); if (!moduleVersionsMap.isEmpty()) { for (Map moduleVersion : moduleVersionsMap.values()) { String moduleId = moduleVersion.get("moduleId"); defaultModules.put(moduleId, new VersionedModule(moduleId, moduleVersion.get("nextRelease"), moduleVersion.get("nextDevelopment"))); } } } } if (defaultModules == null) { prepareBuilderSpecificDefaultModules(); } } private void prepareDefaultVcsSettings() { if (strategyPluginExists) { if (stagingStrategy.containsKey("vcsConfig")) { Map vcsConfig = (Map) stagingStrategy.get("vcsConfig"); defaultVcsConfig = new VcsConfig(((Boolean) vcsConfig.get("useReleaseBranch")), getStagingConfigAsString(vcsConfig, "releaseBranchName"), ((Boolean) vcsConfig.get("createTag")), getStagingConfigAsString(vcsConfig, "tagUrlOrName"), getStagingConfigAsString(vcsConfig, "tagComment"), getStagingConfigAsString(vcsConfig, "nextDevelopmentVersionComment")); } } if (defaultVcsConfig == null) { prepareBuilderSpecificDefaultVcsConfig(); } } private void prepareDefaultPromotionConfig() { if (strategyPluginExists) { if (stagingStrategy.containsKey("promotionConfig")) { Map promotionConfig = (Map) stagingStrategy.get("promotionConfig"); defaultPromotionConfig = new PromotionConfig(promotionConfig.get("targetRepository"), promotionConfig.get("comment")); } } if (defaultPromotionConfig == null) { prepareBuilderSpecificDefaultPromotionConfig(); } } private String getStagingConfigAsString(Map configMap, String key) { if (configMap.containsKey(key)) { return configMap.get(key).toString(); } return null; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy