├── .github ├── CODEOWNERS ├── dependabot.yml ├── release-drafter.yml └── workflows │ ├── changelog.yml │ └── jenkins-security-scan.yml ├── .gitignore ├── .gitpod.yml ├── .mvn ├── extensions.xml └── maven.config ├── CHANGELOG.adoc ├── CONTRIBUTING.md ├── Jenkinsfile ├── README.adoc ├── docs └── images │ ├── screen-capture-1.jpg │ └── screen-capture-2.jpg ├── pom.xml └── src ├── main ├── java │ └── org │ │ └── jenkinsci │ │ └── plugins │ │ └── conditionalbuildstep │ │ ├── BuilderChain.java │ │ ├── ConditionalBuildStepHelper.java │ │ ├── ConditionalBuilder.java │ │ ├── LegacyBuildstepCondition.java │ │ ├── dependency │ │ ├── ConditionalDependencyGraphWrapper.java │ │ └── ConditionalDependencyWrapper.java │ │ ├── lister │ │ ├── BuilderDescriptorLister.java │ │ └── DefaultBuilderDescriptorLister.java │ │ └── singlestep │ │ ├── JobUpdater.java │ │ └── SingleConditionalBuilder.java └── resources │ ├── index.jelly │ ├── lib │ └── conditionalbuildstep │ │ └── taglib │ └── org │ └── jenkinsci │ └── plugins │ └── conditionalbuildstep │ ├── ConditionalBuilder │ ├── config.jelly │ ├── config.properties │ ├── help-runCondition.jelly │ └── help-runner.html │ ├── LegacyBuildstepCondition │ ├── config.jelly │ └── help.jelly │ ├── Messages.properties │ ├── lister │ └── DefaultBuilderDescriptorLister │ │ └── config.jelly │ └── singlestep │ └── SingleConditionalBuilder │ ├── config.jelly │ ├── config.properties │ ├── global.jelly │ ├── global.properties │ ├── help-condition.jelly │ ├── help-runner.html │ └── help.html ├── spotbugs └── spotbugs-excludes.xml └── test ├── java └── org │ └── jenkinsci │ └── plugins │ └── conditionalbuildstep │ └── ConfigFileBuildWrapperTest.java └── resources └── config.xml /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @jenkinsci/conditional-buildstep-plugin-developers 2 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuring-dependabot-version-updates 2 | 3 | version: 2 4 | updates: 5 | - package-ecosystem: maven 6 | directory: / 7 | schedule: 8 | interval: monthly 9 | - package-ecosystem: github-actions 10 | directory: / 11 | schedule: 12 | interval: monthly 13 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | _extends: .github 2 | version-template: $MAJOR.$MINOR.$PATCH 3 | tag-template: $NEXT_MINOR_VERSION 4 | -------------------------------------------------------------------------------- /.github/workflows/changelog.yml: -------------------------------------------------------------------------------- 1 | # Automates creation of changelog drafts using Release Drafter 2 | # More Info: https://github.com/jenkinsci/.github/blob/master/.github/release-drafter.adoc 3 | name: Changelog Drafter 4 | 5 | on: 6 | push: 7 | # branches to consider in the event; optional, defaults to all 8 | branches: 9 | - master 10 | 11 | jobs: 12 | update_draft_release: 13 | runs-on: ubuntu-latest 14 | steps: 15 | # Drafts your next Release notes as Pull Requests are merged into "master" 16 | - name: Generate GitHub Release Draft 17 | id: release-drafter 18 | uses: release-drafter/release-drafter@v6.1.0 19 | env: 20 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 21 | -------------------------------------------------------------------------------- /.github/workflows/jenkins-security-scan.yml: -------------------------------------------------------------------------------- 1 | name: Jenkins Security Scan 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | types: [ opened, synchronize, reopened ] 9 | workflow_dispatch: 10 | 11 | permissions: 12 | security-events: write 13 | contents: read 14 | actions: read 15 | 16 | jobs: 17 | security-scan: 18 | uses: jenkins-infra/jenkins-security-scan/.github/workflows/jenkins-security-scan.yaml@v2 19 | with: 20 | java-cache: 'maven' # Optionally enable use of a build dependency cache. Specify 'maven' or 'gradle' as appropriate. 21 | # java-version: 21 # Optionally specify what version of Java to set up for the build, or remove to use a recent default. 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | work 2 | .idea/ 3 | *.iml 4 | target/ 5 | *~ 6 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | tasks: 2 | - init: mvn clean verify 3 | 4 | vscode: 5 | extensions: 6 | - bierner.markdown-preview-github-styles 7 | - vscjava.vscode-java-pack 8 | - redhat.java 9 | - vscjava.vscode-java-debug 10 | - vscjava.vscode-java-dependency 11 | - vscjava.vscode-java-test 12 | - vscjava.vscode-maven 13 | -------------------------------------------------------------------------------- /.mvn/extensions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | io.jenkins.tools.incrementals 4 | git-changelist-maven-extension 5 | 1.8 6 | 7 | 8 | -------------------------------------------------------------------------------- /.mvn/maven.config: -------------------------------------------------------------------------------- 1 | -Pconsume-incrementals 2 | -Pmight-produce-incrementals 3 | -------------------------------------------------------------------------------- /CHANGELOG.adoc: -------------------------------------------------------------------------------- 1 | = Version History 2 | 3 | == 1.3.6 (9 June 2017) 4 | 5 | * Integrate https://issues.jenkins.io/browse/JENKINS-43887[JENKINS-43887] 6 | upgrade parent pom to 2.x (thanks varyvol 7 | https://github.com/jenkinsci/conditional-buildstep-plugin/pull/14[#14]) 8 | * ConditionalBuilder now implements DependencyDeclarer (thanks 9 | TWestling https://github.com/jenkinsci/conditional-buildstep-plugin/pull/12[#12]) 10 | 11 | == 1.3.5 (16 June 2016) 12 | 13 | * Fix 14 | https://issues.jenkins.io/browse/JENKINS-35526[JENKINS-35526], update 15 | to DependencyDeclarer 16 | (https://github.com/jenkinsci/conditional-buildstep-plugin/pull/10[PR#10] 17 | thanks fbelzunc) 18 | * Fix https://issues.jenkins.io/browse/JENKINS-34971[JENKINS-34971] describe 19 | advanced options about failing the evaluation of a condition 20 | 21 | == 1.3.3 (13 November 2013) 22 | 23 | * Fix https://issues.jenkins.io/browse/JENKINS-20543[JENKINS-20543] 24 | fix "NoSuchMethodError: 25 | org.jenkinsci.plugins.conditionalbuildstep.ConditionalBuildStepHelper.getContainedBuilders()" 26 | 27 | == 1.3.2 (10 November 2013) 28 | 29 | * Add helper (ConditionalBuildStepHelper) to support working with 30 | wrapped build steps to support 31 | https://issues.jenkins.io/browse/JENKINS-18967[JENKINS-18967] 32 | * Enhance ConditionalBuildStepHelper to also return pre- and post 33 | builders from a maven project 34 | 35 | == 1.3 (16 July 2013) 36 | 37 | * Fix https://issues.jenkins.io/browse/JENKINS-18135[JENKINS-18135] 38 | fix compatibility issues 39 | with https://plugins.jenkins.io/any-buildstep/[Any Build Step Plugin] 40 | * Lift dependency to core LTS 1.480.3 41 | 42 | == 1.2.2 (2 June 2013) 43 | 44 | * Fix https://issues.jenkins.io/browse/JENKINS-17836[JENKINS-17836] 45 | exception if there is no builder defined within the conditional build 46 | step 47 | 48 | == 1.2.1 (1 November 2012) 49 | 50 | * Fix https://issues.jenkins.io/browse/JENKINS-13871[JENKINS-13871] 51 | Using "Conditional build step" and "Parameterized build step" in same 52 | step is preventing parallel executions of same job 53 | 54 | == 1.2 (11 October 2012) 55 | 56 | * Fix https://issues.jenkins.io/browse/JENKINS-14118[JENKINS-14118] 57 | show builds triggered through Conditional build step plugin reported as 58 | downstream builds for the current build. 59 | 60 | == 1.1 (6 May 2012) 61 | 62 | * Fix https://issues.jenkins.io/browse/JENKINS-13618[JENKINS-13618] 63 | Unable to use multiple Conditional Steps in the Prebuild section of 64 | Multi configuration job 65 | 66 | == 1.0 (31 March 2012) 67 | 68 | * Fix https://issues.jenkins.io/browse/JENKINS-13112[JENKINS-13112] 69 | Adding any post-build step as a build step causes exception (caused in 70 | combination with the https://plugins.jenkins.io/any-buildstep/[Any Build Step Plugin] 71 | 72 | == 0.0.3 (31 December 2011) 73 | 74 | * Fix https://issues.jenkins.io/browse/JENKINS-12036[JENKINS-12036] conditional build steps plugin does not support matrix build 75 | 76 | == 0.0.2 (14 November 2011) 77 | 78 | * Integrate https://plugins.jenkins.io/run-condition/[Run Condition Plugin] 79 | to ease condition extensions, which also fixes https://issues.jenkins.io/browse/JENKINS-11671[JENKINS-11671] 80 | 81 | == 0.0.1 82 | 83 | * Initial 84 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to the Conditional Build Step Plugin 2 | 3 | ## Beginner Topics 4 | 5 | Look for contribution areas in the 6 | [issues in our issues tracker](https://issues.jenkins.io/issues/?jql=resolution%20is%20EMPTY%20and%20component%3D15947). 7 | 8 | ## Background 9 | 10 | Plugin source code is hosted on https://github.com/jenkinsci/conditional-buildstep-plugin[GitHub]. 11 | New feature proposals and bug fix proposals should be submitted as https://help.github.com/articles/creating-a-pull-request[GitHub pull requests]. 12 | Your pull request will be evaluated by the https://ci.jenkins.io/job/Plugins/job/conditional-buildstep-plugin/[Jenkins job]. 13 | 14 | Before submitting your change, please assure that you've added tests to verify your change. 15 | Tests help us assure that we're delivering a reliable plugin, and that we've communicated our intent to other developers as executable descriptions of plugin behavior. 16 | 17 | ## Building and Testing 18 | 19 | Compile and test the plugin with the command: 20 | 21 | * `mvn clean verify` 22 | 23 | Compile the plugin without running tests using the command: 24 | 25 | * `mvn clean -DskipTests verify` 26 | 27 | Code coverage reporting is available as a maven target. 28 | Please try to improve code coverage with tests when you submit. 29 | 30 | * `mvn -P enable-jacoco clean install jacoco:report` to report code coverage 31 | 32 | Please don't introduce new spotbugs output. 33 | 34 | * `mvn spotbugs:check` to analyze project using https://spotbugs.github.io/[Spotbugs]. 35 | * `mvn spotbugs:gui` to review Spotbugs report using GUI 36 | 37 | ## Automated Tests 38 | 39 | Automated tests are run as part of the `verify` phase. 40 | Run automated tests with multiple Java virtual machines with the command: 41 | 42 | ``` 43 | $ mvn clean -DforkCount=1C verify 44 | ``` 45 | 46 | ## Issue Reports 47 | 48 | Please report issues and enhancements through the [Jenkins issue tracker](https://www.jenkins.io/participate/report-issue/redirect/#15947). 49 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | /* 2 | See the documentation for more options: 3 | https://github.com/jenkins-infra/pipeline-library/ 4 | */ 5 | buildPlugin( 6 | useContainerAgent: true, // Set to `false` if you need to use Docker for containerized tests 7 | configurations: [ 8 | [platform: 'linux', jdk: 21], 9 | [platform: 'windows', jdk: 17], 10 | ]) 11 | -------------------------------------------------------------------------------- /README.adoc: -------------------------------------------------------------------------------- 1 | = Conditional Build Step Plugin for Jenkins 2 | 3 | image:https://img.shields.io/jenkins/plugin/v/conditional-buildstep.svg[link="https://plugins.jenkins.io/conditional-buildstep"] 4 | image:https://img.shields.io/github/release/jenkinsci/conditional-buildstep-plugin.svg?label=changelog[link="https://github.com/jenkinsci/conditional-buildstep-plugin/releases/latest"] 5 | image:https://img.shields.io/jenkins/plugin/i/conditional-buildstep.svg?color=blue[link="https://plugins.jenkins.io/conditional-buildstep"] 6 | 7 | A buildstep wrapping any number of other buildsteps, controlling their execution based on a defined condition. 8 | 9 | == Info 10 | 11 | This plugin requires the 12 | https://plugins.jenkins.io/token-macro/[TokenMacro Plugin] and the  13 | https://plugins.jenkins.io/run-condition/[Run Condition Plugin] to be installed! 14 | 15 | * Ever wanted to have more control whether a step should be executed or not? 16 | * Want to reduce the number of jobs doing nearly the same thing? 17 | 18 | Add a conditional buildstep which acts as a container. 19 | It will allow you to define a condition controling the execution of the step(s). 20 | 21 | == Conditions 22 | 23 | There are multiple conditions one can choose of, these are all defined by the 24 | https://plugins.jenkins.io/run-condition/[Run Condition Plugin] 25 | 26 | Missing builder 27 | 28 | If you're not able to add the builder of your choice within a 29 | conditional build step (because it's not available within the dropdown), 30 | then this is likely because the builder does not provide a 31 | `@DataBoundConstructor` constructor and/or the Descriptor does not 32 | extend `hudson.tasks.BuildStepDescriptor`. 33 | For non programmers: the plugin you would like to use does not yet follow the newest Jenkins coding guidelines. 34 | Without this, the conditional buildstep plugin is not able to work with it. 35 | 36 | == Conditional step (single) 37 | 38 | // TODO: Move https://wiki.jenkins-ci.org/pages/viewpage.action?pageId=59507542 to the documentation 39 | 40 | This build step allows you to select any build step and define a 41 | condition to control whether the step should be executed. 42 | 43 | === Freedom to re-order 44 | 45 | As there is only one build step within the builder, they can all be re-ordered independantly - in the multiple step, they can only be re-ordered within that step. 46 | This also gives the ability to add build steps in the middle of the current list of steps, where the new step may run on every build, or use a different condition from the steps surrounding it. 47 | Obviously, the Conditional step (multiple) itself can be moved around. 48 | 49 | === Move a step from one condition to another 50 | 51 | If you have several steps that are controlled by two conditions (via EnvInject), then you can easily swith the boolean condition for a single step to use the other condition. 52 | With the multiple, all contained steps use the same condition, so again the step would have to be deleted and then added to the other conditional step. 53 | 54 | === Multiple steps can still be controlled by a single condition (EnvInject) 55 | 56 | You can still run multiple build steps based on the result of a single evaluation of a run condition. 57 | Configure a run condition and in the action choose 'Inject environment variables' provied by the EnvInject Plugin. 58 | In the 'Properties Content' set a variable that will evaluate to true by the Boolean run condition e.g. `CONDITION_X=y`. 59 | Now, for all the build steps that you want to run depending on that condition, use the Boolean run condition with `${ENV,var="CONDITION_X"}`. 60 | 61 | === Multiple steps can still be controlled by a single condition (EnvInject) 62 | 63 | This still requires extra configuration, and even an extra build step. 64 | 65 | === GUI space 66 | 67 | Many Conditional step (single) build steps will take up a very large area of the configure page which can make the configuration more difficult to read. 68 | 69 | image:docs/images/screen-capture-1.jpg[image] 70 | 71 | == Conditional steps (multiple) 72 | 73 | A _Conditional steps (multiple)_ container is able to contain any number 74 | of any other buildsteps (e.g. Shell, Ant, Maven,...) and you can have 75 | any number of 'Conditional Steps' containers, each configured with a 76 | different condition. 77 | 78 | image:docs/images/screen-capture-2.jpg[image] 79 | 80 | == Examples 81 | 82 | Please check out the examples at the https://plugins.jenkins.io/run-condition/[Run Condition Plugin] 83 | 84 | == Move steps inside conditional steps 85 | 86 | To move all of the current build steps within a freestyle project into a conditional step (single) you can call a utility method from the script console. 87 | The project build will not be affected in any way (other than some extra text in the build console), as the order of the build steps is preserved, and all of the run conditions will be 'Always'. 88 | Build steps that cannot be moved into a conditional step will not be moved. 89 | 90 | From Manage Jenkins, Script console, enter the following to update a project called 'My Project' 91 | 92 | [source,groovy] 93 | ---- 94 | import static org.jenkinsci.plugins.conditionalbuildstep.singlestep.JobUpdater.* 95 | 96 | def job = hudson.model.Hudson.instance.getItem('My Project') 97 | updateBuilders job 98 | ---- 99 | 100 | After running, go to the configure page, check everything looks ok, then save the configuration. 101 | 102 | You can now easily enable and disable the build steps without losing the configuration. 103 | 104 | == Changelog 105 | 106 | * For recent versions, see https://github.com/jenkinsci/conditional-buildstep-plugin/releases[GitHub Releases] 107 | * For versions 1.3.6 and older, see the link:https://github.com/jenkinsci/conditional-buildstep-plugin/blob/master/CHANGELOG.adoc[legacy CHANGELOG]. 108 | 109 | == Reporting issues 110 | 111 | Please report issues and enhancements through the link:Please report issues and enhancements through the [Jenkins issue tracker](https://www.jenkins.io/participate/report-issue/redirect/#15947)[Jenkins issue tracker]. 112 | 113 | == Getting Help 114 | 115 | For help please use the https://community.jenkins.io[community forum], https://www.jenkins.io/mailing-lists/[Jenkins users mailing list], or link:https://www.jenkins.io/chat/[chat channels]. 116 | 117 | == License 118 | 119 | // TODO: Add License File to the repo 120 | Licensed under the https://opensource.org/licenses/MIT[MIT Licence]. 121 | -------------------------------------------------------------------------------- /docs/images/screen-capture-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/conditional-buildstep-plugin/26be9760f055820584548d0a82f2df787e1242be/docs/images/screen-capture-1.jpg -------------------------------------------------------------------------------- /docs/images/screen-capture-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/conditional-buildstep-plugin/26be9760f055820584548d0a82f2df787e1242be/docs/images/screen-capture-2.jpg -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | 6 | 7 | org.jenkins-ci.plugins 8 | plugin 9 | 5.17 10 | 11 | 12 | 13 | conditional-buildstep 14 | ${revision}${changelist} 15 | 16 | hpi 17 | 18 | Conditional BuildStep 19 | A buildstep wrapping any number of other buildsteps, controlling their execution based on a defined condition. 20 | https://plugins.jenkins.io/conditional-buildstep/ 21 | 22 | scm:git:https://github.com/${gitHubRepo}.git 23 | scm:git:git@github.com:${gitHubRepo}.git 24 | https://github.com/${gitHubRepo} 25 | ${scmTag} 26 | 27 | 28 | 1.5.1 29 | -SNAPSHOT 30 | jenkinsci/conditional-buildstep-plugin 31 | Max 32 | Low 33 | ${project.basedir}/src/spotbugs/spotbugs-excludes.xml 34 | 35 | 2.479 36 | ${jenkins.baseline}.3 37 | 38 | 39 | 40 | The MIT license 41 | All source code is under the MIT license. 42 | 43 | 44 | 45 | 46 | imod 47 | Dominik Bartholdi 48 | 49 | 50 | 51 | bap 52 | Bap 53 | bap-jenkins@BapIT.co.uk 54 | 55 | 56 | 57 | JIRA 58 | https://issues.jenkins.io/ 59 | 60 | 61 | 62 | org.jenkins-ci.plugins 63 | token-macro 64 | 65 | 66 | org.jenkins-ci.plugins 67 | run-condition 68 | 69 | 70 | org.jenkins-ci.main 71 | maven-plugin 72 | true 73 | 74 | 75 | org.jenkins-ci.plugins 76 | mailer 77 | test 78 | 79 | 80 | 81 | 82 | 83 | repo.jenkins-ci.org 84 | https://repo.jenkins-ci.org/public/ 85 | 86 | 87 | 88 | 89 | 90 | repo.jenkins-ci.org 91 | https://repo.jenkins-ci.org/public/ 92 | 93 | 94 | 95 | 96 | 97 | 98 | io.jenkins.tools.bom 99 | bom-${jenkins.baseline}.x 100 | 4862.vc32a_71c3e731 101 | import 102 | pom 103 | 104 | 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/conditionalbuildstep/BuilderChain.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (C) 2011 by Dominik Bartholdi 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package org.jenkinsci.plugins.conditionalbuildstep; 25 | 26 | import hudson.Extension; 27 | import hudson.Launcher; 28 | import hudson.model.BuildListener; 29 | import hudson.model.AbstractBuild; 30 | import hudson.model.AbstractProject; 31 | import hudson.tasks.BuildStep; 32 | import hudson.tasks.BuildStepDescriptor; 33 | import hudson.tasks.Builder; 34 | 35 | import java.io.IOException; 36 | import java.util.List; 37 | 38 | /** 39 | * A builder not directly configurable via UI, instances are only created for transitive usage to wrap the execution of multiple builders. 40 | * 41 | * @author Dominik Bartholdi (imod) 42 | * 43 | */ 44 | public class BuilderChain extends Builder { 45 | 46 | private final List conditionalbuilders; 47 | 48 | public BuilderChain(final List conditionalbuilders) { 49 | this.conditionalbuilders = conditionalbuilders; 50 | } 51 | 52 | @Override 53 | public boolean prebuild(AbstractBuild build, BuildListener listener) { 54 | boolean shouldContinue = true; 55 | for (BuildStep buildStep : conditionalbuilders) { 56 | if (!shouldContinue) { 57 | break; 58 | } 59 | shouldContinue = buildStep.prebuild(build, listener); 60 | } 61 | return shouldContinue; 62 | } 63 | 64 | @Override 65 | public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws IOException, InterruptedException { 66 | boolean shouldContinue = true; 67 | for (BuildStep buildStep : conditionalbuilders) { 68 | if (!shouldContinue) { 69 | break; 70 | } 71 | shouldContinue = buildStep.perform(build, launcher, listener); 72 | } 73 | return shouldContinue; 74 | } 75 | 76 | @Override 77 | public DescriptorImpl getDescriptor() { 78 | return (DescriptorImpl) super.getDescriptor(); 79 | } 80 | 81 | @Extension 82 | public static final class DescriptorImpl extends BuildStepDescriptor { 83 | 84 | @SuppressWarnings("rawtypes") 85 | @Override 86 | public boolean isApplicable(Class jobType) { 87 | return false; 88 | } 89 | 90 | @Override 91 | public String getDisplayName() { 92 | return "BuilderChain"; 93 | } 94 | 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/conditionalbuildstep/ConditionalBuildStepHelper.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.conditionalbuildstep; 2 | 3 | import hudson.maven.MavenModuleSet; 4 | import hudson.model.AbstractProject; 5 | import hudson.model.Project; 6 | import hudson.tasks.BuildStep; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | import jenkins.model.Jenkins; 12 | 13 | import org.jenkinsci.plugins.conditionalbuildstep.singlestep.SingleConditionalBuilder; 14 | 15 | /** 16 | * Helper to work with {@link BuildStep}s wrapped by {@link ConditionalBuilder} or {@link SingleConditionalBuilder}. 17 | * 18 | * @author Dominik Bartholdi (imod) 19 | * 20 | */ 21 | public class ConditionalBuildStepHelper { 22 | 23 | private ConditionalBuildStepHelper() { 24 | } 25 | 26 | /** 27 | * Gets the list of all buildsteps wrapped within any {@link ConditionalBuilder} or {@link SingleConditionalBuilder} from within the given project. Keeps the API backward compatible (Internally 28 | * calls {@link #getConditionalBuildersFromMavenProject(AbstractProject)}) 29 | * 30 | * @see JENKINS-20543 31 | * @param p 32 | * the project to get all wrapped builders for 33 | * @param type 34 | * the type of builders to search for 35 | * @return a list of all buildsteps, never null 36 | */ 37 | public static List getContainedBuilders(Project p, Class type) { 38 | return getContainedBuilders((AbstractProject) p, type); 39 | } 40 | 41 | /** 42 | * Gets the list of all buildsteps wrapped within any {@link ConditionalBuilder} or {@link SingleConditionalBuilder} from within the given project. 43 | * 44 | * @param ap 45 | * the project to get all wrapped builders for 46 | * @param type 47 | * the type of builders to search for 48 | * @return a list of all buildsteps, never null 49 | */ 50 | public static List getContainedBuilders(AbstractProject ap, Class type) { 51 | 52 | final boolean mavenIsInstalled = isMavenPluginInstalled(); 53 | 54 | List r = new ArrayList(); 55 | 56 | List cbuilders = new ArrayList(); 57 | List scbuilders = new ArrayList(); 58 | if (Project.class.isAssignableFrom(ap.getClass())) { 59 | Project p = (Project) ap; 60 | cbuilders.addAll(p.getBuildersList().getAll(ConditionalBuilder.class)); 61 | scbuilders.addAll(p.getBuildersList().getAll(SingleConditionalBuilder.class)); 62 | } else if (mavenIsInstalled) { 63 | cbuilders.addAll(getConditionalBuildersFromMavenProject(ap)); 64 | scbuilders.addAll(getSingleConditionalBuildersFromMavenProject(ap)); 65 | } 66 | 67 | for (ConditionalBuilder conditionalBuilder : cbuilders) { 68 | final List cbs = conditionalBuilder.getConditionalbuilders(); 69 | for (BuildStep buildStep : cbs) { 70 | if (type.isInstance(buildStep)) { 71 | r.add(type.cast(buildStep)); 72 | } 73 | } 74 | } 75 | 76 | for (SingleConditionalBuilder singleConditionalBuilder : scbuilders) { 77 | BuildStep buildStep = singleConditionalBuilder.getBuildStep(); 78 | if (buildStep != null && type.isInstance(buildStep)) { 79 | r.add(type.cast(buildStep)); 80 | } 81 | } 82 | 83 | return r; 84 | } 85 | 86 | private static List getConditionalBuildersFromMavenProject(AbstractProject ap) { 87 | List r = new ArrayList(); 88 | if (MavenModuleSet.class.isAssignableFrom(ap.getClass())) { 89 | MavenModuleSet ms = (MavenModuleSet) ap; 90 | r.addAll(ms.getPostbuilders().getAll(ConditionalBuilder.class)); 91 | r.addAll(ms.getPrebuilders().getAll(ConditionalBuilder.class)); 92 | } 93 | return r; 94 | } 95 | 96 | private static List getSingleConditionalBuildersFromMavenProject(AbstractProject ap) { 97 | List r = new ArrayList(); 98 | if (MavenModuleSet.class.isAssignableFrom(ap.getClass())) { 99 | MavenModuleSet ms = (MavenModuleSet) ap; 100 | r.addAll(ms.getPostbuilders().getAll(SingleConditionalBuilder.class)); 101 | r.addAll(ms.getPrebuilders().getAll(SingleConditionalBuilder.class)); 102 | } 103 | return r; 104 | } 105 | 106 | /** 107 | * Is the maven plugin installed and active? 108 | * 109 | * @return 110 | */ 111 | public static boolean isMavenPluginInstalled() { 112 | Jenkins j = Jenkins.getInstance(); 113 | if (j != null) { 114 | final hudson.Plugin plugin = j.getPlugin("maven-plugin"); 115 | return plugin != null ? plugin.getWrapper().isActive() : false; 116 | } else { 117 | return false; 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/conditionalbuildstep/ConditionalBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (C) 2011 by Dominik Bartholdi 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package org.jenkinsci.plugins.conditionalbuildstep; 25 | 26 | import hudson.DescriptorExtensionList; 27 | import hudson.Extension; 28 | import hudson.Launcher; 29 | import hudson.model.Action; 30 | import hudson.model.BuildListener; 31 | import jenkins.model.DependencyDeclarer; 32 | import hudson.model.DependencyGraph; 33 | import hudson.model.AbstractBuild; 34 | import hudson.model.AbstractProject; 35 | import hudson.model.Descriptor; 36 | import hudson.model.Hudson; 37 | import hudson.tasks.BuildStep; 38 | import hudson.tasks.BuildStepDescriptor; 39 | import hudson.tasks.Builder; 40 | 41 | import java.io.IOException; 42 | import java.util.ArrayList; 43 | import java.util.Collection; 44 | import java.util.List; 45 | import java.util.logging.Logger; 46 | 47 | import net.sf.json.JSONObject; 48 | 49 | import org.jenkins_ci.plugins.run_condition.RunCondition; 50 | import org.jenkins_ci.plugins.run_condition.BuildStepRunner; 51 | import org.jenkinsci.plugins.conditionalbuildstep.dependency.ConditionalDependencyGraphWrapper; 52 | import org.jenkinsci.plugins.conditionalbuildstep.singlestep.SingleConditionalBuilder; 53 | import org.jenkinsci.plugins.conditionalbuildstep.singlestep.SingleConditionalBuilder.SingleConditionalBuilderDescriptor; 54 | import org.kohsuke.stapler.DataBoundConstructor; 55 | import org.kohsuke.stapler.StaplerRequest2; 56 | 57 | /** 58 | * A buildstep wrapping any number of other buildsteps, controlling their execution based on a defined condition. 59 | * 60 | * @author Dominik Bartholdi (imod) 61 | * @author Chris Johnson (cjo9900) 62 | */ 63 | public class ConditionalBuilder extends Builder implements DependencyDeclarer { 64 | private static Logger log = Logger.getLogger(ConditionalBuilder.class.getName()); 65 | 66 | // retaining backward compatibility 67 | private transient String condition; 68 | private transient boolean invertCondition; 69 | 70 | private final BuildStepRunner runner; 71 | private RunCondition runCondition; 72 | private List conditionalbuilders; 73 | 74 | /** 75 | * @deprecated No longer needed as part of the Constructor 76 | * Use {@link #ConditionalBuilder(RunCondition, BuildStepRunner, List)} 77 | */ 78 | @Deprecated 79 | public ConditionalBuilder(RunCondition runCondition, final BuildStepRunner runner) { 80 | //List builders = new ArrayList(); 81 | this(runCondition, runner, new ArrayList()); 82 | } 83 | 84 | @DataBoundConstructor 85 | public ConditionalBuilder(RunCondition runCondition, final BuildStepRunner runner, List conditionalbuilders) { 86 | this.runner = runner; 87 | this.runCondition = runCondition; 88 | this.conditionalbuilders = conditionalbuilders; 89 | } 90 | public BuildStepRunner getRunner() { 91 | return runner; 92 | } 93 | 94 | public RunCondition getRunCondition() { 95 | return runCondition; 96 | } 97 | 98 | @Override 99 | public Collection getProjectActions(AbstractProject project) { 100 | final Collection projectActions = new ArrayList(); 101 | for (BuildStep buildStep : getConditionalbuilders()) { 102 | projectActions.addAll(buildStep.getProjectActions(project)); 103 | } 104 | return projectActions; 105 | } 106 | 107 | public List getConditionalbuilders() { 108 | if(conditionalbuilders == null){ 109 | conditionalbuilders = new ArrayList(); 110 | } 111 | return conditionalbuilders; 112 | } 113 | 114 | /** 115 | * Set the Conditional Builders 116 | * 117 | * @deprecated No longer needed as part of the DataBoundConstructor 118 | */ 119 | @Deprecated 120 | public void setConditionalbuilders(List conditionalbuilders) { 121 | this.conditionalbuilders = conditionalbuilders; 122 | } 123 | 124 | @Override 125 | public boolean prebuild(final AbstractBuild build, final BuildListener listener) { 126 | return runner.prebuild(runCondition, new BuilderChain(getConditionalbuilders()), build, listener); 127 | } 128 | 129 | @Override 130 | public boolean perform(final AbstractBuild build, final Launcher launcher, final BuildListener listener) throws InterruptedException, IOException { 131 | return runner.perform(runCondition, new BuilderChain(getConditionalbuilders()), build, launcher, listener); 132 | } 133 | 134 | public Object readResolve() { 135 | if (condition != null) { 136 | // retaining backward compatibility 137 | this.runCondition = new LegacyBuildstepCondition(condition, invertCondition); 138 | } 139 | return this; 140 | } 141 | 142 | @Override 143 | public DescriptorImpl getDescriptor() { 144 | return (DescriptorImpl) super.getDescriptor(); 145 | } 146 | 147 | @Extension 148 | public static final class DescriptorImpl extends BuildStepDescriptor { 149 | 150 | public boolean isApplicable(final Class aClass) { 151 | // No need for aggregation for matrix build with MatrixAggregatable 152 | // this is only supported for: {@link Publisher}, {@link JobProperty}, {@link BuildWrapper} 153 | return !SingleConditionalBuilder.PROMOTION_JOB_TYPE.equals(aClass.getCanonicalName()); 154 | } 155 | 156 | /** 157 | * This human readable name is used in the configuration screen. 158 | */ 159 | public String getDisplayName() { 160 | return Messages.multistepbuilder_displayName(); 161 | } 162 | 163 | @Override 164 | public boolean configure(StaplerRequest2 req, JSONObject formData) throws FormException { 165 | save(); 166 | return super.configure(req, formData); 167 | } 168 | 169 | public List> getBuilderDescriptors(AbstractProject project) { 170 | final SingleConditionalBuilderDescriptor singleConditionalStepDescriptor = Hudson.getInstance().getDescriptorByType( 171 | SingleConditionalBuilderDescriptor.class); 172 | return singleConditionalStepDescriptor.getAllowedBuilders(project); 173 | } 174 | 175 | public DescriptorExtensionList getBuildStepRunners() { 176 | return BuildStepRunner.all(); 177 | } 178 | 179 | public List> getRunConditions() { 180 | return RunCondition.all(); 181 | } 182 | 183 | } 184 | 185 | public void buildDependencyGraph(AbstractProject project, DependencyGraph graph) { 186 | for (BuildStep builder : getConditionalbuilders()) { 187 | if(builder instanceof DependencyDeclarer) { 188 | ((DependencyDeclarer)builder).buildDependencyGraph( 189 | project, new ConditionalDependencyGraphWrapper(graph, runCondition, runner)); 190 | } 191 | } 192 | } 193 | 194 | } 195 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/conditionalbuildstep/LegacyBuildstepCondition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (C) 2011 by Dominik Bartholdi 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | /** 25 | * 26 | */ 27 | package org.jenkinsci.plugins.conditionalbuildstep; 28 | 29 | import hudson.Extension; 30 | import hudson.model.BuildListener; 31 | import hudson.model.AbstractBuild; 32 | import hudson.util.FormValidation; 33 | import hudson.util.VariableResolver; 34 | 35 | import java.io.IOException; 36 | import java.util.logging.Level; 37 | import java.util.logging.Logger; 38 | 39 | import jakarta.servlet.ServletException; 40 | 41 | import org.jenkins_ci.plugins.run_condition.RunCondition; 42 | import org.jenkinsci.plugins.tokenmacro.MacroEvaluationException; 43 | import org.jenkinsci.plugins.tokenmacro.TokenMacro; 44 | import org.kohsuke.stapler.DataBoundConstructor; 45 | import org.kohsuke.stapler.QueryParameter; 46 | 47 | /** 48 | * Legacy condition to ease migration from old condition to new condition mecano implemented by the run-condition-plugin 49 | * 50 | * @author domi 51 | * @deprecated keep to retain backward compatibility 52 | */ 53 | @Deprecated 54 | public class LegacyBuildstepCondition extends RunCondition { 55 | 56 | private static Logger log = Logger.getLogger(LegacyBuildstepCondition.class.getName()); 57 | 58 | private final String condition; 59 | private final boolean invertCondition; 60 | 61 | @DataBoundConstructor 62 | public LegacyBuildstepCondition(String condition, boolean invert) { 63 | this.condition = condition; 64 | this.invertCondition = invert; 65 | } 66 | 67 | public String getCondition() { 68 | return condition; 69 | } 70 | 71 | public boolean isInvertCondition() { 72 | return invertCondition; 73 | } 74 | 75 | @Override 76 | public boolean runPerform(AbstractBuild build, BuildListener listener) throws Exception { 77 | return shouldRun(build, listener); 78 | } 79 | 80 | @Override 81 | public boolean runPrebuild(AbstractBuild build, BuildListener listener) throws Exception { 82 | return shouldRun(build, listener); 83 | } 84 | 85 | private boolean shouldRun(AbstractBuild build, BuildListener listener) throws IOException, InterruptedException { 86 | String resolvedCondition = condition; 87 | try { 88 | resolvedCondition = TokenMacro.expand(build, listener, condition); 89 | } catch (MacroEvaluationException e) { 90 | 91 | log.log(Level.FINE, "failed to resolve condition via TokenMacro: {0}", e.getMessage()); 92 | 93 | final VariableResolver variableResolver = build.getBuildVariableResolver(); 94 | resolvedCondition = resolveVariable(variableResolver, condition); 95 | } 96 | 97 | resolvedCondition = resolvedCondition == null ? condition : resolvedCondition; 98 | final boolean execute = invertCondition ? !"true".equalsIgnoreCase(resolvedCondition.trim()) : "true".equalsIgnoreCase(resolvedCondition.trim()); 99 | listener.getLogger().println( 100 | "ConditionalStep [" + condition + "] evaluated to [" + resolvedCondition + "] (invert: " + invertCondition + ") execute --> " + execute); 101 | 102 | return execute; 103 | 104 | } 105 | 106 | public static String resolveVariable(VariableResolver variableResolver, String potentalVaraible) { 107 | String value = potentalVaraible; 108 | if (potentalVaraible != null) { 109 | if (potentalVaraible.startsWith("${") && potentalVaraible.endsWith("}")) { 110 | value = potentalVaraible.substring(2, potentalVaraible.length() - 1); 111 | value = variableResolver.resolve(value); 112 | log.log(Level.FINE, "resolve " + potentalVaraible + " to " + value); 113 | } 114 | } 115 | return value; 116 | } 117 | 118 | @Extension 119 | public static class LegacyConditionDescriptor extends RunConditionDescriptor { 120 | 121 | @Override 122 | public String getDisplayName() { 123 | return Messages.legacycondition_displayName(); 124 | } 125 | 126 | /** 127 | * Performs on-the-fly validation of the form field 'condition'. 128 | * 129 | * @param value 130 | * This parameter receives the value that the user has typed. 131 | * @return Indicates the outcome of the validation. 132 | */ 133 | public FormValidation doCheckCondition(@QueryParameter String value) throws IOException, ServletException { 134 | if (value.length() == 0) { 135 | return FormValidation.error("Please define a condition"); 136 | } 137 | if (!value.startsWith("${")) { 138 | return FormValidation.warning("do you realy want to hard code the condition?"); 139 | } 140 | return FormValidation.ok(); 141 | } 142 | 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/conditionalbuildstep/dependency/ConditionalDependencyGraphWrapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2013 IKEDA Yasuyuki 5 | * This class originates from the class with the same name in flexible publish plugin: 6 | * https://github.com/jenkinsci/flexible-publish-plugin 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | package org.jenkinsci.plugins.conditionalbuildstep.dependency; 27 | 28 | import java.util.List; 29 | import java.util.Set; 30 | 31 | import org.jenkins_ci.plugins.run_condition.RunCondition; 32 | import org.jenkins_ci.plugins.run_condition.BuildStepRunner; 33 | 34 | import hudson.model.AbstractProject; 35 | import hudson.model.DependencyGraph; 36 | 37 | /** 38 | * Wraps {@link DependencyGraph} and append {@link RunCondition} to {@link Dependency}. 39 | * 40 | * Methods other than addDependency are just calling methods of wrapped {@link DependencyGraph} 41 | */ 42 | public class ConditionalDependencyGraphWrapper extends DependencyGraph 43 | { 44 | private DependencyGraph graph; 45 | private RunCondition condition; 46 | private BuildStepRunner runner; 47 | 48 | public ConditionalDependencyGraphWrapper(DependencyGraph graph, RunCondition condition, BuildStepRunner runner) { 49 | this.graph = graph; 50 | this.condition = condition; 51 | this.runner = runner; 52 | } 53 | 54 | /** 55 | * Add dependency. {@link RunCondition} will be attached. 56 | * 57 | * @see hudson.model.DependencyGraph#addDependency(hudson.model.DependencyGraph.Dependency) 58 | */ 59 | @Override 60 | public void addDependency(Dependency dep) { 61 | graph.addDependency(new ConditionalDependencyWrapper(dep, condition, runner)); 62 | } 63 | 64 | @Override 65 | public void build() { 66 | graph.build(); 67 | } 68 | 69 | @SuppressWarnings("rawtypes") 70 | @Override 71 | public int compare(AbstractProject o1, AbstractProject o2) { 72 | return graph.compare(o1, o2); 73 | } 74 | 75 | @Override 76 | public T getComputationalData(Class key) { 77 | return graph.getComputationalData(key); 78 | } 79 | 80 | @SuppressWarnings("rawtypes") 81 | @Override 82 | public List getDownstream(AbstractProject p) { 83 | return graph.getDownstream(p); 84 | } 85 | 86 | @SuppressWarnings("rawtypes") 87 | @Override 88 | public List getDownstreamDependencies(AbstractProject p) { 89 | return graph.getDownstreamDependencies(p); 90 | } 91 | 92 | @SuppressWarnings("rawtypes") 93 | @Override 94 | public Set getTransitiveDownstream(AbstractProject src) { 95 | return graph.getTransitiveDownstream(src); 96 | } 97 | 98 | @SuppressWarnings("rawtypes") 99 | @Override 100 | public Set getTransitiveUpstream(AbstractProject src) { 101 | return graph.getTransitiveUpstream(src); 102 | } 103 | 104 | @SuppressWarnings("rawtypes") 105 | @Override 106 | public List getUpstream(AbstractProject p) { 107 | return graph.getUpstream(p); 108 | } 109 | 110 | @SuppressWarnings("rawtypes") 111 | @Override 112 | public List getUpstreamDependencies(AbstractProject p) { 113 | return graph.getUpstreamDependencies(p); 114 | } 115 | 116 | @SuppressWarnings("rawtypes") 117 | @Override 118 | public boolean hasIndirectDependencies(AbstractProject src, AbstractProject dst) { 119 | return graph.hasIndirectDependencies(src, dst); 120 | } 121 | 122 | @Override 123 | public void putComputationalData(Class key, T value) { 124 | graph.putComputationalData(key, value); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/conditionalbuildstep/dependency/ConditionalDependencyWrapper.java: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* 4 | * The MIT License 5 | * 6 | * Copyright (c) 2013 IKEDA Yasuyuki 7 | * This class originates from the class with the same name in flexible publish plugin: 8 | * https://github.com/jenkinsci/flexible-publish-plugin 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy 11 | * of this software and associated documentation files (the "Software"), to deal 12 | * in the Software without restriction, including without limitation the rights 13 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | * copies of the Software, and to permit persons to whom the Software is 15 | * furnished to do so, subject to the following conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in 18 | * all copies or substantial portions of the Software. 19 | * 20 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | * THE SOFTWARE. 27 | */ 28 | package org.jenkinsci.plugins.conditionalbuildstep.dependency; 29 | 30 | import java.io.IOException; 31 | import java.util.List; 32 | import java.util.logging.Level; 33 | import java.util.logging.Logger; 34 | import org.jenkins_ci.plugins.run_condition.RunCondition; 35 | import org.jenkins_ci.plugins.run_condition.BuildStepRunner; 36 | import hudson.Launcher; 37 | import hudson.model.DependencyGraph.Dependency; 38 | import hudson.model.AbstractBuild; 39 | import hudson.model.AbstractProject; 40 | import hudson.model.Descriptor; 41 | import hudson.model.Action; 42 | import hudson.model.BuildListener; 43 | import hudson.model.StreamBuildListener; 44 | import hudson.model.TaskListener; 45 | import hudson.tasks.BuildStepDescriptor; 46 | import hudson.tasks.Builder; 47 | import hudson.util.NullStream; 48 | 49 | /** 50 | * Wraps {@link Dependency} and evaluates {@link RunCondition} when the dependency is triggered. 51 | */ 52 | public class ConditionalDependencyWrapper extends Dependency { 53 | private static Logger LOGGER = Logger.getLogger(ConditionalDependencyWrapper.class.getName()); 54 | private Dependency dep; 55 | private RunCondition condition; 56 | private BuildStepRunner runner; 57 | 58 | public ConditionalDependencyWrapper(Dependency dep, RunCondition condition, BuildStepRunner runner) { 59 | super(dep.getUpstreamProject(), dep.getDownstreamProject()); 60 | this.dep = dep; 61 | this.condition = condition; 62 | this.runner = runner; 63 | } 64 | 65 | /** 66 | * Determines whether the downstream project should be launched. 67 | * 68 | * {@link RunCondition} is evaluated. 69 | * 70 | * @see hudson.model.DependencyGraph.Dependency#shouldTriggerBuild(hudson.model.AbstractBuild, hudson.model.TaskListener, java.util.List) 71 | */ 72 | @SuppressWarnings("rawtypes") 73 | @Override 74 | public boolean shouldTriggerBuild(AbstractBuild build, 75 | TaskListener listener, List actions) { 76 | BuildListener buildListener = null; 77 | if (listener instanceof BuildListener) { 78 | buildListener = (BuildListener)listener; 79 | } else { 80 | // Usually listener is instance of BuildListener, 81 | // So there may be no case entering this path. 82 | // If there's that case, BuildLister wrapping TaskListener should be written. 83 | LOGGER.warning("There is no BuildListener, and logs from RunCondition won't be recorded."); 84 | buildListener = new StreamBuildListener(new NullStream()); 85 | } 86 | 87 | try { 88 | MarkPerformedBuilder marker = new MarkPerformedBuilder(); 89 | 90 | // launcher is not used by condition or runner or marker, 91 | // this never cause NPE. 92 | Launcher launcher = null; 93 | runner.perform(condition, marker, build, launcher, buildListener); 94 | 95 | if (marker.isPerformed()) { 96 | return dep.shouldTriggerBuild(build, listener, actions); 97 | } else { 98 | return false; 99 | } 100 | } catch (Exception e) { 101 | LOGGER.log(Level.SEVERE, "Failed to evaluate condition", e); 102 | return false; 103 | } 104 | } 105 | 106 | @Override 107 | public boolean equals(Object obj) { 108 | if (obj == null || getClass() != obj.getClass()) { 109 | return false; 110 | } 111 | 112 | ConditionalDependencyWrapper d = (ConditionalDependencyWrapper)obj; 113 | 114 | return dep.equals(d.dep) && condition.equals(d.condition); 115 | } 116 | 117 | @Override 118 | public int hashCode() { 119 | return dep.hashCode() * 23 + condition.hashCode(); 120 | } 121 | 122 | @SuppressWarnings("rawtypes") 123 | @Override 124 | public AbstractProject getDownstreamProject() { 125 | return dep.getDownstreamProject(); 126 | } 127 | 128 | @SuppressWarnings("rawtypes") 129 | @Override 130 | public AbstractProject getUpstreamProject() { 131 | return dep.getUpstreamProject(); 132 | } 133 | 134 | @Override 135 | public boolean pointsItself() { 136 | return dep.pointsItself(); 137 | } 138 | 139 | /** 140 | * Used with {@link BuildStepRunner}. 141 | * 142 | * Stores whether perform is executed. 143 | */ 144 | private static class MarkPerformedBuilder extends Builder { 145 | private boolean performed = false; 146 | 147 | public boolean isPerformed() { 148 | return performed; 149 | } 150 | 151 | @Override 152 | public boolean perform(AbstractBuild build, Launcher launcher, 153 | BuildListener listener) throws InterruptedException, IOException { 154 | performed = true; 155 | return true; 156 | } 157 | 158 | private static final Descriptor DESCRIPTOR = 159 | new BuildStepDescriptor() { 160 | @SuppressWarnings("rawtypes") 161 | @Override 162 | public boolean isApplicable(Class jobType) { 163 | return true; 164 | } 165 | 166 | @Override 167 | public String getDisplayName() { 168 | return "Builder to mark whether executed"; 169 | } 170 | }; 171 | @Override 172 | public Descriptor getDescriptor() { 173 | return DESCRIPTOR; 174 | } 175 | }; 176 | } 177 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/conditionalbuildstep/lister/BuilderDescriptorLister.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (C) 2011 by Anthony Robinson 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package org.jenkinsci.plugins.conditionalbuildstep.lister; 26 | 27 | import hudson.ExtensionPoint; 28 | import hudson.model.Describable; 29 | import hudson.model.AbstractProject; 30 | import hudson.model.Descriptor; 31 | import hudson.tasks.BuildStep; 32 | 33 | import java.util.List; 34 | 35 | public interface BuilderDescriptorLister extends Describable, ExtensionPoint { 36 | public List> getAllowedBuilders(AbstractProject project); 37 | } 38 | 39 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/conditionalbuildstep/lister/DefaultBuilderDescriptorLister.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (C) 2011 by Anthony Robinson 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package org.jenkinsci.plugins.conditionalbuildstep.lister; 26 | 27 | import hudson.Extension; 28 | import hudson.model.AbstractProject; 29 | import hudson.model.Descriptor; 30 | import hudson.model.Hudson; 31 | import hudson.tasks.BuildStep; 32 | import hudson.tasks.BuildStepDescriptor; 33 | import hudson.tasks.Builder; 34 | 35 | import java.lang.reflect.Constructor; 36 | import java.util.ArrayList; 37 | import java.util.List; 38 | 39 | import org.jenkinsci.plugins.conditionalbuildstep.BuilderChain; 40 | import org.jenkinsci.plugins.conditionalbuildstep.ConditionalBuilder; 41 | import org.jenkinsci.plugins.conditionalbuildstep.Messages; 42 | import org.jenkinsci.plugins.conditionalbuildstep.singlestep.SingleConditionalBuilder; 43 | import org.kohsuke.stapler.DataBoundConstructor; 44 | 45 | public class DefaultBuilderDescriptorLister implements BuilderDescriptorLister { 46 | 47 | @DataBoundConstructor 48 | public DefaultBuilderDescriptorLister() { 49 | } 50 | 51 | public List> getAllowedBuilders(final AbstractProject project) { 52 | final List> builders = new ArrayList>(); 53 | if (project == null) 54 | return builders; 55 | for (Descriptor descriptor : Builder.all()) { 56 | if (descriptor instanceof SingleConditionalBuilder.SingleConditionalBuilderDescriptor) { 57 | continue; 58 | } 59 | if (descriptor instanceof ConditionalBuilder.DescriptorImpl) { 60 | continue; 61 | } 62 | if (descriptor instanceof BuilderChain.DescriptorImpl) { 63 | continue; 64 | } 65 | if (!(descriptor instanceof BuildStepDescriptor)) { 66 | continue; 67 | } 68 | BuildStepDescriptor buildStepDescriptor = (BuildStepDescriptor) descriptor; 69 | if (buildStepDescriptor.isApplicable(project.getClass()) && hasDbc(buildStepDescriptor.clazz)){ 70 | builders.add(buildStepDescriptor); 71 | } 72 | } 73 | return builders; 74 | } 75 | 76 | public DescriptorImpl getDescriptor() { 77 | return Hudson.getInstance().getDescriptorByType(DescriptorImpl.class); 78 | } 79 | 80 | private boolean hasDbc(final Class clazz) { 81 | for (Constructor constructor : clazz.getConstructors()) { 82 | if (constructor.isAnnotationPresent(DataBoundConstructor.class)) 83 | return true; 84 | } 85 | return false; 86 | } 87 | 88 | @Extension 89 | public static class DescriptorImpl extends Descriptor { 90 | 91 | @Override 92 | public String getDisplayName() { 93 | return Messages.defaultBuilderDescriptor_displayName(); 94 | } 95 | 96 | } 97 | 98 | } -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/conditionalbuildstep/singlestep/JobUpdater.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (C) 2011 by Anthony Robinson 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package org.jenkinsci.plugins.conditionalbuildstep.singlestep; 26 | 27 | import hudson.model.Descriptor; 28 | import hudson.model.FreeStyleProject; 29 | import hudson.tasks.BuildStep; 30 | import hudson.tasks.Builder; 31 | import hudson.util.DescribableList; 32 | 33 | import java.io.IOException; 34 | import java.util.ArrayList; 35 | import java.util.List; 36 | 37 | import org.jenkins_ci.plugins.run_condition.BuildStepRunner; 38 | import org.jenkins_ci.plugins.run_condition.core.AlwaysRun; 39 | import org.jenkinsci.plugins.conditionalbuildstep.lister.DefaultBuilderDescriptorLister; 40 | 41 | /** 42 | * Utilities for the script console 43 | */ 44 | public class JobUpdater { 45 | 46 | /** 47 | * Wrap all of the allowed BuildSteps on a freestyle project with a single conditional builder 48 | * 49 | * For freestyle project called 'xxx': 50 | * 51 | * 52 | * import static org.jenkinsci.plugins.conditionalbuildstep.singlestep.JobUpdater.* 53 | * 54 | * def job = hudson.model.Hudson.instance.getItem('xxx') 55 | * updateBuilders job 56 | * 57 | * 58 | * Once executed, go to the configure page to check that everything looks OK, then save the configuration 59 | */ 60 | public static boolean updateBuilders(final FreeStyleProject project) throws IOException { 61 | if (project == null) return false; 62 | final DescribableList> builders = project.getBuildersList(); 63 | final DefaultBuilderDescriptorLister builderLister = new DefaultBuilderDescriptorLister(); 64 | final List> allowed = builderLister.getAllowedBuilders(project); 65 | final List replace = new ArrayList(); 66 | for (Builder builder : builders) { 67 | if (allowed.contains(builder.getDescriptor())) 68 | replace.add(new SingleConditionalBuilder((BuildStep) builder, new AlwaysRun(), new BuildStepRunner.Fail())); 69 | else 70 | replace.add(builder); 71 | } 72 | builders.replaceBy(replace); 73 | return true; 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/conditionalbuildstep/singlestep/SingleConditionalBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (C) 2011 by Anthony Robinson 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package org.jenkinsci.plugins.conditionalbuildstep.singlestep; 26 | 27 | import hudson.DescriptorExtensionList; 28 | import hudson.Extension; 29 | import hudson.Launcher; 30 | import hudson.model.BuildListener; 31 | import hudson.model.DependencyGraph; 32 | import hudson.model.AbstractBuild; 33 | import hudson.model.AbstractProject; 34 | import hudson.model.Descriptor; 35 | import hudson.model.Hudson; 36 | import hudson.tasks.BuildStep; 37 | import hudson.tasks.BuildStepDescriptor; 38 | import hudson.tasks.BuildStepMonitor; 39 | import hudson.tasks.Builder; 40 | 41 | import java.io.IOException; 42 | import java.util.Collection; 43 | import java.util.Collections; 44 | import java.util.List; 45 | 46 | import jenkins.model.DependencyDeclarer; 47 | import net.sf.json.JSONObject; 48 | 49 | import org.jenkins_ci.plugins.run_condition.RunCondition; 50 | import org.jenkins_ci.plugins.run_condition.BuildStepRunner; 51 | import org.jenkins_ci.plugins.run_condition.core.AlwaysRun; 52 | import org.jenkinsci.plugins.conditionalbuildstep.Messages; 53 | import org.jenkinsci.plugins.conditionalbuildstep.dependency.ConditionalDependencyGraphWrapper; 54 | import org.jenkinsci.plugins.conditionalbuildstep.lister.BuilderDescriptorLister; 55 | import org.jenkinsci.plugins.conditionalbuildstep.lister.DefaultBuilderDescriptorLister; 56 | import org.kohsuke.stapler.DataBoundConstructor; 57 | import org.kohsuke.stapler.Stapler; 58 | import org.kohsuke.stapler.StaplerRequest2; 59 | 60 | /** 61 | * 62 | * @author Anthony Robinson 63 | * @author Dominik Bartholdi (imod) 64 | */ 65 | public class SingleConditionalBuilder extends Builder implements DependencyDeclarer { 66 | 67 | public static final String PROMOTION_JOB_TYPE = "hudson.plugins.promoted_builds.PromotionProcess"; 68 | 69 | private final RunCondition condition; 70 | private final BuildStep buildStep; 71 | private final BuildStepRunner runner; 72 | 73 | @DataBoundConstructor 74 | public SingleConditionalBuilder(final BuildStep buildStep, final RunCondition condition, final BuildStepRunner runner) { 75 | this.buildStep = buildStep; 76 | this.condition = condition; 77 | this.runner = runner; 78 | } 79 | 80 | public BuildStep getBuildStep() { 81 | return buildStep; 82 | } 83 | 84 | public RunCondition getCondition() { 85 | return condition; 86 | } 87 | 88 | public BuildStepRunner getRunner() { 89 | return runner; 90 | } 91 | 92 | public BuildStepMonitor getRequiredMonitorService() { 93 | return buildStep == null ? BuildStepMonitor.NONE : buildStep.getRequiredMonitorService(); 94 | } 95 | 96 | @Override 97 | public Collection getProjectActions(final AbstractProject project) { 98 | return buildStep == null ? Collections.emptyList() : buildStep.getProjectActions(project); 99 | } 100 | 101 | @Override 102 | public boolean prebuild(final AbstractBuild build, final BuildListener listener) { 103 | return runner.prebuild(condition, buildStep, build, listener); 104 | } 105 | 106 | @Override 107 | public boolean perform(final AbstractBuild build, final Launcher launcher, final BuildListener listener) throws InterruptedException, IOException { 108 | return runner.perform(condition, buildStep, build, launcher, listener); 109 | } 110 | 111 | public void buildDependencyGraph(AbstractProject project, DependencyGraph graph) { 112 | if(buildStep != null) { 113 | if(buildStep instanceof DependencyDeclarer) { 114 | DependencyDeclarer dependencyDeclarer = (DependencyDeclarer) buildStep; 115 | dependencyDeclarer.buildDependencyGraph(project, new ConditionalDependencyGraphWrapper(graph, condition, runner)); 116 | } 117 | } 118 | } 119 | 120 | @Extension(ordinal = Integer.MAX_VALUE - 500) 121 | public static class SingleConditionalBuilderDescriptor extends BuildStepDescriptor { 122 | 123 | public static DescriptorExtensionList> getAllBuilderDescriptorListers() { 124 | return Hudson.getInstance().> getDescriptorList(BuilderDescriptorLister.class); 125 | } 126 | 127 | private BuilderDescriptorLister builderLister; 128 | 129 | @DataBoundConstructor 130 | public SingleConditionalBuilderDescriptor(final BuilderDescriptorLister builderLister) { 131 | this.builderLister = builderLister; 132 | } 133 | 134 | public SingleConditionalBuilderDescriptor() { 135 | load(); 136 | if (builderLister == null) 137 | builderLister = new DefaultBuilderDescriptorLister(); 138 | } 139 | 140 | public BuilderDescriptorLister getBuilderLister() { 141 | return builderLister; 142 | } 143 | 144 | @Override 145 | public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { 146 | final SingleConditionalBuilderDescriptor newConfig = req.bindJSON(SingleConditionalBuilderDescriptor.class, json); 147 | if (newConfig.builderLister != null) 148 | builderLister = newConfig.builderLister; 149 | save(); 150 | return true; 151 | } 152 | 153 | @Override 154 | public String getDisplayName() { 155 | return Messages.singlestepbuilder_displayName(); 156 | } 157 | 158 | public boolean isApplicable(final Class aClass) { 159 | // No need for aggregation for matrix build with MatrixAggregatable 160 | // this is only supported for: {@link Publisher}, {@link JobProperty}, {@link BuildWrapper} 161 | return !PROMOTION_JOB_TYPE.equals(aClass.getCanonicalName()); 162 | } 163 | 164 | public DescriptorExtensionList getBuildStepRunners() { 165 | return BuildStepRunner.all(); 166 | } 167 | 168 | public BuildStepRunner.BuildStepRunnerDescriptor getDefaultBuildStepRunner() { 169 | return Hudson.getInstance().getDescriptorByType(BuildStepRunner.Fail.FailDescriptor.class); 170 | } 171 | 172 | public List> getRunConditions() { 173 | return RunCondition.all(); 174 | } 175 | 176 | public RunCondition.RunConditionDescriptor getDefaultRunCondition() { 177 | return Hudson.getInstance().getDescriptorByType(AlwaysRun.AlwaysRunDescriptor.class); 178 | } 179 | 180 | public List> getAllowedBuilders(AbstractProject project) { 181 | if (project == null) 182 | project = Stapler.getCurrentRequest2().findAncestorObject(AbstractProject.class); 183 | return builderLister.getAllowedBuilders(project); 184 | } 185 | 186 | public Object readResolve() { 187 | if (builderLister == null) 188 | builderLister = new DefaultBuilderDescriptorLister(); 189 | return this; 190 | } 191 | 192 | } 193 | 194 | } -------------------------------------------------------------------------------- /src/main/resources/index.jelly: -------------------------------------------------------------------------------- 1 | 2 |
3 | A buildstep wrapping any number of other buildsteps, controlling their execution based on a defined condition (e.g. BuildParameter). 4 |
5 | -------------------------------------------------------------------------------- /src/main/resources/lib/conditionalbuildstep/taglib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/conditional-buildstep-plugin/26be9760f055820584548d0a82f2df787e1242be/src/main/resources/lib/conditionalbuildstep/taglib -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/conditionalbuildstep/ConditionalBuilder/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 |
17 | 18 | 19 | 21 | 22 | 23 |
24 |
25 |
26 |
27 | 28 | 29 |
30 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/conditionalbuildstep/ConditionalBuilder/config.properties: -------------------------------------------------------------------------------- 1 | # 2 | # The MIT License 3 | # 4 | # Copyright (C) 2011 by Anthony Robinson 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in 14 | # all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | # THE SOFTWARE. 23 | # 24 | 25 | condition=Run? 26 | runner=On evaluation failure 27 | stepssection=Steps to run if condition is met -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/conditionalbuildstep/ConditionalBuilder/help-runCondition.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 26 | 27 | 28 | 29 | 30 |
31 |

