├── .gitignore ├── Jenkinsfile ├── LICENSE ├── README.md ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── orctom │ │ └── jenkins │ │ └── plugin │ │ └── globalpostscript │ │ ├── GlobalPostScript.java │ │ ├── GlobalPostScriptAction.java │ │ ├── GlobalPostScriptPlugin.java │ │ ├── ScriptContentLoader.java │ │ ├── ScriptExecutor.java │ │ ├── model │ │ ├── ScriptContent.java │ │ └── URL.java │ │ └── runner │ │ ├── GroovyScriptRunner.java │ │ ├── ScriptRunner.java │ │ └── ShellScriptRunner.java ├── resources │ ├── com │ │ └── orctom │ │ │ └── jenkins │ │ │ └── plugin │ │ │ └── globalpostscript │ │ │ ├── GlobalPostScript │ │ │ └── global.jelly │ │ │ └── GlobalPostScriptAction │ │ │ └── badge.jelly │ └── index.jelly └── webapp │ └── img │ ├── calendar.png │ ├── cancel.png │ ├── check.png │ ├── computer.png │ ├── danger.png │ ├── error.png │ ├── file.png │ ├── good.png │ ├── green.png │ ├── laptop.png │ ├── lock.png │ ├── orange.png │ ├── planning.png │ ├── profit.png │ ├── prohibited.png │ ├── red.png │ ├── server.png │ ├── star.png │ ├── success.png │ ├── warning.png │ └── yellow.png └── test ├── java └── com │ └── orctom │ └── jenkins │ └── plugin │ └── globalpostscript │ ├── ScriptTest.java │ └── URLTest.java └── resources ├── downstream_job_trigger.groovy ├── test.groovy ├── test.py ├── test2.groovy └── test2.py /.gitignore: -------------------------------------------------------------------------------- 1 | DummyTest.java 2 | *.class 3 | 4 | # Package Files # 5 | *.jar 6 | *.war 7 | *.ear 8 | *.iml 9 | 10 | /work 11 | /target 12 | /.idea 13 | /.settings/ 14 | /.classpath 15 | /.project 16 | pom.xml.releaseBackup 17 | release.properties 18 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | buildPlugin( 2 | configurations: [ 3 | [platform: 'linux', jdk: 11], 4 | [platform: 'windows', jdk: 11], 5 | ]) 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 ORCTOM 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # global-post-script-plugin [![Build Status](https://jenkins.ci.cloudbees.com/buildStatus/icon?job=plugins/global-post-script-plugin)](https://jenkins.ci.cloudbees.com/job/plugins/job/global-post-script-plugin/) 3 | Execute a global configured groovy script after each build of each job managed by the Jenkins 4 | 5 | **NOTICE: python script support removed as of 1.0.0** 6 | 7 | See also: https://wiki.jenkins-ci.org/display/JENKINS/Global+Post+Script+Plugin 8 | 9 | ## Variables that could be used in the script file 10 | ### Jenkins Built-in Variables 11 | | Variable | Description | Sample Data | 12 | | -------- | ----------- | ------ | 13 | | BUILD_ID | Build timestamp as ID | 2014-06-26_07-16-51 | 14 | | BUILD_NUMBER | Build No# | 16 | 15 | | BUILD_RESULT | Build result | SUCCESS / UNSTABLE / FAILURE ... | 16 | | BUILD_TAG | Job Name + Build No# | jenkins-test-job-16 | 17 | | BUILD_URL | The URL of this build | http://localhost:8080/job/test-job/16/ | 18 | | JENKINS_HOME | The path of the root folder of Jenkins | ~/workspace-idea/global-post-script-plugin/./work | 19 | | JENKINS_URL | The root URL of Jenkins | http://localhost:8080/ | 20 | | JOB_NAME | Name of the job | test-job | 21 | | JOB_URL | URL of the job | http://localhost:8080/job/test-job/ | 22 | | MAVEN_CMD_LINE_ARGS | Maven command args | clean install | 23 | | NODE_LABELS | Lables of the nodes where the build could be executed | master | 24 | | NODE_NAME | Name of the node where the build executed | master | 25 | | SVN_REVISION | SVN redeploy_targets?.trivision | 185214 | 26 | | SVN_URL | SVN URL | | 27 | | WORKSPACE | The path of the workspace | deploy_targets?.tri~/workspace-idea/global-post-script-plugin/work/workspace/LOGANALYZE | 28 | 29 | ### Extra variables 30 | Parameters of `parameterized build` or parameters been passed in by `-Dparameter_name=parameter_value` are also available 31 | 32 | ### `manager` 33 | An extra object is available as groovy variables: `manager`, provided 4 methods: 34 | 35 | | Method | Description | 36 | | -------- | ----------- | 37 | | `isVar(String name)` | Check if a variable is defined and usable in the script | 38 | | `isNotBlankVar(String name)` | Check if a variable is defined and usable in the script, and with a non-blank value | 39 | | `addBadge(String icon, String text)` | Add a badge to the build | 40 | | `addShortText(String text)` | Add a text label to the build | 41 | | `triggerJob(String jobName)` | Trigger a job managed by the same Jenkins | 42 | | `triggerJob(String jobName, HashMap params)` | Trigger a job managed by the same Jenkins with parameters| 43 | | `triggerRemoteJob(String url)` | Trigger a job by URL | 44 | 45 | ## Supported Scripts 46 | ### Groovy 47 | Sample: 48 | ```groovy 49 | out.println("repo to: $GIT_URL") 50 | job = hudson.model.Hudson.instance.getItem("TEST2") 51 | build = job.getLastBuild() 52 | println build 53 | ``` 54 | 55 | Sample: 56 | ```groovy 57 | out.println("deploy to: " + deploy_targets) 58 | ``` 59 | 60 | Sample: 61 | ```groovy 62 | if (binding.variables.containsKey("variable_name")) { 63 | ... 64 | } 65 | ``` 66 | 67 | Sample: 68 | ```groovy 69 | def triggers = [ 70 | wwwsqs8: { 71 | def params = [ 72 | PARENT_BUILD_NUMBER: '$BUILD_NUMBER', 73 | PARENT_JOB_NAME: '$JOB_NAME', 74 | any_param_name: '$deploy_targets' 75 | ] 76 | manager.triggerJob("WWW_JBEHAVE_TEST", params) 77 | manager.triggerJob("WWW_MOBILE_API_TEST") 78 | manager.triggerRemoteJob("http://localhost/job/Dev_Launch_WWW_SQS_REGRESSION/build?token=88e4b5fd1d28949710a9c4924775ce40&delay=1800sec") 79 | }, 80 | wwwsqm8: { 81 | manager.triggerRemoteJob("http://localhost/job/Dev_Launch_WWW_SQM_REGRESSION/build?token=88e4b5fd1d28949710a9c4924775ce40&delay=1800sec") 82 | }, 83 | bsdsqs8: { 84 | manager.triggerJob("BSD_JBEHAVE_TEST") 85 | manager.triggerJob("BSD_MOBILE_API_TEST") 86 | manager.triggerRemoteJob("http://localhost/job/Dev_Launch_BSD_SQS_REGRESSION/build?token=88e4b5fd1d28949710a9c4924775ce40&delay=1800sec") 87 | }, 88 | bsdsqm8: { 89 | manager.triggerRemoteJob("http://localhost/job/Dev_Launch_BSD_SQM_REGRESSION/build?token=88e4b5fd1d28949710a9c4924775ce40&delay=1800sec") 90 | }, 91 | gmlsqs8: { 92 | manager.triggerJob("GMIL_JBEHAVE_TEST") 93 | manager.triggerRemoteJob("http://localhost/job/Dev_Launch_GMIL_SQS_REGRESSION/build?token=88e4b5fd1d28949710a9c4924775ce40&delay=1800sec") 94 | }, 95 | gmlsqm8: { 96 | manager.triggerRemoteJob("http://localhost/job/Dev_Launch_GMIL_SQM_REGRESSION/build?token=88e4b5fd1d28949710a9c4924775ce40&delay=1800sec") 97 | }, 98 | basepom: { 99 | manager.triggerJob("basepom") 100 | } 101 | ] 102 | 103 | if (manager.isVar("deploy") && manager.isNotBlankVar("deploy_targets") && "true" == deploy) { 104 | dropped = false 105 | deploy_targets.split(',').each { 106 | trigger = triggers[it] 107 | if (trigger) { 108 | trigger() 109 | dropped = true 110 | } 111 | } 112 | if (dropped) { 113 | manager.addBadge("server.png", "[SQ: " + deploy_targets + "]") 114 | } 115 | } 116 | ``` 117 | 118 | ### bat/sh 119 | **NO** variables will passed into the script 120 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | org.jenkins-ci.plugins 6 | plugin 7 | 4.54 8 | 9 | 10 | global-post-script 11 | 1.1.6-SNAPSHOT 12 | hpi 13 | 14 | https://wiki.jenkins-ci.org/display/JENKINS/Global+Post+Script+Plugin 15 | Global Post Script Plugin 16 | 17 | 18 | https://github.com/jenkinsci/global-post-script-plugin/ 19 | scm:git:git@github.com:jenkinsci/global-post-script-plugin.git 20 | scm:git:git@github.com:jenkinsci/global-post-script-plugin.git 21 | master 22 | 23 | 24 | 25 | UTF-8 26 | 2.375.2 27 | 28 | 29 | 30 | 31 | orctom 32 | Hao CHEN 33 | orctom@gmail.com 34 | 35 | 36 | 37 | 38 | 39 | false 40 | maven.jenkins-ci.org 41 | https://repo.jenkins-ci.org/releases/ 42 | 43 | 44 | maven.jenkins-ci.org 45 | https://repo.jenkins-ci.org/snapshots/ 46 | 47 | 48 | 49 | 50 | 51 | repo.jenkins-ci.org 52 | https://repo.jenkins-ci.org/public/ 53 | 54 | 55 | 56 | 57 | repo.jenkins-ci.org 58 | https://repo.jenkins-ci.org/public/ 59 | 60 | 61 | 62 | 63 | 64 | 65 | org.apache.maven.plugins 66 | maven-release-plugin 67 | 68 | deploy 69 | 70 | 71 | 72 | org.jenkins-ci.tools 73 | maven-hpi-plugin 74 | true 75 | 76 | 77 | 78 | 79 | 80 | 81 | org.codehaus.plexus 82 | plexus-utils 83 | 3.0.16 84 | 85 | 86 | junit 87 | junit 88 | 4.13.2 89 | test 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /src/main/java/com/orctom/jenkins/plugin/globalpostscript/GlobalPostScript.java: -------------------------------------------------------------------------------- 1 | package com.orctom.jenkins.plugin.globalpostscript; 2 | 3 | import com.google.common.collect.Lists; 4 | import com.orctom.jenkins.plugin.globalpostscript.model.URL; 5 | import hudson.EnvVars; 6 | import hudson.Extension; 7 | import hudson.console.ModelHyperlinkNote; 8 | import hudson.model.*; 9 | import hudson.model.listeners.RunListener; 10 | import hudson.util.ComboBoxModel; 11 | import hudson.util.FormValidation; 12 | import jenkins.model.Jenkins; 13 | import net.sf.json.JSONObject; 14 | import org.apache.commons.codec.net.URLCodec; 15 | import org.apache.commons.httpclient.HttpClient; 16 | import org.apache.commons.httpclient.HttpMethod; 17 | import org.apache.commons.httpclient.methods.GetMethod; 18 | import org.apache.commons.lang.StringUtils; 19 | import org.kohsuke.stapler.QueryParameter; 20 | import org.kohsuke.stapler.StaplerRequest; 21 | 22 | import javax.servlet.ServletException; 23 | import java.io.File; 24 | import java.io.FilenameFilter; 25 | import java.io.IOException; 26 | import java.util.Collections; 27 | import java.util.List; 28 | import java.util.Map; 29 | 30 | /** 31 | * Global Post Script that will be executed for all jobs 32 | * Created by hao on 6/25/2014. 33 | */ 34 | @Extension 35 | public class GlobalPostScript extends RunListener> implements Describable { 36 | 37 | public static final String SCRIPT_FOLDER = File.separator + "global-post-script" + File.separator; 38 | 39 | public static String getRemoteJobUrl(String jobUrl) { 40 | if (jobUrl.contains("buildByToken")) { 41 | return jobUrl.substring(0, jobUrl.indexOf("buildByToken")) + "job/" + jobUrl.replaceFirst(".*job=(\\w+)&.*", "$1"); 42 | } else { 43 | return jobUrl.substring(0, jobUrl.lastIndexOf("/") + 1); 44 | } 45 | } 46 | 47 | @Override 48 | public void onCompleted(Run run, TaskListener listener) { 49 | EnvVars envVars = getEnvVars(run, listener); 50 | 51 | Result result = run.getResult(); 52 | if (result == null || result.isWorseThan(getDescriptorImpl().getResultCondition())) { 53 | return; 54 | } 55 | 56 | String script = getDescriptorImpl().getScript(); 57 | File file = new File(Jenkins.get().getRootDir().getAbsolutePath() + SCRIPT_FOLDER, script); 58 | if (file.exists()) { 59 | try { 60 | BadgeManager manager = new BadgeManager(run, listener); 61 | ScriptExecutor executor = new ScriptExecutor(listener, manager); 62 | executor.execute(file, envVars); 63 | } catch (Throwable e) { 64 | e.printStackTrace(listener.getLogger()); 65 | } 66 | } 67 | } 68 | 69 | private EnvVars getEnvVars(Run run, TaskListener listener) { 70 | try { 71 | EnvVars envVars = run.getEnvironment(listener); 72 | Result result = run.getResult(); 73 | envVars.put("BUILD_RESULT", result == null ? "ongoing" : result.toString()); 74 | return envVars; 75 | } catch (Throwable e) { 76 | e.printStackTrace(); 77 | return null; 78 | } 79 | } 80 | 81 | public Descriptor getDescriptor() { 82 | return getDescriptorImpl(); 83 | } 84 | 85 | public DescriptorImpl getDescriptorImpl() { 86 | return (DescriptorImpl) Jenkins.get().getDescriptorOrDie(GlobalPostScript.class); 87 | } 88 | 89 | @SuppressWarnings("unchecked") 90 | public static class BadgeManager { 91 | 92 | private Run run; 93 | private TaskListener listener; 94 | private EnvVars envVars; 95 | 96 | public BadgeManager(Run run, TaskListener listener) { 97 | this.run = run; 98 | this.listener = listener; 99 | 100 | if (null != run) { 101 | try { 102 | envVars = run.getEnvironment(listener); 103 | } catch (IOException e) { 104 | e.printStackTrace(); 105 | } catch (InterruptedException e) { 106 | e.printStackTrace(); 107 | } 108 | } 109 | } 110 | 111 | public boolean isVar(String name) { 112 | if (null == envVars || StringUtils.isBlank(name)) { 113 | return false; 114 | } 115 | 116 | return envVars.containsKey(name); 117 | } 118 | 119 | public boolean isNotBlankVar(String name) { 120 | if (null == envVars || StringUtils.isBlank(name)) { 121 | return false; 122 | } 123 | 124 | return StringUtils.isNotBlank(envVars.get(name)); 125 | } 126 | 127 | public void addBadge(String icon, String text) { 128 | run.addAction(GlobalPostScriptAction.createBadge(icon, text)); 129 | } 130 | 131 | public void addShortText(String text) { 132 | run.addAction(GlobalPostScriptAction.addShortText(text)); 133 | } 134 | 135 | public void triggerJob(String jobName) { 136 | triggerJob(jobName, Collections.emptyMap()); 137 | } 138 | 139 | public void triggerJob(String jobName, Map params) { 140 | List newParams = Lists.newArrayList(); 141 | for (Map.Entry entry : params.entrySet()) { 142 | newParams.add(new StringParameterValue(entry.getKey(), entry.getValue())); 143 | } 144 | AbstractProject job = Jenkins.get().getItem(jobName, run.getParent().getParent(), AbstractProject.class); 145 | if (null != job) { 146 | Cause cause = new Cause.UpstreamCause(run); 147 | boolean scheduled = job.scheduleBuild(job.getQuietPeriod(), cause, new ParametersAction(newParams)); 148 | if (Jenkins.get().getItemByFullName(job.getFullName()) == job) { 149 | String name = ModelHyperlinkNote.encodeTo(job) + " " 150 | + ModelHyperlinkNote.encodeTo( 151 | job.getAbsoluteUrl() + job.getNextBuildNumber() + "/", 152 | "#" + job.getNextBuildNumber()); 153 | if (scheduled) { 154 | println("Triggering " + name); 155 | } else { 156 | println("In queue " + name); 157 | } 158 | } 159 | } else { 160 | println("[ERROR] Downstream job not found: " + jobName); 161 | } 162 | } 163 | 164 | public void triggerRemoteJob(String jobTriggerUrl) { 165 | String url = jobTriggerUrl; 166 | String jobUrl = getRemoteJobUrl(jobTriggerUrl); 167 | 168 | try { 169 | URL jobURL = new URL(jobTriggerUrl); 170 | jobURL.appendToParamValue("cause", new URLCodec().encode(getCause(), "UTF-8")); 171 | url = jobURL.getURL(); 172 | } catch (Exception e) { 173 | println("[WARNING] ignoring URL exception for " + jobTriggerUrl); 174 | } 175 | 176 | HttpClient client = new HttpClient(); 177 | HttpMethod method = new GetMethod(url); 178 | try { 179 | client.executeMethod(method); 180 | int statusCode = method.getStatusCode(); 181 | if (statusCode < 400) { 182 | println("Triggering " + jobUrl); 183 | } else { 184 | println("[ERROR] Failed to trigger: " + jobUrl + " | " + statusCode); 185 | } 186 | } catch (Exception e) { 187 | e.printStackTrace(); 188 | println("[ERROR] Failed to trigger: " + jobUrl + " | " + e.getMessage()); 189 | } finally { 190 | method.releaseConnection(); 191 | } 192 | } 193 | 194 | public String getCause() { 195 | List causes = run.getCauses(); 196 | StringBuilder cause = new StringBuilder(50); 197 | for (Cause c : causes) { 198 | String desc = c.getShortDescription(); 199 | if (StringUtils.isNotEmpty(desc)) { 200 | cause.append(c.getShortDescription()).append(" "); 201 | } 202 | } 203 | 204 | String rootUrl = Jenkins.get().getRootUrl(); 205 | if (StringUtils.isNotEmpty(rootUrl)) { 206 | cause.append("on ").append(rootUrl).append(" "); 207 | } 208 | 209 | cause.append("[").append(run.getParent().getName()).append("]"); 210 | return cause.toString(); 211 | } 212 | 213 | private void println(String message) { 214 | listener.getLogger().println(message); 215 | } 216 | } 217 | 218 | @Extension 219 | public static final class DescriptorImpl extends Descriptor { 220 | 221 | private String script = "downstream_job_trigger.groovy"; 222 | private Result runCondition = Result.UNSTABLE; 223 | 224 | public DescriptorImpl() { 225 | load(); 226 | } 227 | 228 | public FormValidation doCheckScript(@QueryParameter("script") String name) throws IOException, ServletException { 229 | Jenkins.get().checkPermission(Jenkins.ADMINISTER); 230 | if (StringUtils.isEmpty(name)) { 231 | return FormValidation.error("Please set the script name"); 232 | } 233 | if (!name.matches("[a-zA-Z0-9_\\-]+\\.\\w+")) { 234 | return FormValidation.error("Please make sure it's a valid file name with extension"); 235 | } 236 | return FormValidation.ok(); 237 | } 238 | 239 | public ComboBoxModel doFillScriptItems() { 240 | ComboBoxModel items = new ComboBoxModel(); 241 | 242 | File scriptFolder = new File(Jenkins.get().getRootDir().getAbsolutePath() + SCRIPT_FOLDER); 243 | FilenameFilter filter = new FilenameFilter() { 244 | public boolean accept(File dir, String name) { 245 | String fileName = name.toLowerCase(); 246 | return new File(dir, name).isFile() && ( 247 | fileName.endsWith(".groovy") || 248 | fileName.endsWith(".gvy") || 249 | fileName.endsWith(".gy") || 250 | fileName.endsWith(".gsh") || 251 | fileName.endsWith(".bat") || 252 | fileName.endsWith(".sh") 253 | ); 254 | } 255 | }; 256 | 257 | String [] filteredFiles = scriptFolder.list(filter); 258 | if (filteredFiles != null) { 259 | Collections.addAll(items, filteredFiles); 260 | } 261 | return items; 262 | } 263 | 264 | public boolean isApplicable(Class aClass) { 265 | return true; 266 | } 267 | 268 | /** 269 | * This human readable name is used in the configuration screen. 270 | */ 271 | public String getDisplayName() { 272 | return GlobalPostScriptPlugin.PLUGIN_NAME; 273 | } 274 | 275 | @Override 276 | public boolean configure(StaplerRequest req, JSONObject formData) throws Descriptor.FormException { 277 | script = formData.getString("script"); 278 | runCondition = Result.fromString(formData.getString("runCondition")); 279 | save(); 280 | return super.configure(req, formData); 281 | } 282 | 283 | public String getScript() { 284 | return script; 285 | } 286 | 287 | public Result getResultCondition() { 288 | return runCondition; 289 | } 290 | 291 | public String getRunCondition() { 292 | return runCondition.toString(); 293 | } 294 | } 295 | } 296 | -------------------------------------------------------------------------------- /src/main/java/com/orctom/jenkins/plugin/globalpostscript/GlobalPostScriptAction.java: -------------------------------------------------------------------------------- 1 | package com.orctom.jenkins.plugin.globalpostscript; 2 | 3 | import hudson.PluginWrapper; 4 | import hudson.model.BuildBadgeAction; 5 | import jenkins.model.Jenkins; 6 | 7 | import java.io.File; 8 | 9 | /** 10 | * plugin action class 11 | * Created by CH on 6/29/2014. 12 | */ 13 | public class GlobalPostScriptAction implements BuildBadgeAction { 14 | 15 | private String iconPath; 16 | private String text; 17 | 18 | private GlobalPostScriptAction(String iconPath, String text) { 19 | this.iconPath = iconPath; 20 | this.text = text; 21 | } 22 | 23 | public static GlobalPostScriptAction createBadge(String icon, String text) { 24 | return new GlobalPostScriptAction(getIconPath(icon), text); 25 | } 26 | 27 | public static GlobalPostScriptAction addShortText(String text) { 28 | return new GlobalPostScriptAction(null, text); 29 | } 30 | 31 | private static String getIconPath(String icon) { 32 | if (null == icon) { 33 | return null; 34 | } 35 | 36 | PluginWrapper wrapper = Jenkins.get().getPluginManager().getPlugin(GlobalPostScriptPlugin.class); 37 | boolean pluginIconExists = (wrapper != null) && new File(wrapper.baseResourceURL.getPath() + "/img/" + icon).exists(); 38 | return pluginIconExists ? "/plugin/global-post-script/img/" + icon : Jenkins.RESOURCE_PATH + "/images/16x16/" + icon; 39 | } 40 | 41 | public String getIconFileName() { 42 | return iconPath; 43 | } 44 | 45 | public String getDisplayName() { 46 | return text; 47 | } 48 | 49 | public String getUrlName() { 50 | return null; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/orctom/jenkins/plugin/globalpostscript/GlobalPostScriptPlugin.java: -------------------------------------------------------------------------------- 1 | package com.orctom.jenkins.plugin.globalpostscript; 2 | 3 | import hudson.Plugin; 4 | 5 | /** 6 | * plugin class 7 | * Created by hao on 7/1/2014. 8 | */ 9 | public class GlobalPostScriptPlugin extends Plugin { 10 | 11 | public static final String PLUGIN_NAME = "Global Post Script"; 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/orctom/jenkins/plugin/globalpostscript/ScriptContentLoader.java: -------------------------------------------------------------------------------- 1 | package com.orctom.jenkins.plugin.globalpostscript; 2 | 3 | import com.orctom.jenkins.plugin.globalpostscript.model.ScriptContent; 4 | import hudson.Util; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | import java.util.Map; 9 | 10 | /** 11 | * load script content with cache 12 | * Created by hao on 3/9/16. 13 | */ 14 | public class ScriptContentLoader { 15 | 16 | private static String scriptFileName; 17 | private static long scriptLastModified; 18 | 19 | private static String scriptContent; 20 | 21 | public static ScriptContent getScriptContent(File script, Map variables) throws IOException { 22 | long modified = script.lastModified(); 23 | boolean isChanged = false; 24 | if (!script.getName().equals(scriptFileName) || scriptLastModified < modified) { 25 | scriptFileName = script.getName(); 26 | scriptLastModified = modified; 27 | 28 | scriptContent = Util.loadFile(script); 29 | isChanged = true; 30 | } 31 | return new ScriptContent(scriptContent, isChanged); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/orctom/jenkins/plugin/globalpostscript/ScriptExecutor.java: -------------------------------------------------------------------------------- 1 | package com.orctom.jenkins.plugin.globalpostscript; 2 | 3 | import com.orctom.jenkins.plugin.globalpostscript.runner.GroovyScriptRunner; 4 | import com.orctom.jenkins.plugin.globalpostscript.runner.ShellScriptRunner; 5 | import hudson.model.TaskListener; 6 | import org.codehaus.plexus.util.FileUtils; 7 | 8 | import java.io.File; 9 | import java.util.Map; 10 | 11 | /** 12 | * script executor 13 | * Created by hao on 6/25/2014. 14 | */ 15 | public class ScriptExecutor { 16 | 17 | private TaskListener listener; 18 | private GlobalPostScript.BadgeManager manager; 19 | 20 | public ScriptExecutor(TaskListener listener, GlobalPostScript.BadgeManager manager) { 21 | this.listener = listener; 22 | this.manager = manager; 23 | } 24 | 25 | public void execute(File scriptFile, Map variables) { 26 | println("[INFO]"); 27 | println("[INFO] -----------------------------------------------------"); 28 | println("[INFO] " + GlobalPostScriptPlugin.PLUGIN_NAME); 29 | println("[INFO] -----------------------------------------------------"); 30 | String ext = FileUtils.getExtension(scriptFile.getAbsolutePath()); 31 | if ("groovy".equalsIgnoreCase(ext) || "gvy".equalsIgnoreCase(ext) || "gs".equalsIgnoreCase(ext) || "gsh".equalsIgnoreCase(ext)) { 32 | new GroovyScriptRunner().run(scriptFile, variables, manager, listener); 33 | } else if ("sh".equalsIgnoreCase(ext) || "bat".equalsIgnoreCase(ext)) { 34 | new ShellScriptRunner().run(scriptFile, variables, manager, listener); 35 | } else { 36 | println("[ERROR] Script type not supported: " + ext + " | " + scriptFile.getName()); 37 | } 38 | println("[INFO] -----------------------------------------------------"); 39 | } 40 | 41 | private void println(String message) { 42 | listener.getLogger().println(message); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/orctom/jenkins/plugin/globalpostscript/model/ScriptContent.java: -------------------------------------------------------------------------------- 1 | package com.orctom.jenkins.plugin.globalpostscript.model; 2 | 3 | /** 4 | * script content model 5 | * Created by hao on 3/13/16. 6 | */ 7 | public class ScriptContent { 8 | 9 | private String content; 10 | private boolean isChanged; 11 | 12 | public ScriptContent(String content, boolean isChanged) { 13 | this.content = content; 14 | this.isChanged = isChanged; 15 | } 16 | 17 | public String getContent() { 18 | return content; 19 | } 20 | 21 | public void setContent(String content) { 22 | this.content = content; 23 | } 24 | 25 | public boolean isChanged() { 26 | return isChanged; 27 | } 28 | 29 | public void setChanged(boolean changed) { 30 | this.isChanged = changed; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/orctom/jenkins/plugin/globalpostscript/model/URL.java: -------------------------------------------------------------------------------- 1 | package com.orctom.jenkins.plugin.globalpostscript.model; 2 | 3 | import org.apache.commons.lang.StringUtils; 4 | 5 | import java.util.LinkedHashMap; 6 | import java.util.Map; 7 | import java.util.regex.Matcher; 8 | import java.util.regex.Pattern; 9 | 10 | /** 11 | * url model 12 | * Created by hao on 8/13/2014. 13 | */ 14 | public class URL { 15 | 16 | public static final Pattern PATTERN = Pattern.compile("^(https?://)?((?:[\\w-]+\\.)+[\\w-]*(?::\\d+)?)(/[\\w\\/]*)*(?:\\?(.*))?(?:#([-a-z\\d_]+))?"); 17 | private String protocol; 18 | private String host; 19 | private String uri; 20 | private Map parameters = new LinkedHashMap(); 21 | 22 | public URL(String url) { 23 | Matcher matcher = PATTERN.matcher(url); 24 | String queryString = null; 25 | while (matcher.find()) { 26 | this.protocol = matcher.group(1); 27 | this.host = matcher.group(2); 28 | this.uri = matcher.group(3); 29 | queryString = matcher.group(4); 30 | } 31 | if (StringUtils.isNotEmpty(queryString)) { 32 | String[] params = StringUtils.split(queryString, '&'); 33 | if (params != null) { 34 | for (String param : params) { 35 | String[] entry = StringUtils.split(param, '='); 36 | parameters.put(entry[0], entry[1]); 37 | } 38 | } 39 | } 40 | } 41 | 42 | public String getProtocol() { 43 | return protocol; 44 | } 45 | 46 | public String getHost() { 47 | return host; 48 | } 49 | 50 | public String getUri() { 51 | return uri; 52 | } 53 | 54 | public Map getParams() { 55 | return this.parameters; 56 | } 57 | 58 | public String removeParam(String param) { 59 | return this.parameters.remove(param); 60 | } 61 | 62 | public String getParamValue(String param) { 63 | return this.parameters.get(param); 64 | } 65 | 66 | public void updateParamValue(String param, String value) { 67 | this.parameters.put(param, value); 68 | } 69 | 70 | public void appendToParamValue(String param, String append) { 71 | String oldValue = getParamValue(param); 72 | String newValue = null == oldValue ? append : oldValue + append; 73 | updateParamValue(param, newValue); 74 | } 75 | 76 | public void prependToParamValue(String param, String prepend) { 77 | String oldValue = getParamValue(param); 78 | String newValue = null == oldValue ? prepend : prepend + oldValue; 79 | updateParamValue(param, newValue); 80 | } 81 | 82 | public String getQueryString() { 83 | StringBuilder queryString = new StringBuilder(100); 84 | for (Map.Entry entry : parameters.entrySet()) { 85 | queryString.append(entry.getKey()).append("=").append(entry.getValue()).append("&"); 86 | } 87 | queryString.deleteCharAt(queryString.length() - 1); 88 | return queryString.toString(); 89 | } 90 | 91 | public String getURL() { 92 | return protocol + host + uri + "?" + getQueryString(); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/com/orctom/jenkins/plugin/globalpostscript/runner/GroovyScriptRunner.java: -------------------------------------------------------------------------------- 1 | package com.orctom.jenkins.plugin.globalpostscript.runner; 2 | 3 | import com.orctom.jenkins.plugin.globalpostscript.GlobalPostScript; 4 | import com.orctom.jenkins.plugin.globalpostscript.ScriptContentLoader; 5 | import com.orctom.jenkins.plugin.globalpostscript.model.ScriptContent; 6 | import groovy.lang.GroovyClassLoader; 7 | import groovy.lang.GroovyShell; 8 | import groovy.lang.MissingPropertyException; 9 | import hudson.model.TaskListener; 10 | import jenkins.model.Jenkins; 11 | 12 | import java.io.File; 13 | import java.io.FilenameFilter; 14 | import java.util.Map; 15 | 16 | /** 17 | * groovy script runner 18 | * Created by hao on 3/13/16. 19 | */ 20 | public class GroovyScriptRunner extends ScriptRunner { 21 | 22 | public void run(File scriptFile, 23 | Map variables, 24 | GlobalPostScript.BadgeManager manager, 25 | TaskListener listener) { 26 | GroovyShell shell = new GroovyShell(getGroovyClassloader()); 27 | try { 28 | for (Map.Entry entry : variables.entrySet()) { 29 | shell.setVariable(entry.getKey(), entry.getValue()); 30 | } 31 | shell.setVariable("out", listener.getLogger()); 32 | shell.setVariable("manager", manager); 33 | 34 | ScriptContent sc = ScriptContentLoader.getScriptContent(scriptFile, variables); 35 | shell.parse(sc.getContent()).run(); 36 | } catch (MissingPropertyException e) { 37 | println(listener, "[ERROR] Failed to execute: " + scriptFile.getName() + ", " + e.getMessage()); 38 | } catch (Throwable e) { 39 | e.printStackTrace(); 40 | println(listener, "[ERROR] Failed to execute: " + scriptFile.getName() + ", " + e.getMessage()); 41 | } 42 | } 43 | 44 | protected ClassLoader getGroovyClassloader() { 45 | try { 46 | Jenkins.get(); 47 | } 48 | catch (IllegalStateException e){ 49 | return getParentClassloader(); 50 | } 51 | 52 | File libFolder = new File(Jenkins.get().getRootDir().getAbsolutePath() + GlobalPostScript.SCRIPT_FOLDER, "lib"); 53 | return getGroovyClassloader(libFolder); 54 | } 55 | 56 | private GroovyClassLoader getGroovyClassloaderFromParent() { 57 | GroovyClassLoader cl = new GroovyClassLoader(getParentClassloader()); 58 | return cl; 59 | } 60 | 61 | protected ClassLoader getGroovyClassloader(File libFolder) { 62 | GroovyClassLoader cl = getGroovyClassloaderFromParent(); 63 | if (!libFolder.exists() || !libFolder.isDirectory()) { 64 | return cl; 65 | } 66 | 67 | File[] files = libFolder.listFiles(new JarFilter()); 68 | if (null == files || 0 == files.length) { 69 | return cl; 70 | } 71 | 72 | for (File file : files) { 73 | cl.addClasspath(file.getPath()); 74 | System.out.println("[global-post-script] extra classpath: " + file.getPath()); 75 | } 76 | 77 | return cl; 78 | } 79 | 80 | protected static class JarFilter implements FilenameFilter { 81 | private static final String JAR_FILE_SUFFIX = ".jar"; 82 | 83 | public boolean accept(File dir, String name) { 84 | return name.toLowerCase().endsWith(JAR_FILE_SUFFIX); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/com/orctom/jenkins/plugin/globalpostscript/runner/ScriptRunner.java: -------------------------------------------------------------------------------- 1 | package com.orctom.jenkins.plugin.globalpostscript.runner; 2 | 3 | import com.orctom.jenkins.plugin.globalpostscript.GlobalPostScript; 4 | import hudson.model.TaskListener; 5 | import jenkins.model.Jenkins; 6 | 7 | import java.io.File; 8 | import java.util.Map; 9 | 10 | /** 11 | * script runner interface 12 | * Created by hao on 3/13/16. 13 | */ 14 | public abstract class ScriptRunner { 15 | 16 | public abstract void run(File script, 17 | Map variables, 18 | GlobalPostScript.BadgeManager manager, 19 | TaskListener listener); 20 | 21 | protected void println(TaskListener listener, String message) { 22 | listener.getLogger().println(message); 23 | } 24 | 25 | protected ClassLoader getParentClassloader() { 26 | try { 27 | return Jenkins.get().getPluginManager().uberClassLoader; 28 | } 29 | catch (IllegalStateException e){ 30 | return Thread.currentThread().getContextClassLoader(); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/orctom/jenkins/plugin/globalpostscript/runner/ShellScriptRunner.java: -------------------------------------------------------------------------------- 1 | package com.orctom.jenkins.plugin.globalpostscript.runner; 2 | 3 | import com.orctom.jenkins.plugin.globalpostscript.GlobalPostScript; 4 | import hudson.model.TaskListener; 5 | import org.codehaus.plexus.util.FileUtils; 6 | 7 | import java.io.BufferedReader; 8 | import java.io.File; 9 | import java.io.InputStreamReader; 10 | import java.nio.charset.StandardCharsets; 11 | import java.util.Map; 12 | 13 | import static com.orctom.jenkins.plugin.globalpostscript.ScriptContentLoader.getScriptContent; 14 | 15 | /** 16 | * shell/bash script runner 17 | * Created by hao on 3/13/16. 18 | */ 19 | public class ShellScriptRunner extends ScriptRunner { 20 | 21 | public void run(File script, 22 | Map variables, 23 | GlobalPostScript.BadgeManager manager, 24 | TaskListener listener) { 25 | File temp = null; 26 | try { 27 | String extension = "." + FileUtils.getExtension(script.getPath()); 28 | temp = FileUtils.createTempFile("global-post-script-", extension, null); 29 | FileUtils.fileWrite(temp, getScriptContent(script, variables).getContent()); 30 | String[] commands; 31 | if (".sh".equals(extension)) { 32 | commands = new String[]{getExecutable(script), temp.getAbsolutePath()}; 33 | } else { 34 | commands = new String[]{temp.getAbsolutePath()}; 35 | } 36 | ProcessBuilder builder = new ProcessBuilder(commands); 37 | Map env = builder.environment(); 38 | for (Map.Entry entry : variables.entrySet()) { 39 | env.put(entry.getKey(), entry.getValue()); 40 | } 41 | Process process = builder.start(); 42 | 43 | try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))) { 44 | String line; 45 | while ((line = reader.readLine()) != null) { 46 | println(listener, line); 47 | } 48 | } 49 | 50 | } catch (Throwable e) { 51 | e.printStackTrace(); 52 | println(listener, "[ERROR] Failed to execute: " + script.getName() + ", " + e.getMessage()); 53 | } finally { 54 | if (null != temp) { 55 | if (temp.delete()) { 56 | println(listener, "[WARNING] Failed to delete temp file: " + temp.getName()); 57 | } 58 | } 59 | } 60 | } 61 | 62 | private String getExecutable(File script) { 63 | return FileUtils.getExtension(script.getAbsolutePath()); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/resources/com/orctom/jenkins/plugin/globalpostscript/GlobalPostScript/global.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/main/resources/com/orctom/jenkins/plugin/globalpostscript/GlobalPostScriptAction/badge.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ${it.displayName} 5 | 6 | 7 | ${it.displayName} 8 | 9 | -------------------------------------------------------------------------------- /src/main/resources/index.jelly: -------------------------------------------------------------------------------- 1 | 2 | 5 |
6 | This plugin execute a script configured in global configure after all builds, all jobs.
7 | Caution: jython script supports removed since 1.1.0 8 |
9 | -------------------------------------------------------------------------------- /src/main/webapp/img/calendar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/global-post-script-plugin/6ef4d89279fe1b4c4f19f4622294893ba7f36040/src/main/webapp/img/calendar.png -------------------------------------------------------------------------------- /src/main/webapp/img/cancel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/global-post-script-plugin/6ef4d89279fe1b4c4f19f4622294893ba7f36040/src/main/webapp/img/cancel.png -------------------------------------------------------------------------------- /src/main/webapp/img/check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/global-post-script-plugin/6ef4d89279fe1b4c4f19f4622294893ba7f36040/src/main/webapp/img/check.png -------------------------------------------------------------------------------- /src/main/webapp/img/computer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/global-post-script-plugin/6ef4d89279fe1b4c4f19f4622294893ba7f36040/src/main/webapp/img/computer.png -------------------------------------------------------------------------------- /src/main/webapp/img/danger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/global-post-script-plugin/6ef4d89279fe1b4c4f19f4622294893ba7f36040/src/main/webapp/img/danger.png -------------------------------------------------------------------------------- /src/main/webapp/img/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/global-post-script-plugin/6ef4d89279fe1b4c4f19f4622294893ba7f36040/src/main/webapp/img/error.png -------------------------------------------------------------------------------- /src/main/webapp/img/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/global-post-script-plugin/6ef4d89279fe1b4c4f19f4622294893ba7f36040/src/main/webapp/img/file.png -------------------------------------------------------------------------------- /src/main/webapp/img/good.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/global-post-script-plugin/6ef4d89279fe1b4c4f19f4622294893ba7f36040/src/main/webapp/img/good.png -------------------------------------------------------------------------------- /src/main/webapp/img/green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/global-post-script-plugin/6ef4d89279fe1b4c4f19f4622294893ba7f36040/src/main/webapp/img/green.png -------------------------------------------------------------------------------- /src/main/webapp/img/laptop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/global-post-script-plugin/6ef4d89279fe1b4c4f19f4622294893ba7f36040/src/main/webapp/img/laptop.png -------------------------------------------------------------------------------- /src/main/webapp/img/lock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/global-post-script-plugin/6ef4d89279fe1b4c4f19f4622294893ba7f36040/src/main/webapp/img/lock.png -------------------------------------------------------------------------------- /src/main/webapp/img/orange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/global-post-script-plugin/6ef4d89279fe1b4c4f19f4622294893ba7f36040/src/main/webapp/img/orange.png -------------------------------------------------------------------------------- /src/main/webapp/img/planning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/global-post-script-plugin/6ef4d89279fe1b4c4f19f4622294893ba7f36040/src/main/webapp/img/planning.png -------------------------------------------------------------------------------- /src/main/webapp/img/profit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/global-post-script-plugin/6ef4d89279fe1b4c4f19f4622294893ba7f36040/src/main/webapp/img/profit.png -------------------------------------------------------------------------------- /src/main/webapp/img/prohibited.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/global-post-script-plugin/6ef4d89279fe1b4c4f19f4622294893ba7f36040/src/main/webapp/img/prohibited.png -------------------------------------------------------------------------------- /src/main/webapp/img/red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/global-post-script-plugin/6ef4d89279fe1b4c4f19f4622294893ba7f36040/src/main/webapp/img/red.png -------------------------------------------------------------------------------- /src/main/webapp/img/server.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/global-post-script-plugin/6ef4d89279fe1b4c4f19f4622294893ba7f36040/src/main/webapp/img/server.png -------------------------------------------------------------------------------- /src/main/webapp/img/star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/global-post-script-plugin/6ef4d89279fe1b4c4f19f4622294893ba7f36040/src/main/webapp/img/star.png -------------------------------------------------------------------------------- /src/main/webapp/img/success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/global-post-script-plugin/6ef4d89279fe1b4c4f19f4622294893ba7f36040/src/main/webapp/img/success.png -------------------------------------------------------------------------------- /src/main/webapp/img/warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/global-post-script-plugin/6ef4d89279fe1b4c4f19f4622294893ba7f36040/src/main/webapp/img/warning.png -------------------------------------------------------------------------------- /src/main/webapp/img/yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/global-post-script-plugin/6ef4d89279fe1b4c4f19f4622294893ba7f36040/src/main/webapp/img/yellow.png -------------------------------------------------------------------------------- /src/test/java/com/orctom/jenkins/plugin/globalpostscript/ScriptTest.java: -------------------------------------------------------------------------------- 1 | package com.orctom.jenkins.plugin.globalpostscript; 2 | 3 | import com.orctom.jenkins.plugin.globalpostscript.runner.GroovyScriptRunner; 4 | import hudson.model.TaskListener; 5 | import hudson.util.LogTaskListener; 6 | import org.apache.commons.lang.StringUtils; 7 | import org.junit.Assert; 8 | import org.junit.Before; 9 | import org.junit.Test; 10 | 11 | import java.io.ByteArrayOutputStream; 12 | import java.io.File; 13 | import java.io.PrintStream; 14 | import java.util.HashMap; 15 | import java.util.Map; 16 | import java.util.logging.Level; 17 | import java.util.logging.Logger; 18 | 19 | /** 20 | * script tests 21 | * Created by hao on 6/26/2014. 22 | */ 23 | public class ScriptTest { 24 | 25 | private Map variables = new HashMap(); 26 | 27 | private TaskListener listener = new LogTaskListener(Logger.getLogger(ScriptTest.class.getName()), Level.ALL) { 28 | 29 | private PrintStream logger = new PrintStream(new ByteArrayOutputStream()) { 30 | private StringBuilder logs = new StringBuilder(); 31 | @Override 32 | public void println(String x) { 33 | logs.append(x).append(System.getProperty("line.separator")); 34 | } 35 | 36 | @Override 37 | public void print(String x) { 38 | logs.append(x); 39 | } 40 | 41 | @Override 42 | public String toString() { 43 | return logs.toString(); 44 | } 45 | }; 46 | 47 | @Override 48 | public PrintStream getLogger() { 49 | return logger; 50 | } 51 | }; 52 | 53 | private GlobalPostScript.BadgeManager manager = new GlobalPostScript.BadgeManager(null, null) { 54 | @Override 55 | public void addBadge(String icon, String text) { 56 | System.out.println("addBadge: " + icon + ", " + text); 57 | } 58 | 59 | @Override 60 | public void addShortText(String text) { 61 | System.out.println("addShortText: " + text); 62 | } 63 | 64 | @Override 65 | public void triggerJob(String jobName) { 66 | System.out.println("triggerJob: " + jobName); 67 | } 68 | 69 | @Override 70 | public void triggerRemoteJob(String jobTriggerUrl) { 71 | System.out.println("triggerRemoteJob: " + jobTriggerUrl); 72 | } 73 | 74 | @Override 75 | public String getCause() { 76 | return "dummy cause"; 77 | } 78 | }; 79 | 80 | @Before 81 | public void before() { 82 | variables.put("dropdeploy_targets", "server1"); 83 | } 84 | 85 | @Test 86 | public void testExecuteGroovy() { 87 | File script = new File(ClassLoader.getSystemResource("test.groovy").getPath()); 88 | System.out.println("script: " + script); 89 | String expected = "dropdeploy to: server1"; 90 | new GroovyScriptRunner().run(script, variables, manager, listener); 91 | String actual = StringUtils.trim(listener.getLogger().toString()); 92 | System.out.println("expected: " + expected); 93 | System.out.println("actual : " + actual); 94 | Assert.assertEquals(expected, actual); 95 | } 96 | 97 | @Test 98 | public void testExecuteGroovy2() { 99 | File script = new File(ClassLoader.getSystemResource("test2.groovy").getPath()); 100 | System.out.println("script: " + script); 101 | String expected = "dropdeploy to: server1"; 102 | new GroovyScriptRunner().run(script, variables, manager, listener); 103 | String actual = StringUtils.trim(listener.getLogger().toString()); 104 | System.out.println("expected: " + expected); 105 | System.out.println("actual : " + actual); 106 | Assert.assertEquals(expected, actual); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/test/java/com/orctom/jenkins/plugin/globalpostscript/URLTest.java: -------------------------------------------------------------------------------- 1 | package com.orctom.jenkins.plugin.globalpostscript; 2 | 3 | import com.orctom.jenkins.plugin.globalpostscript.model.URL; 4 | import org.junit.Assert; 5 | import org.junit.Test; 6 | 7 | /** 8 | * url tests 9 | * Created by hao on 8/13/2014. 10 | */ 11 | public class URLTest { 12 | 13 | @Test 14 | public void testPattern() { 15 | Assert.assertTrue(URL.PATTERN.matcher("http://www.google.com").matches()); 16 | Assert.assertTrue(URL.PATTERN.matcher("http://www.google.com:100/abc?hello").matches()); 17 | Assert.assertTrue(URL.PATTERN.matcher("https://google.com/a?a=b&b=a+b+c").matches()); 18 | Assert.assertTrue(URL.PATTERN.matcher("http://10.20.13.15/hello/abc?a=b&b=a+b+c").matches()); 19 | Assert.assertTrue(URL.PATTERN.matcher("https://10.20.13.15/hello/abc?a=b&b=a+b+c").matches()); 20 | 21 | Assert.assertFalse(URL.PATTERN.matcher("http:/www.google.com").matches()); 22 | Assert.assertFalse(URL.PATTERN.matcher("//www.google.com:80/h").matches()); 23 | Assert.assertFalse(URL.PATTERN.matcher("http:/www.google.com").matches()); 24 | Assert.assertTrue(URL.PATTERN.matcher("http://10.20.13/").matches()); 25 | Assert.assertTrue(URL.PATTERN.matcher("http://ecopsci.uschecomrnd.net/buildByToken/build?job=sync_ag2content_to_dev&token=8a36b668396e7aed7b4576f90bbbdc37").matches()); 26 | } 27 | 28 | @Test 29 | public void testAppendToParamValue() { 30 | String jobUrl = "http://ecopsci.uschecomrnd.net/buildByToken/build?job=sync_ag2content_to_dev&token=8a36b668396e7aed7b4576f90bbbdc37"; 31 | URL url = new URL(jobUrl); 32 | Assert.assertEquals(jobUrl, url.getURL()); 33 | Assert.assertEquals("ecopsci.uschecomrnd.net", url.getHost()); 34 | Assert.assertEquals("http://", url.getProtocol()); 35 | Assert.assertEquals("/buildByToken/build", url.getUri()); 36 | Assert.assertEquals("job=sync_ag2content_to_dev&token=8a36b668396e7aed7b4576f90bbbdc37", url.getQueryString()); 37 | url.appendToParamValue("job", "_appendix"); 38 | Assert.assertEquals("job=sync_ag2content_to_dev_appendix&token=8a36b668396e7aed7b4576f90bbbdc37", url.getQueryString()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/resources/downstream_job_trigger.groovy: -------------------------------------------------------------------------------- 1 | def triggers = [ 2 | wwwsqs8 : { 3 | manager.triggerJob("WWW_JBEHAVE_TEST") 4 | manager.triggerJob("WWW_MOBILE_API_TEST") 5 | manager.triggerRemoteJob("http://10.94.0.137:8006/job/Dev_Launch_WWW_SQS_REGRESSION/build?token=88e4b5fd1d28949710a9c4924775ce40&delay=1800sec") 6 | }, 7 | wwwsqm8 : { 8 | manager.triggerRemoteJob("http://10.94.0.137:8006/job/Dev_Launch_WWW_SQM_REGRESSION/build?token=88e4b5fd1d28949710a9c4924775ce40&delay=1800sec") 9 | }, 10 | wwwsqp8 : { 11 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/job/wwwsqp_deploy/build?token=wwwsqp_deploy") 12 | }, 13 | bsdsqs8 : { 14 | manager.triggerJob("BSD_JBEHAVE_TEST") 15 | manager.triggerJob("BSD_MOBILE_API_TEST") 16 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/job/BSD_DEPLOY/buildWithParameters?token=BSD_DEPLOY&target=bsdsqs8") 17 | manager.triggerRemoteJob("http://10.94.0.137:8006/job/Dev_Launch_BSD_SQS_REGRESSION/build?token=88e4b5fd1d28949710a9c4924775ce40&delay=1800sec") 18 | }, 19 | bsdsqm8 : { 20 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/job/BSD_DEPLOY/buildWithParameters?token=BSD_DEPLOY&target=bsdsqm8") 21 | manager.triggerRemoteJob("http://10.94.0.137:8006/job/Dev_Launch_BSD_SQM_REGRESSION/build?token=88e4b5fd1d28949710a9c4924775ce40&delay=1800sec") 22 | }, 23 | bsdsqd8 : { 24 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/job/BSD_DEPLOY/buildWithParameters?token=BSD_DEPLOY&target=bsdsqd") 25 | }, 26 | bsdsqe8 : { 27 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/job/BSD_DEPLOY/buildWithParameters?token=BSD_DEPLOY&target=bsdsqe8") 28 | }, 29 | bsdsqf8 : { 30 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/job/BSD_DEPLOY/buildWithParameters?token=BSD_DEPLOY&target=bsdsqf8") 31 | }, 32 | bsdsqp8 : { 33 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/job/BSD_DEPLOY/buildWithParameters?token=BSD_DEPLOY&target=bsdsqp8") 34 | }, 35 | bsdperf8 : { 36 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/job/BSD_DEPLOY/buildWithParameters?token=BSD_DEPLOY&target=bsdperf8") 37 | }, 38 | bsdprfp8 : { 39 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/job/BSD_DEPLOY/buildWithParameters?token=BSD_DEPLOY&target=bsdprfp") 40 | }, 41 | bsd1sqs8 : { 42 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/job/BSD_DEPLOY/buildWithParameters?token=BSD_DEPLOY&target=bsd1sqs8") 43 | }, 44 | bsd1sqm8 : { 45 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/job/BSD_DEPLOY/buildWithParameters?token=BSD_DEPLOY&target=bsd1sqm8") 46 | }, 47 | bsd1sqp8 : { 48 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/job/BSD_DEPLOY/buildWithParameters?token=BSD_DEPLOY&target=bsd1sqp8") 49 | }, 50 | gmlsqs8 : { 51 | manager.triggerJob("GMIL_JBEHAVE_TEST") 52 | manager.triggerRemoteJob("http://10.94.0.137:8006/job/Dev_Launch_GMIL_SQS_REGRESSION/build?token=88e4b5fd1d28949710a9c4924775ce40&delay=1800sec") 53 | }, 54 | gmlsqm8 : { 55 | manager.triggerRemoteJob("http://10.94.0.137:8006/job/Dev_Launch_GMIL_SQM_REGRESSION/build?token=88e4b5fd1d28949710a9c4924775ce40&delay=1800sec") 56 | }, 57 | odensqs8 : { 58 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/job/odnsqs_deploy/build?token=odnsqs_deploy") 59 | }, 60 | odensqm8 : { 61 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/job/odnsqm_deploy/build?token=odnsqm_deploy") 62 | }, 63 | odensqp8 : { 64 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/job/odnsqp_deploy/build?token=odnsqp_deploy") 65 | }, 66 | cpdperf : { 67 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/job/CPD_DEPLOY/buildWithParameters?token=CPD_DEPLOY&target=cpdperf") 68 | }, 69 | cpdpoc : { 70 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/job/CPD_DEPLOY/buildWithParameters?token=CPD_DEPLOY&target=cpdpoc") 71 | }, 72 | cpdprf_service : { 73 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/job/CPD_DEPLOY/buildWithParameters?token=CPD_DEPLOY&target=cpdprf-service") 74 | }, 75 | cpdsqs_configurator_www: { 76 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/job/CPD_DEPLOY/buildWithParameters?token=CPD_DEPLOY&target=cpdsqs-configurator-www") 77 | }, 78 | cpdsqs_configurator_bsd: { 79 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/job/CPD_DEPLOY/buildWithParameters?token=CPD_DEPLOY&target=cpdsqs-configurator-bsd") 80 | }, 81 | cpdsqs_service : { 82 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/job/CPD_DEPLOY/buildWithParameters?token=CPD_DEPLOY&target=cpdsqs-service") 83 | }, 84 | cpdsqm : { 85 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/job/CPD_DEPLOY/buildWithParameters?token=CPD_DEPLOY&target=cpdsqm") 86 | }, 87 | cpdsqm_configurator : { 88 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/job/CPD_DEPLOY/buildWithParameters?token=CPD_DEPLOY&target=cpdsqm-configurator") 89 | }, 90 | cpdsqm_configurator_bsd: { 91 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/job/CPD_DEPLOY/buildWithParameters?token=CPD_DEPLOY&target=cpdsqm-configurator-bsd") 92 | }, 93 | cpdsqm_service : { 94 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/job/CPD_DEPLOY/buildWithParameters?token=CPD_DEPLOY&target=cpdsqm-service") 95 | }, 96 | cpdsqp_configurator_www: { 97 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/job/CPD_DEPLOY/buildWithParameters?token=CPD_DEPLOY&target=cpdsqp-configurator-www") 98 | }, 99 | cpdsqp_configurator_bsd: { 100 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/job/CPD_DEPLOY/buildWithParameters?token=CPD_DEPLOY&target=cpdsqp-configurator-bsd") 101 | }, 102 | cpdsqp_service : { 103 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/job/CPD_DEPLOY/buildWithParameters?token=CPD_DEPLOY&target=cpdsqp-service") 104 | }, 105 | configurator_www_dev : { 106 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/buildByToken/buildWithParameters?token=8a36b668396e7aed7b4576f90bbbdc37&job=sync_ag2content_to_dev&targets=chvwwwdevcmb01,chvwwwdevcmb02") 107 | }, 108 | configurator_bsd_dev : { 109 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/buildByToken/buildWithParameters?token=8a36b668396e7aed7b4576f90bbbdc37&job=sync_ag2content_to_dev&targets=chvbsddevcmb01,chvbsddevcmb02") 110 | }, 111 | admdev : { 112 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/buildByToken/buildWithParameters?token=8a36b668396e7aed7b4576f90bbbdc37&job=sync_adam_build_to_s3&targets=admdev") 113 | Thread.sleep(60000) 114 | manager.triggerRemoteJob("http://awsecopsci.uschecomrnd.net/buildByToken/build?token=45ca521be27644a6d4b6f3eae4486e5a&job=deploy_adam_dev") 115 | }, 116 | admsqs : { 117 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/buildByToken/buildWithParameters?token=8a36b668396e7aed7b4576f90bbbdc37&job=sync_adam_build_to_s3&targets=admsqs") 118 | Thread.sleep(60000) 119 | manager.triggerRemoteJob("http://awsecopsci.uschecomrnd.net/buildByToken/build?token=45ca521be27644a6d4b6f3eae4486e5a&job=deploy_adam_sqs") 120 | }, 121 | admsqm : { 122 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/buildByToken/buildWithParameters?token=8a36b668396e7aed7b4576f90bbbdc37&job=sync_adam_build_to_s3&targets=admsqm") 123 | Thread.sleep(60000) 124 | manager.triggerRemoteJob("http://awsecopsci.uschecomrnd.net/buildByToken/build?token=45ca521be27644a6d4b6f3eae4486e5a&job=deploy_adam_sqm") 125 | }, 126 | admsqp : { 127 | manager.triggerRemoteJob("http://ecopsci.uschecomrnd.net/buildByToken/buildWithParameters?token=8a36b668396e7aed7b4576f90bbbdc37&job=sync_adam_build_to_s3&targets=admsqp") 128 | Thread.sleep(60000) 129 | manager.triggerRemoteJob("http://awsecopsci.uschecomrnd.net/buildByToken/build?token=45ca521be27644a6d4b6f3eae4486e5a&job=deploy_adam_sqp") 130 | } 131 | ] 132 | 133 | 134 | if (binding.variables.containsKey("deploy") && binding.variables.containsKey("deploy_targets") && 135 | "true" == deploy && deploy_targets?.trim()) { 136 | manager.addBadge("computer.png", "[DEV: " + deploy_targets + "]") 137 | deploy_targets.split(',').each { 138 | String entry = it; 139 | trigger = triggers[entry.replaceAll(/\W/, "_")] 140 | if (trigger) { 141 | trigger() 142 | } 143 | } 144 | } 145 | if (binding.variables.containsKey("dropdeploy") && binding.variables.containsKey("dropdeploy_targets") && 146 | "true" == dropdeploy && dropdeploy_targets?.trim()) { 147 | dropped = false 148 | dropdeploy_targets.split(',').each { 149 | dropped = true 150 | String entry = it; 151 | trigger = triggers[entry.replaceAll(/\W/, "_")] 152 | if (trigger) { 153 | trigger() 154 | } 155 | } 156 | if (dropped) { 157 | manager.addBadge("server.png", "[SQ: " + dropdeploy_targets + "]") 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /src/test/resources/test.groovy: -------------------------------------------------------------------------------- 1 | out.println("dropdeploy to: $dropdeploy_targets") -------------------------------------------------------------------------------- /src/test/resources/test.py: -------------------------------------------------------------------------------- 1 | print 'dropdeploy to: ' + dropdeploy_targets + ", " + manager.getCause() -------------------------------------------------------------------------------- /src/test/resources/test2.groovy: -------------------------------------------------------------------------------- 1 | out.println("dropdeploy to: " + dropdeploy_targets) -------------------------------------------------------------------------------- /src/test/resources/test2.py: -------------------------------------------------------------------------------- 1 | str = 'dropdeploy to: ' 2 | if 'dropdeploy_targets' in locals(): 3 | str += dropdeploy_targets 4 | if 'manager' in locals(): 5 | str += ", " + manager.getCause() 6 | print str --------------------------------------------------------------------------------