├── src └── main │ ├── webapp │ └── version.txt │ ├── resources │ ├── hudson │ │ └── plugins │ │ │ └── antexec │ │ │ ├── AntExec │ │ │ ├── help-noAntcontrib.html │ │ │ ├── help-antOpts.html │ │ │ ├── help-scriptName.html │ │ │ ├── help-extendedScriptSource.html │ │ │ ├── help-scriptSource.html │ │ │ ├── help-properties.html │ │ │ ├── config.properties │ │ │ └── config.groovy │ │ │ └── Messages.properties │ └── index.jelly │ └── java │ └── hudson │ └── plugins │ └── antexec │ └── AntExec.java ├── .github ├── release-drafter.yml ├── CODEOWNERS ├── dependabot.yml └── workflows │ ├── cd.yml │ ├── jenkins-security-scan.yml │ ├── manual-build.yml │ └── codeql-analysis.yml ├── .mvn ├── maven.config └── extensions.xml ├── docs └── images │ ├── 05.Example1.png │ ├── 01.Add_buildstep.png │ ├── 02.New_AntExec_Step.png │ ├── 06.Example2-Validation.png │ ├── 03.New_AntExec_Step_Adv1.png │ └── 04.New_AntExec_Step_Adv2.png ├── .gitignore ├── Jenkinsfile ├── .gitattributes ├── LICENSE.txt ├── CHANGELOG.md ├── README.md └── pom.xml /src/main/webapp/version.txt: -------------------------------------------------------------------------------- 1 | ${pom.version} -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | _extends: .github -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @jenkinsci/antexec-plugin-developers 2 | -------------------------------------------------------------------------------- /.mvn/maven.config: -------------------------------------------------------------------------------- 1 | -Pconsume-incrementals 2 | -Pmight-produce-incrementals 3 | -Dchangelist.format=%d.v%s -------------------------------------------------------------------------------- /docs/images/05.Example1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/antexec-plugin/main/docs/images/05.Example1.png -------------------------------------------------------------------------------- /docs/images/01.Add_buildstep.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/antexec-plugin/main/docs/images/01.Add_buildstep.png -------------------------------------------------------------------------------- /docs/images/02.New_AntExec_Step.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/antexec-plugin/main/docs/images/02.New_AntExec_Step.png -------------------------------------------------------------------------------- /docs/images/06.Example2-Validation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/antexec-plugin/main/docs/images/06.Example2-Validation.png -------------------------------------------------------------------------------- /docs/images/03.New_AntExec_Step_Adv1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/antexec-plugin/main/docs/images/03.New_AntExec_Step_Adv1.png -------------------------------------------------------------------------------- /docs/images/04.New_AntExec_Step_Adv2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/antexec-plugin/main/docs/images/04.New_AntExec_Step_Adv2.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .settings/ 2 | .idea/ 3 | target/ 4 | work/ 5 | lib/ 6 | *.iml 7 | .project 8 | .classpath 9 | release.properties 10 | build_and_deploy.bat 11 | *.releaseBackup 12 | *.class 13 | *.hpi 14 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/antexec/AntExec/help-noAntcontrib.html: -------------------------------------------------------------------------------- 1 |
2 |

3 | Disabling usage of Ant-Contrib Tasks in this build step. 4 |