Available Token Macros

32 | 33 | 34 |
-------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/conditionalbuildstep/ConditionalBuilder/help-runner.html: -------------------------------------------------------------------------------- 1 | 24 | 25 |
If the evaluation of a run condition fails, should the build fail, be marked unstable, run the build step ... 26 |

A run condition evaluation may fail to run cleanly - especially if it is dependent on expanding tokens provided by the Token Macro Plugin 27 | and the values are expected to be present or look like a certain type i.e. be a number.
28 | ...its about the action to take when the condition can not be evaluated - this is not same as evaluating to false. 29 |

30 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/conditionalbuildstep/LegacyBuildstepCondition/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/conditionalbuildstep/LegacyBuildstepCondition/help.jelly: -------------------------------------------------------------------------------- 1 | 2 |
3 | Used to retain backward compatibility... please use the 'Boolean condition' 4 | The resolved value has to be true or false (where everything else then true is handled as false, case ignored).
5 | The following definitions are supported: 6 |
    7 |
  • fix value true or false
  • 8 |
  • reference of a build parameter (e.g. ${DOIT})
  • 9 |
  • as TokenMacro consumer (install any plugin from the TokenMacro Producer List)
  • 10 |
11 | With the checkbox it is possible to invert the resolved condition. 12 |
-------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/conditionalbuildstep/Messages.properties: -------------------------------------------------------------------------------- 1 | # 2 | # The MIT License 3 | # 4 | # Copyright (C) 2011 by Anthony Robinson, Dominik Bartholdi 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in 14 | # all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | # THE SOFTWARE. 23 | # 24 | 25 | multistepbuilder.displayName=Conditional steps (multiple) 26 | singlestepbuilder.displayName=Conditional step (single) 27 | defaultBuilderDescriptor.displayName=Default builder lister 28 | legacycondition.displayName=Legacy boolean condition (deprecated) 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/conditionalbuildstep/lister/DefaultBuilderDescriptorLister/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/conditionalbuildstep/singlestep/SingleConditionalBuilder/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 26 | 27 | 28 | 29 | 30 | 32 | 33 | 34 | 35 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/conditionalbuildstep/singlestep/SingleConditionalBuilder/config.properties: -------------------------------------------------------------------------------- 1 | # 2 | # The MIT License 3 | # 4 | # Copyright (C) 2011 by Anthony Robinson 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in 14 | # all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | # THE SOFTWARE. 23 | # 24 | 25 | condition=Run? 26 | runner=On evaluation failure 27 | buildStep=Builder 28 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/conditionalbuildstep/singlestep/SingleConditionalBuilder/global.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/conditionalbuildstep/singlestep/SingleConditionalBuilder/global.properties: -------------------------------------------------------------------------------- 1 | # 2 | # The MIT License 3 | # 4 | # Copyright (C) 2011 by Anthony Robinson 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in 14 | # all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | # THE SOFTWARE. 23 | # 24 | 25 | section=Conditional buildstep 26 | builderLister=Allowed build steps 27 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/conditionalbuildstep/singlestep/SingleConditionalBuilder/help-condition.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 26 | 27 | 28 | 29 | 30 |
31 |

