├── 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 |
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 | 
40 |
41 | ### New AntExec build step
42 | 
43 |
44 | ### New AntExec build step with 1st level of advanced options
45 | 
46 |
47 | ### New AntExec build step with 2nd level of advanced options
48 | 
49 |
50 | ### Code Example
51 | 
52 |
53 | ### Code Validation Example
54 | 
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 extends AbstractProject> 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 | }
--------------------------------------------------------------------------------