5 |
6 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "maven" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | - package-ecosystem: github-actions 8 | directory: / 9 | schedule: 10 | interval: daily -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/antexec/AntExec/help-antOpts.html: -------------------------------------------------------------------------------- 1 |
2 | If your build requires a custom ANT_OPTS, specify it 3 | here. Typically this may be used to specify java memory limits to use, for example -Xmx512m.
Note that other Ant 4 | options (such as -lib) should not be here. 5 |
-------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | /* 2 | See the documentation for more options: 3 | https://github.com/jenkins-infra/pipeline-library/ 4 | */ 5 | buildPlugin( 6 | forkCount: '1C', // Run a JVM per core in tests 7 | useContainerAgent: true, // Set to `false` if you need to use Docker for containerized tests 8 | configurations: [ 9 | [platform: 'linux', jdk: 21], 10 | [platform: 'windows', jdk: 17], 11 | ]) 12 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/antexec/AntExec/help-scriptName.html: -------------------------------------------------------------------------------- 1 |
2 | Here you can enter the name for your new script. The name will be also used for default Ant target. 3 | This build file will then have a name that differs from the default name, so it will not be overwritten 4 | by the upcoming build step and therefore it might be used repeatedly, or it can be included/imported. 5 |
-------------------------------------------------------------------------------- /.mvn/extensions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | io.jenkins.tools.incrementals 4 | git-changelist-maven-extension 5 | 1.13 6 | 7 | 8 | -------------------------------------------------------------------------------- /.github/workflows/cd.yml: -------------------------------------------------------------------------------- 1 | # Note: additional setup is required, see https://www.jenkins.io/redirect/continuous-delivery-of-plugins 2 | 3 | name: cd 4 | on: 5 | workflow_dispatch: 6 | check_run: 7 | types: 8 | - completed 9 | 10 | jobs: 11 | maven-cd: 12 | uses: jenkins-infra/github-reusable-workflows/.github/workflows/maven-cd.yml@v1 13 | secrets: 14 | MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }} 15 | MAVEN_TOKEN: ${{ secrets.MAVEN_TOKEN }} 16 | 17 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/antexec/AntExec/help-extendedScriptSource.html: -------------------------------------------------------------------------------- 1 |
2 | Into this field you can enter a code, you could not able to enter into the previous field, as it should not appear 3 | within the Ant target. The entries can be other targets, import/include tasks etc. With this extension you are able 4 | to create more complex Ant build file with just one limitation - the first field (textarea) must always be used 5 | for default Ant target. This field is optional. 6 |
-------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/antexec/AntExec/help-scriptSource.html: -------------------------------------------------------------------------------- 1 |
2 | Runs entered Apache Ant tasks as a build file with only one target, untill you write code into the "Extended script 3 | source", but the target created from this code will always be the default target of the created build file. 4 |

5 | The script will run with WORKSPACE as the current directory. Build will be considered as failure if any Ant task 6 | fails. You can use Ant-Contrib tasks 7 | (if it is enabled in global configuration). You need to use namespace "antcontrib" (example: "<antcontrib:if>"). 8 |
-------------------------------------------------------------------------------- /.github/workflows/jenkins-security-scan.yml: -------------------------------------------------------------------------------- 1 | name: Jenkins Security Scan 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 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 | -------------------------------------------------------------------------------- /.github/workflows/manual-build.yml: -------------------------------------------------------------------------------- 1 | name: manual-build 2 | on: 3 | workflow_dispatch: 4 | 5 | jobs: 6 | release: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Check out 10 | # https://github.com/actions/checkout 11 | uses: actions/checkout@v6 12 | with: 13 | fetch-depth: 0 14 | 15 | - name: Set up JDK 16 | # https://github.com/actions/setup-java 17 | uses: actions/setup-java@v5 18 | with: 19 | distribution: "temurin" 20 | java-version: "17" 21 | 22 | - name: Release 23 | # https://github.com/jenkins-infra/jenkins-maven-cd-action 24 | uses: jenkins-infra/jenkins-maven-cd-action@v1 25 | with: 26 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 27 | MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }} 28 | MAVEN_TOKEN: ${{ secrets.MAVEN_TOKEN }} -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/antexec/AntExec/help-properties.html: -------------------------------------------------------------------------------- 1 |
2 | Properties needed by your ant build can be specified here (in standard properties file format): 5 |
# comment
 6 | name1=value1
 7 | name2=$VAR2
 8 | 
9 | These are passed to Ant like "-Dname1=value1 -Dname2=value2". 10 | Always use $VAR style (even on Windows) for references to Jenkins-defined 11 | environment variables. On Windows, %VAR% style references may be used 12 | for environment variables that exist outside of Jenkins. 13 | Backslashes are used for escaping, so use \\ for a single backslash. 14 | Double quotes (") should be avoided, as ant on *nix wraps parameters in quotes 15 | quotes and runs them through eval, and Windows has its own issues 16 | with escaping.. in either case, use of quotes may result in build failure. 17 | To define an empty property, simply write varname= 18 |
-------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2011, Milos Svasek, Kohsuke Kawaguchi 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 13 | all 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 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /src/main/resources/index.jelly: -------------------------------------------------------------------------------- 1 | 2 | 25 | 26 |
27 | This plugin makes it possible to run Apache Ant code directly from Jenkins-CI 28 |
-------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ### Newer versions 4 | See [Release page at Jenkins Plugin Index](https://plugins.jenkins.io/antexec/releases/) 5 | 6 | 7 | ### 1.11 8 | Release date: _2015-08-18_ 9 | 10 | - Passing parameters and properties through the generated property file instead of command-line which caused problems (especially on Windows) 11 | - Changed core dependency from `1.480` to `1.596` 12 | - Updated dependency on "token-macro" plugin (1.10) 13 | - Dropped compatibility with Java 1.5 14 | 15 | ### 1.10 16 | Release date: _2013-10-31_ 17 | 18 | - Load environment variables with `` by default, so they are accessible via ${env.VARIABLE} 19 | - Fixed missing job options in command line properties 20 | 21 | ### 1.9 22 | Release date: _2013-07-15_ 23 | 24 | - Build files are now automatically deleted by default so you need to update job configuration if you want to keep them 25 | - Fixing upgrade issue with ant-contrib in version 1.8 26 | 27 | ### 1.8 28 | Release date: _2013-06-28_ 29 | 30 | - Remove archive copying of buildfile to job directory 31 | - Cleanup dependencies in pom.xml 32 | 33 | ### 1.7 34 | Release date: _2013-06-24_ 35 | 36 | - Added option to keep build files for each build step, it's deleted by default now 37 | - Added dependency on "ant" plugin (1.2) 38 | - Added dependency on "token-macro" plugin (1.7) 39 | - Option for disabling ant-contrib has been moved to build step configuration 40 | - Changed dependency to core 1.480 41 | 42 | ### 1.6 43 | Release date: _2012-08-28_ 44 | 45 | - Fixing typo in extendedScriptSource 46 | 47 | ### 1.5 48 | Release date: _2012-06-21_ 49 | 50 | - Fixing typo 51 | 52 | ### 1.4 53 | Release date: _2012-06-20_ 54 | 55 | - Fixing build file when extended script source is null 56 | 57 | ### 1.3 58 | Release date: _2012-06-06_ 59 | 60 | - First public release -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/antexec/AntExec/config.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi 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 13 | # all 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 21 | # THE SOFTWARE. 22 | 23 | Source\ description=See the list of Apache Ant core tasks, Ant-Contrib tasks and the list of, available environment variables. 24 | ScriptName\ description=You can specify script name if you want use them more than once or import it into another one. 25 | Extended\ source\ description=This is the extended code placed outside of the default ant target (see Script source). -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Jenkins AntExec Plugin 2 | 3 | This plugin makes it possible to run Apache Ant code directly from build steps of your Jenkins-CI. 4 | 5 | ## Features 6 | - Adding build step to execute Ant code 7 | - Bundled ant-contrib to support ant-contrib tasks (needs to be enable in global config) 8 | - Easy to write simple Ant build file directly into the build step 9 | - Ability to write the fully functional Ant build file directly into Jenkins as a build step 10 | - You can reuse the build file created by the build step 11 | - Supports multi-line parameters 12 | 13 | ## Some use cases 14 | - To do some platform independent tasks 15 | - To do some advanced build preparation steps 16 | - To write the custom Ant build file maintained by Jenkins 17 | - To maintain custom Ant build file when you don't have access into the VCS of the current project 18 | - To write Ant targets that use multi-line text parameters (currently not possible using the core Ant plugin) 19 | - And much more (wink) 20 | 21 | ## Support for multi-line text parameters 22 | If your job uses text parameters (as opposed to string parameters) and the parameter values contain newline characters, the core ant plugin fails with the following syntax error: 23 | 24 | ``` 25 | Building in workspace c:\svn\automation\baf 26 | baf $ cmd.exe /C '"ant.bat "-Dmulti_line_text=This is line 1 27 | This is line 2 28 | This is line3" usage && exit %%ERRORLEVEL%%"' 29 | The syntax of the command is incorrect. 30 | Build step 'Invoke Ant' marked build as failure 31 | Finished: FAILURE 32 | ``` 33 | 34 | The problem is that parameters are passed verbatim to the command line, and if they contain any line breaks, cmd.exe will discard everything after the first line break, inevitably leading to a syntax error. The AntExec plugin gets around this problem by saving the build parameters into a .properties file on the fly and loading this file into the Ant session automatically. This also means that you can no longer verify in the build log the list of parameters that were handed down to Ant. If you need this (presumably for debugging purposes) then check the Keep buildfile check box, which will cause the plugin to retain the build file, as well as the parameter properties file, in the workspace of the plugin. 35 | 36 | ## Usage Screenshots 37 | 38 | ### Adding new build step 39 | ![](docs/images/01.Add_buildstep.png) 40 | 41 | ### New AntExec build step 42 | ![](docs/images/02.New_AntExec_Step.png) 43 | 44 | ### New AntExec build step with 1st level of advanced options 45 | ![](docs/images/03.New_AntExec_Step_Adv1.png) 46 | 47 | ### New AntExec build step with 2nd level of advanced options 48 | ![](docs/images/04.New_AntExec_Step_Adv2.png) 49 | 50 | ### Code Example 51 | ![](docs/images/05.Example1.png) 52 | 53 | ### Code Validation Example 54 | ![](docs/images/06.Example2-Validation.png) 55 | 56 | 57 | For release history, please see [release page](https://plugins.jenkins.io/antexec/releases/). -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/antexec/Messages.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2009, Milos Svasek, Kohsuke Kawaguchi 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 13 | # all 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 21 | # THE SOFTWARE. 22 | 23 | AntExec.DisplayName=Execute Apache Ant 24 | AntExec.ExecFailed=command execution failed. 25 | AntExec.SetAntHome=If you use "(Default)" Ant installation, please set Ant home directory\! 26 | AntExec.NotADirectory={0} is not a directory 27 | AntExec.NotAntDirectory={0} doesn''t look like an Ant directory 28 | AntExec.ProjectConfigNeeded= Maybe you need to set environment variable ANT_HOME, or set its correct value in job configuration. 29 | AntExec.ExecutableNotFound=Cannot find executable from the choosen Ant installation "{0}" 30 | AntExec.AntInstallationDefault=Ant Installation is "(Default)", so Ant installation is not set! 31 | 32 | AntExec.AntHomeValidation=Please set ANT_HOME directory! 33 | AntExec.UseAntCoreTasksOnly=Please use only the core Apache Ant tasks! Ant-contrib is not enabled in global settings. 34 | AntExec.UseAntContribTasks=You can use core Apache Ant and Ant-contrib tasks! Ant-contrib is enabled in global settings. 35 | 36 | AntExec.AntHomeEnvVarFound=Found usable ANT_HOME in environment: "{0}" 37 | AntExec.AntHomeEnvVarNotFound=Usable ANT_HOME has not been found in environment variables. 38 | AntExec.AntHomeReplacing=You have specified ANT_HOME in setup of build step. Forcing it to "{1}" from "{0}" 39 | AntExec.EnvironmentAdded=WARNING\: Environment variable {0} has been extended with "{1}" 40 | AntExec.EnvironmentChanged=WARNING: Environment variable {0} has been changed to: "{1}" 41 | 42 | AntExec.DebugScriptSourceFieldBegin=Content of scriptSource text area --- begin --- 43 | AntExec.DebugScriptSourceFieldEnd=Content of scriptSource text area ---- end ---- 44 | AntExec.DebugPropertiesFieldBegin=Content of properties text area --- begin --- 45 | AntExec.DebugPropertiesFieldEnd=Content of properties text area ---- end ---- -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | name: "CodeQL" 7 | 8 | on: 9 | push: 10 | branches: [main] 11 | pull_request: 12 | # The branches below must be a subset of the branches above 13 | branches: [main] 14 | schedule: 15 | - cron: "0 13 * * 6" 16 | 17 | jobs: 18 | analyze: 19 | name: Analyze 20 | runs-on: ubuntu-latest 21 | 22 | strategy: 23 | fail-fast: false 24 | matrix: 25 | # Override automatic language detection by changing the below list 26 | # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python'] 27 | language: ["java"] 28 | # Learn more... 29 | # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection 30 | 31 | steps: 32 | - name: Checkout repository 33 | # https://github.com/actions/checkout 34 | uses: actions/checkout@v6 35 | with: 36 | # We must fetch at least the immediate parents so that if this is 37 | # a pull request then we can checkout the head. 38 | fetch-depth: 2 39 | 40 | - name: Set up JDK 41 | # https://github.com/actions/setup-java 42 | uses: actions/setup-java@v5 43 | with: 44 | distribution: "temurin" 45 | java-version: "17" 46 | 47 | - name: Set up Maven 48 | # https://github.com/stCarolas/setup-maven 49 | uses: stCarolas/setup-maven@v5 50 | with: 51 | maven-version: 3.9.9 52 | 53 | # Initializes the CodeQL tools for scanning. 54 | - name: Initialize CodeQL 55 | # https://github.com/github/codeql-action 56 | uses: github/codeql-action/init@v4 57 | with: 58 | languages: ${{ matrix.language }} 59 | # If you wish to specify custom queries, you can do so here or in a config file. 60 | # By default, queries listed here will override any specified in a config file. 61 | # Prefix the list here with "+" to use these queries and those in the config file. 62 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 63 | 64 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 65 | # If this step fails, then you should remove it and run the build manually (see below) 66 | - name: Autobuild 67 | uses: github/codeql-action/autobuild@v4 68 | 69 | # ℹ️ Command-line programs to run using the OS shell. 70 | # 📚 https://git.io/JvXDl 71 | 72 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 73 | # and modify them (or add more) to build your code if your project 74 | # uses a compiled language 75 | 76 | #- run: | 77 | # make bootstrap 78 | # make release 79 | 80 | - name: Perform CodeQL Analysis 81 | uses: github/codeql-action/analyze@v4 82 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/antexec/AntExec/config.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2011, Milos Svasek 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 NON INFRINGEMENT. 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 hudson.plugins.antexec.AntExec 26 | f = namespace(lib.FormTagLib) 27 | 28 | f.entry(title: _("Script source"), field: "scriptSource", class: "fixed-width", description: _("Source description", rootURL)) { 29 | f.textarea() 30 | } 31 | if (descriptor.installations.length != 0) { 32 | f.entry(title: _("Ant Version")) { 33 | select(class: "setting-input", name: "instance.antName") { 34 | option(value: "(Default)", _("Default")) 35 | descriptor.installations.each { 36 | f.option(selected: it.name == instance?.antName, value: it.name, it.name) 37 | } 38 | } 39 | } 40 | } 41 | f.advanced { 42 | f.entry(title: _("Script name"), field: "scriptName", description: _("ScriptName description")) { 43 | f.expandableTextbox() 44 | } 45 | f.entry(title: _("Keep buildfile"), field: "keepBuildfile") { 46 | f.checkbox() 47 | f.description {_("Do not delete build file so you can use it in one of the next build step again.")} 48 | } 49 | f.entry(title: _("Extended script source"), field: "extendedScriptSource", class: "fixed-width", description: _("Extended source description")) { 50 | f.textarea() 51 | } 52 | f.entry(title: _("Properties"), field: "properties", class: "fixed-width") { 53 | f.expandableTextbox() 54 | } 55 | f.advanced { 56 | f.entry(title: _("Java Options"), field: "antOpts") { 57 | f.expandableTextbox() 58 | } 59 | f.entry(title: _("Verbose mode"), field: "verbose") { 60 | f.checkbox() 61 | f.description {_("Enabling verbose output")} 62 | } 63 | f.entry(title: _("Emacs mode"), field: "emacs") { 64 | f.checkbox() 65 | f.description {_("Enabling logging information without adornments")} 66 | } 67 | f.entry(title: _("Do not use Ant-Contrib"), field: "noAntcontrib") { 68 | f.checkbox() 69 | f.description {_("Disabling usage of Ant-Contrib Tasks in this build step.")} 70 | } 71 | } 72 | } -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.jenkins-ci.plugins 7 | plugin 8 | 5.28 9 | 10 | 11 | antexec 12 | ${changelist} 13 | hpi 14 | 15 | 999999-SNAPSHOT 16 | jenkinsci/${project.artifactId}-plugin 17 | UTF-8 18 | 19 | 2.479 20 | ${jenkins.baseline}.1 21 | 22 | AntExec 23 | Adds new build step for running directly written Apache Ant code 24 | https://github.com/jenkinsci/${project.artifactId}-plugin 25 | 26 | 27 | 28 | svasek 29 | Milos Svasek 30 | Milos@Svasek.net 31 | +1 32 | 33 | 34 | 35 | 36 | 37 | The MIT license 38 | All source code is under the MIT license. 39 | https://opensource.org/licenses/MIT 40 | repo 41 | 42 | 43 | 44 | 45 | scm:git:https://github.com/${gitHubRepo}.git 46 | scm:git:https://github.com/${gitHubRepo}.git 47 | https://github.com/${gitHubRepo} 48 | ${scmTag} 49 | 50 | 51 | 52 | 53 | 54 | io.jenkins.tools.bom 55 | bom-${jenkins.baseline}.x 56 | 5054.v620b_5d2b_d5e6 57 | import 58 | pom 59 | 60 | 61 | org.jenkins-ci.tools 62 | maven-hpi-plugin 63 | 3.1773.v3646231d4c22 64 | 65 | 66 | 67 | 68 | 69 | 70 | org.jenkins-ci.plugins 71 | ant 72 | 73 | 74 | org.jenkins-ci.plugins 75 | token-macro 76 | 77 | 78 | 79 | 80 | 81 | 82 | src/main/resources 83 | false 84 | 85 | 86 | src/main/webapp 87 | ${project.build.directory}/${project.artifactId} 88 | true 89 | 90 | version.txt 91 | 92 | 93 | 94 | 95 | 96 | org.apache.maven.plugins 97 | maven-dependency-plugin 98 | 99 | 100 | copy 101 | prepare-package 102 | 103 | copy 104 | 105 | 106 | 107 | 108 | ant-contrib 109 | ant-contrib 110 | 1.0b3 111 | jar 112 | ${project.build.directory}/${project.artifactId}/META-INF/lib 113 | 114 | ant-contrib.jar 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | org.jenkins-ci.tools 123 | maven-hpi-plugin 124 | 125 | 126 | maven-release-plugin 127 | 128 | deploy 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | repo.jenkins-ci.org 137 | https://repo.jenkins-ci.org/public/ 138 | 139 | 140 | 141 | 142 | repo.jenkins-ci.org 143 | https://repo.jenkins-ci.org/public/ 144 | 145 | 146 | 147 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/antexec/AntExec.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2011, Milos Svasek, Kohsuke Kawaguchi, etc. 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 NON INFRINGEMENT. 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 hudson.plugins.antexec; 25 | 26 | import hudson.*; 27 | import hudson.model.*; 28 | import hudson.tasks.Ant; 29 | import hudson.tasks.BuildStepDescriptor; 30 | import hudson.tasks.Builder; 31 | import hudson.tasks._ant.AntConsoleAnnotator; 32 | import hudson.util.ArgumentListBuilder; 33 | import hudson.util.FormValidation; 34 | import jenkins.model.Jenkins; 35 | 36 | import org.jenkinsci.plugins.tokenmacro.MacroEvaluationException; 37 | import org.jenkinsci.plugins.tokenmacro.TokenMacro; 38 | import org.kohsuke.stapler.DataBoundConstructor; 39 | import org.kohsuke.stapler.QueryParameter; 40 | import org.xml.sax.InputSource; 41 | import org.xml.sax.SAXException; 42 | import org.xml.sax.XMLReader; 43 | import org.kohsuke.accmod.Restricted; 44 | import org.kohsuke.accmod.restrictions.NoExternalUse; 45 | import org.kohsuke.stapler.interceptor.RequirePOST; 46 | import javax.xml.parsers.SAXParserFactory; 47 | import javax.xml.parsers.ParserConfigurationException; 48 | import java.io.ByteArrayOutputStream; 49 | import java.io.ByteArrayInputStream; 50 | import java.io.InputStreamReader; 51 | import java.io.IOException; 52 | import java.util.ArrayList; 53 | import java.util.Properties; 54 | import java.util.List; 55 | import java.util.logging.Level; 56 | import java.util.logging.Logger; 57 | 58 | /** 59 | * Invokes the Apache Ant script entered on the hudson build configuration. 60 | * 61 | * @author Milos Svasek 62 | */ 63 | @SuppressWarnings("ALL") 64 | public class AntExec extends Builder { 65 | private static final String myName = "antexec"; 66 | protected static final String buildXml = myName + "_build.xml"; 67 | private final String scriptSource; 68 | private final String extendedScriptSource; 69 | private final String scriptName; 70 | private final String properties; 71 | private final String antOpts; 72 | private final Boolean keepBuildfile; 73 | private final Boolean verbose; 74 | private final Boolean emacs; 75 | private final Boolean noAntcontrib; 76 | private final String antName; 77 | 78 | // Fields in config.groovy must match the parameter names in the "DataBoundConstructor" 79 | @SuppressWarnings("ALL") 80 | @DataBoundConstructor 81 | public AntExec(String scriptSource, String extendedScriptSource, String scriptName, String properties, String antName, String antOpts, Boolean keepBuildfile, Boolean verbose, Boolean emacs, Boolean noAntcontrib) { 82 | this.scriptSource = scriptSource; 83 | this.extendedScriptSource = extendedScriptSource; 84 | this.scriptName = scriptName; 85 | this.properties = properties; 86 | this.keepBuildfile = keepBuildfile; 87 | this.antName = antName; 88 | this.antOpts = antOpts; 89 | this.verbose = verbose; 90 | this.emacs = emacs; 91 | this.noAntcontrib = noAntcontrib; 92 | } 93 | 94 | /** 95 | * Returns content of text area with script source from job configuration screen 96 | * 97 | * @return String scriptSource 98 | */ 99 | public String getScriptSource() { 100 | return scriptSource; 101 | } 102 | 103 | /** 104 | * Returns content of text area with script source from job configuration screen 105 | * 106 | * @return String extendedScriptSource 107 | */ 108 | public String getExtendedScriptSource() { 109 | return extendedScriptSource; 110 | } 111 | 112 | 113 | /** 114 | * Returns content of text area with script name from job configuration screen 115 | * 116 | * @return String scriptName 117 | */ 118 | public String getScriptName() { 119 | return scriptName; 120 | } 121 | 122 | /** 123 | * Returns content of text field with properties from job configuration screen 124 | * 125 | * @return String properties 126 | */ 127 | public String getProperties() { 128 | return properties; 129 | } 130 | 131 | /** 132 | * Returns content of text field with java/ant options from job configuration screen. 133 | * It will be used for ANT_OPTS environment variable 134 | * 135 | * @return String antOpts 136 | */ 137 | public String getAntOpts() { 138 | return antOpts; 139 | } 140 | 141 | /** 142 | * Returns checkbox boolean from job configuration screen 143 | * 144 | * @return Boolean keepBuildfile 145 | */ 146 | public Boolean getKeepBuildfile() { 147 | return keepBuildfile; 148 | } 149 | 150 | /** 151 | * Returns checkbox boolean from job configuration screen 152 | * 153 | * @return Boolean verbose 154 | */ 155 | public Boolean getVerbose() { 156 | return verbose; 157 | } 158 | 159 | /** 160 | * Returns checkbox boolean from job configuration screen 161 | * 162 | * @return Boolean emacs 163 | */ 164 | public Boolean getEmacs() { 165 | return emacs; 166 | } 167 | 168 | /** 169 | * Returns checkbox boolean from job configuration screen 170 | * 171 | * @return Boolean noAntcontrib 172 | */ 173 | public Boolean getNoAntcontrib() { 174 | return noAntcontrib; 175 | } 176 | 177 | /** 178 | * @return Ant to invoke, or null to invoke the default one. 179 | */ 180 | Ant.AntInstallation getAnt() { 181 | for (Ant.AntInstallation i : getDescriptor().getInstallations()) { 182 | if (antName != null && antName.equals(i.getName())) 183 | return i; 184 | } 185 | return null; 186 | } 187 | 188 | @Override 189 | public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws IOException, InterruptedException { 190 | ArgumentListBuilder args = new ArgumentListBuilder(); 191 | String scriptSourceResolved = scriptSource; 192 | String extendedScriptSourceResolved = extendedScriptSource; 193 | 194 | FilePath propertyFile = null; 195 | if ((properties != null && properties.length() > 0 && !properties.equals("")) || (!build.getBuildVariables().isEmpty())) { 196 | Properties myMergedProperties = new Properties(); 197 | // Add build properties 198 | myMergedProperties.putAll(build.getBuildVariables()); 199 | // Add properties from text field "Properties" on job configuration screen 200 | byte[] bytes = properties.getBytes("UTF-8"); 201 | ByteArrayInputStream bais = new ByteArrayInputStream(bytes); 202 | InputStreamReader isr = new InputStreamReader(bais, "UTF-8"); 203 | myMergedProperties.load(isr); 204 | // Create property file 205 | propertyFile = makePropertyFile(scriptName, build, myMergedProperties); 206 | } 207 | 208 | try { 209 | //Resolve all the envirionment variables and properties before creating the build.xml 210 | scriptSourceResolved = TokenMacro.expandAll(build, listener, scriptSource); 211 | extendedScriptSourceResolved = TokenMacro.expandAll(build, listener, extendedScriptSource); 212 | } catch (MacroEvaluationException ex) { 213 | Logger.getLogger(AntExec.class.getName()).log(Level.WARNING, null, ex); 214 | } 215 | EnvVars env = build.getEnvironment(listener); 216 | env.overrideAll(build.getBuildVariables()); 217 | 218 | Ant.AntInstallation ai = getAnt(); 219 | if (ai == null) { 220 | args.add(launcher.isUnix() ? "ant" : "ant.bat"); 221 | } else { 222 | Node node = Computer.currentComputer().getNode(); 223 | if (node == null) { 224 | throw new AbortException("Cannot get installation for node, since it is not online"); 225 | } 226 | ai = ai.forNode(node, listener); 227 | ai = ai.forEnvironment(env); 228 | String exe = ai.getExecutable(launcher); 229 | if (exe == null) { 230 | throw new AbortException("Cannot find executable from the chosen Ant installation."); 231 | } 232 | args.add(exe); 233 | } 234 | 235 | //Create Ant build.xml file 236 | FilePath buildFile = makeBuildFile(scriptName, scriptSourceResolved, extendedScriptSourceResolved, build); 237 | 238 | //Added build file to the command line 239 | args.add("-file", buildFile.getName()); 240 | 241 | 242 | if (ai != null) 243 | ai.buildEnvVars(env); 244 | if (antOpts != null && antOpts.length() > 0 && !antOpts.equals("")) { 245 | env.put("ANT_OPTS", env.expand(antOpts)); 246 | } 247 | 248 | //Get and prepare ant-contrib.jar 249 | FilePath antLibDir = null; 250 | if (noAntcontrib == null || !noAntcontrib) { 251 | if (verbose != null && verbose) listener.getLogger().println(Messages.AntExec_UseAntContribTasks()); 252 | 253 | FilePath ws = build.getWorkspace(); 254 | if (ws == null) throw new AbortException("Cannot get Workspace for node, since it is not online"); 255 | 256 | antLibDir = new FilePath(ws, "antlib"); 257 | if (!antLibDir.exists()) { 258 | FilePath antContribJar = new FilePath(antLibDir, "ant-contrib.jar"); 259 | FilePath antContribJarOnMaster = new FilePath(Jenkins.get().getRootPath(), "plugins/antexec/META-INF/lib/ant-contrib.jar"); 260 | antContribJar.copyFrom(antContribJarOnMaster.toURI().toURL()); 261 | } 262 | args.add("-lib", antLibDir.getName()); 263 | } else { 264 | if (verbose != null && verbose) listener.getLogger().println(Messages.AntExec_UseAntCoreTasksOnly()); 265 | } 266 | 267 | //Add Ant option: -verbose 268 | if (verbose != null && verbose) args.add("-verbose"); 269 | 270 | //Add Ant option: -emacs 271 | if (emacs != null && emacs) args.add("-emacs"); 272 | 273 | //Fixing command line for windows 274 | if (!launcher.isUnix()) { 275 | args = args.toWindowsCommand(); 276 | // For some reason, ant on windows rejects empty parameters but unix does not. 277 | // Add quotes for any empty parameter values: 278 | List newArgs = new ArrayList(args.toList()); 279 | newArgs.set(newArgs.size() - 1, newArgs.get(newArgs.size() - 1).replaceAll("(?<= )(-D[^\" ]+)= ", "$1=\"\" ")); 280 | args = new ArgumentListBuilder(newArgs.toArray(new String[newArgs.size()])); 281 | } 282 | 283 | //Content of scriptSourceResolved and properties (only if verbose is true 284 | if (verbose != null && verbose) { 285 | listener.getLogger().println(); 286 | listener.getLogger().println(Messages.AntExec_DebugScriptSourceFieldBegin()); 287 | listener.getLogger().println(scriptSourceResolved); 288 | listener.getLogger().println(Messages.AntExec_DebugScriptSourceFieldEnd()); 289 | listener.getLogger().println(); 290 | listener.getLogger().println(Messages.AntExec_DebugPropertiesFieldBegin()); 291 | listener.getLogger().println(properties); 292 | listener.getLogger().println(Messages.AntExec_DebugPropertiesFieldEnd()); 293 | listener.getLogger().println(); 294 | } 295 | 296 | long startTime = System.currentTimeMillis(); 297 | try { 298 | AntConsoleAnnotator aca = new AntConsoleAnnotator(listener.getLogger(), build.getCharset()); 299 | int r; 300 | try { 301 | r = launcher.launch().cmds(args).envs(env).stdout(aca).pwd(buildFile.getParent()).join(); 302 | } finally { 303 | aca.forceEol(); 304 | //After the ant script has been executed, we delete the build.xml. 305 | //The plugin is a way to run an Ant Script from a small source code, we shoudn't keep the antexec_build.xml 306 | if (keepBuildfile == null || !keepBuildfile) { 307 | if (propertyFile != null && propertyFile.exists()) { 308 | boolean deleteResponse1 = propertyFile.delete(); 309 | if (!deleteResponse1) 310 | listener.getLogger().println("The temporary property file coudn't be deleted"); 311 | } 312 | boolean deleteResponse2 = buildFile.delete(); 313 | if (!deleteResponse2) 314 | listener.getLogger().println("The temporary Ant Build Script coudn't be deleted"); 315 | 316 | //if (noAntcontrib == null || !noAntcontrib); 317 | // antLibDir.deleteRecursive(); 318 | } 319 | } 320 | return r == 0; 321 | } catch (IOException e) { 322 | Util.displayIOException(e, listener); 323 | 324 | String errorMessage = "command execution failed."; 325 | if (ai == null && (System.currentTimeMillis() - startTime) < 1000) { 326 | if (getDescriptor().getInstallations() == null) 327 | // looks like the user didn't configure any Ant installation 328 | errorMessage += " Maybe you need to configure where your Ant installations are?"; 329 | else 330 | // There are Ant installations configured but the project didn't pick it 331 | errorMessage += " Maybe you need to configure the job to choose one of your Ant installations?"; 332 | } 333 | e.printStackTrace(listener.fatalError(errorMessage)); 334 | return false; 335 | } 336 | } 337 | 338 | @Override 339 | public DescriptorImpl getDescriptor() { 340 | return (DescriptorImpl) super.getDescriptor(); 341 | } 342 | 343 | @SuppressWarnings("UnusedDeclaration") 344 | @Extension 345 | public static final class DescriptorImpl extends BuildStepDescriptor { 346 | 347 | @SuppressWarnings("UnusedDeclaration") 348 | public DescriptorImpl() { 349 | super(AntExec.class); 350 | load(); 351 | } 352 | 353 | // for compatibility reasons, the persistence is done by Ant.DescriptorImpl 354 | public Ant.AntInstallation[] getInstallations() { 355 | return Jenkins.get().getDescriptorByType(Ant.DescriptorImpl.class).getInstallations(); 356 | } 357 | 358 | //Check if entered script source is wellformed xml document 359 | @RequirePOST 360 | @Restricted(NoExternalUse.class) 361 | public FormValidation doCheckScriptSource(@QueryParameter String value) throws IOException, ParserConfigurationException, SAXException { 362 | // Check if the user has the necessary permissions 363 | Jenkins.get().checkPermission(Jenkins.ADMINISTER); 364 | 365 | String xmlContent = makeBuildFileXml("", value, "test_script"); 366 | try { 367 | SAXParserFactory factory = SAXParserFactory.newInstance(); 368 | factory.setFeature("http://xml.org/sax/features/external-general-entities", false); 369 | factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); 370 | factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); 371 | XMLReader reader = factory.newSAXParser().getXMLReader(); 372 | reader.parse(new InputSource(new ByteArrayInputStream(xmlContent.getBytes("UTF-8")))); 373 | return FormValidation.ok(); 374 | } catch (SAXException sax) { 375 | return FormValidation.error("ERROR: " + sax.getLocalizedMessage()); 376 | } 377 | } 378 | 379 | //Check if entered extended script source is wellformed xml document 380 | @SuppressWarnings("unused") 381 | private FormValidation doCheckExtendedScriptSource(@QueryParameter String value) throws IOException, ParserConfigurationException { 382 | String xmlContent = makeBuildFileXml(value, "", "test_script"); 383 | try { 384 | SAXParserFactory factory = SAXParserFactory.newInstance(); 385 | factory.setFeature("http://xml.org/sax/features/external-general-entities", false); 386 | factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); 387 | factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); 388 | XMLReader reader = factory.newSAXParser().getXMLReader(); 389 | reader.parse(new InputSource(new ByteArrayInputStream(xmlContent.getBytes("UTF-8")))); 390 | return FormValidation.ok(); 391 | } catch (SAXException sax) { 392 | return FormValidation.error("ERROR: " + sax.getLocalizedMessage()); 393 | } 394 | } 395 | 396 | @SuppressWarnings("rawtypes") 397 | public boolean isApplicable(Class aClass) { 398 | // indicates that this builder can be used with all kinds of project types 399 | return true; 400 | } 401 | 402 | public String getDisplayName() { 403 | return Messages.AntExec_DisplayName(); 404 | } 405 | } 406 | 407 | static String makeBuildFileXml(String scriptSource, String extendedScriptSource, String myScriptName) { 408 | StringBuilder sb = new StringBuilder(); 409 | sb.append("\n"); 410 | sb.append("\n\n"); 411 | sb.append("\n"); 412 | sb.append("\n\n"); 413 | sb.append("\n"); 414 | sb.append("\n\n"); 415 | sb.append("\n"); 416 | sb.append("\n"); 417 | sb.append(scriptSource); 418 | sb.append("\n\n"); 419 | sb.append("\n"); 420 | if (extendedScriptSource != null && extendedScriptSource.length() > 0 && !extendedScriptSource.equals("")) { 421 | sb.append("\n"); 422 | sb.append(extendedScriptSource); 423 | sb.append("\n\n"); 424 | } 425 | sb.append("\n"); 426 | return sb.toString(); 427 | } 428 | 429 | static FilePath makeBuildFile(String scriptName, String targetSource, String extendedScriptSource, AbstractBuild build) throws IOException, InterruptedException { 430 | String myScriptName = buildXml; 431 | if (scriptName != null && scriptName.length() > 0 && !scriptName.equals("")) { 432 | myScriptName = scriptName; 433 | } 434 | 435 | FilePath ws = build.getWorkspace(); 436 | if (ws == null) throw new AbortException("Cannot get Workspace for node, since it is not online"); 437 | FilePath buildFile = new FilePath(ws, myScriptName); 438 | 439 | buildFile.write(makeBuildFileXml(targetSource, extendedScriptSource, myScriptName), null); 440 | return buildFile; 441 | } 442 | 443 | static FilePath makePropertyFile(String scriptName, AbstractBuild build, Properties buildProperties) throws IOException, InterruptedException { 444 | String myScriptName = buildXml; 445 | if (scriptName != null && scriptName.length() > 0 && !scriptName.equals("")) { 446 | myScriptName = scriptName; 447 | } 448 | 449 | FilePath ws = build.getWorkspace(); 450 | if (ws == null) throw new AbortException("Cannot get Workspace for node, since it is not online"); 451 | FilePath propertyFile = new FilePath(ws, myScriptName + ".properties"); 452 | 453 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 454 | buildProperties.store(baos, "Stored by AntExec Jenkins plugin"); 455 | propertyFile.write(baos.toString("UTF-8"), "UTF-8"); 456 | return propertyFile; 457 | } 458 | 459 | } --------------------------------------------------------------------------------