Available Token Macros

32 | 33 | 34 |
-------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/conditionalbuildstep/singlestep/SingleConditionalBuilder/help-runner.html: -------------------------------------------------------------------------------- 1 | 24 | 25 |
If the evaluation of a run condition fails, should the build fail, be marked unstable, run the build step ... 26 |

A run condition evaluation may fail to run cleanly - especially if it is dependent on expanding tokens provided by the Token Macro Plugin 27 | and the values are expected to be present or look like a certain type i.e. be a number.
28 | ...its about the action to take when the condition can not be evaluated - this is not same as evaluating to false. 29 |

30 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/conditionalbuildstep/singlestep/SingleConditionalBuilder/help.html: -------------------------------------------------------------------------------- 1 | 24 | 25 |
Use run conditions to decide whether a builder should be run.
26 | -------------------------------------------------------------------------------- /src/spotbugs/spotbugs-excludes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/test/java/org/jenkinsci/plugins/conditionalbuildstep/ConfigFileBuildWrapperTest.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.conditionalbuildstep; 2 | 3 | import hudson.maven.MavenModuleSet; 4 | import hudson.model.FreeStyleProject; 5 | import hudson.tasks.Shell; 6 | import org.jenkins_ci.plugins.run_condition.BuildStepRunner; 7 | import org.jenkins_ci.plugins.run_condition.core.BooleanCondition; 8 | import org.junit.jupiter.api.Test; 9 | import org.jvnet.hudson.test.JenkinsRule; 10 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins; 11 | 12 | import java.util.List; 13 | 14 | import static org.junit.jupiter.api.Assertions.assertEquals; 15 | import static org.junit.jupiter.api.Assertions.assertNotNull; 16 | 17 | @WithJenkins 18 | class ConfigFileBuildWrapperTest { 19 | 20 | @Test 21 | void conditionalBuildersInMavenProjectMustBeResolvable(JenkinsRule j) throws Exception { 22 | final MavenModuleSet p = j.createProject(MavenModuleSet.class, "mvn"); 23 | p.setRunHeadless(true); 24 | 25 | ConditionalBuilder cBuilder = new ConditionalBuilder(new BooleanCondition("true"), new BuildStepRunner.Run()); 26 | Shell shell = new Shell("ls"); 27 | cBuilder.getConditionalbuilders().add(shell); 28 | p.getPrebuilders().add(cBuilder); 29 | 30 | final List containedBuilders = ConditionalBuildStepHelper.getContainedBuilders(p, Shell.class); 31 | assertNotNull(containedBuilders, "no builders returned"); 32 | assertEquals(1, containedBuilders.size(), "not correct number of builders returned"); 33 | } 34 | 35 | @Test 36 | void conditionalBuildersInFreestyleProjectMustBeResolvable(JenkinsRule j) throws Exception { 37 | final FreeStyleProject p = j.createFreeStyleProject(); 38 | 39 | ConditionalBuilder cBuilder = new ConditionalBuilder(new BooleanCondition("true"), new BuildStepRunner.Run()); 40 | Shell shell = new Shell("ls"); 41 | Shell shell2 = new Shell("ls"); 42 | cBuilder.getConditionalbuilders().add(shell); 43 | cBuilder.getConditionalbuilders().add(shell2); 44 | p.getBuildersList().add(cBuilder); 45 | 46 | final List containedBuilders = ConditionalBuildStepHelper.getContainedBuilders(p, Shell.class); 47 | assertNotNull(containedBuilders, "no builders returned"); 48 | assertEquals(2, containedBuilders.size(), "not correct number of builders returned"); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/test/resources/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -1 7 | 5 8 | -1 9 | -1 10 | 11 | false 12 | 13 | 14 | 15 | 16 | DOIT 17 | 18 | false 19 | 20 | 21 | 22 | 23 | 24 | true 25 | false 26 | false 27 | false 28 | 29 | false 30 | 31 | 32 | ${DOIT} 33 | true 34 | 35 | 36 | echo "entweder" 37 | 38 | 39 | doit 40 | (Default) 41 | 42 | 43 | 44 | 45 | echo "immer da" 46 | 47 | 48 | ${DOIT} 49 | false 50 | 51 | 52 | echo "oder" 53 | 54 | 55 | clean 56 | false 57 | 58 | 59 | 60 | 61 | 62 | 63 | --------------------------------------------------------------------------------