Preface
Jenkins is a popular open source Continuous Integration tool that is widely used in project development and has functions such as automated construction, testing and deployment.
Recently, I participated in the development of the company's integrated test platform and encountered many problems in the development. The two-week iteration is about to be completed. I will use this blog to record the problems in the development for readers' reference.
The company has many applications, so we need to understand how to build these applications in Jenkins. I have participated in two types of commander applications, one is the big data class, and the other is the scala application of our server architecture group.
1. Big Data Application
The configuration is as follows:
The xml file corresponding to the configuration file: obtain the xml configuration file through crul: http://host/job/tar_py_dwx_dev/config.xml
<project><actions/><description/><keepDependencies>false</keepDependencies><properties><com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty plugin="[email protected]"><gitLabConnection/</com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty><hudson.plugins.promoted__builds.JobPropertyImpl plugin="[email protected]"><activeProcessNames><string>Deploy DEV</string></activeProcessNames></hudson.plugins.promoted__builds.JobPropertyImpl></properties><scm plugin="[email protected]"><configVersion>2</configVersion><userRemoteConfigs><hudson.plugins.git.UserRemoteConfig><url>ssh://[email protected]:10022/bigdata/dwx.git</url><credentialsId>84f4be19-ea8d-4271 -8cfb-42af8f507285</credentialsId></hudson.plugins.git.UserRemoteConfig></userRemoteConfigs><branches><hudson.plugins.git.BranchSpec><name>*/develop</name></hudson.plugins.git.BranchSpec></branch es><doGenerateSubmoduleConfigurations>false</doGenerateSubmoduleConfigurations><submoduleCfg/><extensions/</scm><assignedNode>!macmini</assignedNode><canRoam>false</canRoam><disabled>false</disa bled><blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding><blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding><triggers><hudson.triggers.SCMTrigger><spec>H/5 * * * * *</spec><ignorePostCommitHooks>false</ignorePostCommitHooks></hudson.triggers.SCMTrigger></triggers><concurrentBuild>false</concurrentBuild><builders><hudson.tasks.Shell><command>project=dwx1 cd ${WORKSPACE} tar zcvf ${project}.tar.gz * aws s3 cp ${project}.tar.gz s3://lattebank-jenkins-build-dev/${JOB_BASE_NAME}/${BUILD_NUMBER}/ --region cn-north-1 rm -rf ${project}.tar.gz</command></hudson.tasks.Shell></builders><publishers/><buildWrappers/><project>
The information obtained from the xml does not correspond to the configuration file in the figure.
Promotion scripts cannot be obtained in the xml configuration file. At this time, there is a problem. This API cannot obtain the promotion scripts. At the same time, this also brings great challenges to our work. It also means that the deployment of the commander application can not be realized through this method and the configuration of jenkins through the platform method can be directly operated.
However, after querying the relevant APIs, we cannot find the relevant content. After unremitting efforts, we finally found the API related to the Promote build plug-in
Query: http://host/job/jobName/promotion/process/promotionName/config.xml
This interface can obtain its xml file, but it cannot add or modify the configuration file.
I have encapsulated some methods for this:
/** * @author chenlang * date 2018/5/7 */@Slf4jpublic class JenkinsPromotionUtils { private static final String SUB_PATH_PROMOTION_COOMMAND = "/hudson.plugins.promoted__builds.PromotionProcess"; private static final String SUB_PATH_BUILD = "/buildSteps"; private static final String SUB_PATH_BUILDER_SHELL_COMMAND = "/hudson.tasks.Shell/command"; private static final String PATH_PROMOTION_COMMAND = SUB_PATH_PROMOTION_COOMMAND + SUB_PATH_BUILD + SUB_PATH_BUILDER_SHELL_COMMAND; private static String CREATE_PROMOTION_JSON = "{'properties':{'stapler-class-bag':'true','hudson-plugins-promoted_builds-JobPropertyImpl':{'promotions':{'activeItems':{'name':'%s','isVisible':'','icon':'star-gold','hasAssignedLabel':false,'assignedLabelString':'','conditions':{'stapler-class-bag':'true'}}}}}"; private static final String CONTENT_TYPE = "application/x-www-form-urlencoded"; public static void updatePromotionShell(Document jobConfigDocument, String jobName, JenkinsPromotionClient jenkinsPromotionClient, String promotionShell, String path) throws IOException, DocumentException { if (StringUtils.isBlank(promotionShell)) { return; } String promotionName = getPromotionName(jobConfigDocument, path); Document document = jenkinsPromotionClient.getJobPromotionXml(jobName, promotionName); document.selectSingleNode(PATH_PROMOTION_COMMAND).setText(promotionShell); jenkinsPromotionClient.updateJob(jobName, promotionName, document.asXML()); } public static void createPromotionShell(Document jobConfigDocument, String tmpJobName, String jobName, String promotionShell, String path, JenkinsPromotionClient jenkinsPromotionClient) throws IOException, DocumentException { if (StringUtils.isBlank(promotionShell)) { return; } String promotionName = getPromotionName(jobConfigDocument, path); Document document = jenkinsPromotionClient.getJobPromotionXml(tmpJobName, promotionName); document.selectSingleNode(PATH_PROMOTION_COMMAND).setText(promotionShell); Map<String, String> map = Maps.newHashMap(); map.put("Content-Type", CONTENT_TYPE); map.put("json", String.format(CREATE_PROMOTION_JSON, promotionName)); try { jenkinsPromotionClient.createJob(jobName, map); } catch (Exception e) { log.error("Failed when starting a promotion" + e); } jenkinsPromotionClient.createJob(jobName, promotionName, document.asXML()); } public static String getPromotionName(Document jobConfigDocument, String path) { return jobConfigDocument.selectSingleNode(path).getText(); }} package cn.caijiajia.phoenix.service.jenkins;import com.offbytwo.jenkins.client.JenkinsHttpClient;import com.offbytwo.jenkins.client.util.EncodingUtils;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.DocumentHelper;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import java.io.IOException;import java.util.Map; /** * @author chenlang * date 2018/5/4 */@Componentpublic class JenkinsPromotionClient { @Autowired private JenkinsHttpClient jenkinsHttpClient; public JenkinsPromotionClient() { } /** * Get the job's promotion configuration file* * @param jobName job name* @param promotionName promotion name* @return * @throws IOException */ public Document getJobPromotionXml(String jobName, String promotionName) throws IOException, DocumentException { return DocumentHelper.parseText(this.getJobXml(jobName, promotionName)); } /** * Update job * * @param jobName * @param promotionName * @param jobXml * @throws IOException */ public void updateJob(String jobName, String promotionName, String jobXml) throws IOException { this.jenkinsHttpClient.post_xml(this.toJobBaseUrl(jobName, promotionName) + "/config.xml", jobXml, true); } /** * Add job script* * @param jobName * @param jobXml * @throws IOException */ public void createJob(String jobName, String promotionName, String jobXml) throws IOException { this.jenkinsHttpClient.post_xml(this.toJobBaseUrl(jobName, promotionName) + "/config.xml", jobXml, true); } /** * Add a job of promotion * * @param jobName * @param map * @throws IOException */ public void createJob(String jobName, Map map) throws IOException { this.jenkinsHttpClient.post_form("/job/" + EncodingUtils.encode(jobName) + "/configSubmit?", map, false); } private String getJobXml(String jobName, String promotionName) throws IOException { return this.jenkinsHttpClient.get(this.toJobBaseUrl(jobName, promotionName) + "/config.xml"); } private String toJobBaseUrl(String jobName, String promotionName) { return "/job/" + EncodingUtils.encode(jobName) + "/promotion/process/" + promotionName; } /** * Construction of promotion scripts* @param jobName * @param promotionName * @param version * @param isFirstBuild * @throws IOException */ public void build(String jobName,String promotionName,Integer version,boolean isFirstBuild) throws IOException{ if (isFirstBuild) { this.jenkinsHttpClient.post("/job/"+ EncodingUtils.encode(jobName) + "/"+version+"/promotion/forcePromotion?name="+promotionName+"&json=%7B%7D&Submit=Force promotion"); } else { this.jenkinsHttpClient.post("/job/"+ EncodingUtils.encode(jobName) + "/"+version+"/promotion/"+promotionName+"/build?json=%7B%7D&Submit=Re-execute promotion"); } }}The method encapsulates the configuration addition, deletion, modification and query of the promote build plug-in, as well as the construction of the promotion script.
Summarize
The above is the entire content of this article. I hope that the content of this article has certain reference value for everyone's study or work. If you have any questions, you can leave a message to communicate. Thank you for your support to Wulin.com.