Use yaml local tags to support including files
Add support for local tags which are application specific to allow including of other yaml files or code from scripts. Allows for code to be maintained and tested as seperate files, as well as reduces duplication of yaml code that cannot be macro'ed or easily templated by including it from a common file. Adds support for the following tags: 'include' - load file as yaml code 'include-raw' - load file as data (for scripts) 'include-raw-escaped' - load file as data with escaping braces '{}' as default for use with job-templates Use configuration file options to provide a search path for the files. - Test behaviour of yaml tags independent of any XML generation by comparing json result of yaml parsing to verify that certain tags do/don't recall the yaml.load() method. - Add examples for the include tags via addition tests for YamlParser class Inspired by http://stackoverflow.com/questions/528281/how-can-i-include-an-yaml-file-inside-another Change-Id: Ib90a07043112d4739d6529ceddbc9817668bcec0
This commit is contained in:
parent
18a07f1077
commit
3e3996d32a
@ -302,6 +302,12 @@ For example:
|
||||
.. literalinclude:: /../../tests/yamlparser/fixtures/custom_distri.yaml
|
||||
|
||||
|
||||
Custom Yaml Tags
|
||||
----------------
|
||||
|
||||
.. automodule:: jenkins_jobs.local_yaml
|
||||
|
||||
|
||||
Modules
|
||||
-------
|
||||
|
||||
|
@ -65,6 +65,11 @@ job_builder section
|
||||
When this option is set to True, that behavior changes and it will only
|
||||
overwrite the description if you specified it in the yaml. False by default.
|
||||
|
||||
**include_path**
|
||||
(Optional) Can be set to a ':' delimited list of paths, which jenkins
|
||||
job builder will search for any files specified by the custom application
|
||||
yaml tags 'include', 'include-raw' and 'include-raw-escaped'.
|
||||
|
||||
jenkins section
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
[job_builder]
|
||||
ignore_cache=True
|
||||
keep_descriptions=False
|
||||
include_path=.:scripts:~/git/
|
||||
|
||||
[jenkins]
|
||||
user=jenkins
|
||||
|
@ -31,6 +31,7 @@ import copy
|
||||
import itertools
|
||||
import fnmatch
|
||||
from jenkins_jobs.errors import JenkinsJobsException
|
||||
import local_yaml
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
MAGIC_MANAGE_STRING = "<!-- Managed by Jenkins Job Builder -->"
|
||||
@ -122,9 +123,15 @@ class YamlParser(object):
|
||||
self.jobs = []
|
||||
self.config = config
|
||||
self.registry = ModuleRegistry(self.config)
|
||||
self.path = ["."]
|
||||
if self.config:
|
||||
if config.has_section('job_builder') and \
|
||||
config.has_option('job_builder', 'include_path'):
|
||||
self.path = config.get('job_builder',
|
||||
'include_path').split(':')
|
||||
|
||||
def parse_fp(self, fp):
|
||||
data = yaml.load(fp)
|
||||
data = local_yaml.load(fp, search_path=self.path)
|
||||
if data:
|
||||
if not isinstance(data, list):
|
||||
raise JenkinsJobsException(
|
||||
|
159
jenkins_jobs/local_yaml.py
Normal file
159
jenkins_jobs/local_yaml.py
Normal file
@ -0,0 +1,159 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright (C) 2013 Hewlett-Packard.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
# Provides local yaml parsing classes and extend yaml module
|
||||
|
||||
"""Custom application specific yamls tags are supported to provide
|
||||
enhancements when reading yaml configuration.
|
||||
|
||||
These allow inclusion of arbitrary files as a method of having blocks of data
|
||||
managed separately to the yaml job configurations. A specific usage of this is
|
||||
inlining scripts contained in separate files, although such tags may also be
|
||||
used to simplify usage of macros or job templates.
|
||||
|
||||
The tag ``!include`` will treat the following string as file which should be
|
||||
parsed as yaml configuration data.
|
||||
|
||||
Example:
|
||||
|
||||
.. literalinclude:: /../../tests/localyaml/fixtures/include001.yaml
|
||||
|
||||
|
||||
The tag ``!include-raw`` will treat the following file as a data blob, which
|
||||
should be read into the calling yaml construct without any further parsing.
|
||||
Any data in a file included through this tag, will be treated as string data.
|
||||
|
||||
Example:
|
||||
|
||||
.. literalinclude:: /../../tests/localyaml/fixtures/include-raw001.yaml
|
||||
|
||||
|
||||
The tag ``!include-raw-escape`` treats the given file as a data blob, which
|
||||
should be escaped before being read in as string data. This allows
|
||||
job-templates to use this tag to include scripts from files without
|
||||
needing to escape braces in the original file.
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
.. literalinclude::
|
||||
/../../tests/localyaml/fixtures/include-raw-escaped001.yaml
|
||||
|
||||
"""
|
||||
|
||||
import functools
|
||||
import logging
|
||||
import re
|
||||
import os
|
||||
import yaml
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class LocalLoader(yaml.Loader):
|
||||
"""Subclass for yaml.Loader which handles the local tags 'include',
|
||||
'include-raw' and 'include-raw-escaped' to specify a file to include data
|
||||
from and whether to parse it as additional yaml, treat it as a data blob
|
||||
or additionally escape the data contained. These are specified in yaml
|
||||
files by "!include path/to/file.yaml".
|
||||
|
||||
Constructor access a list of search paths to look under for the given
|
||||
file following each tag, taking the first match found. Search path by
|
||||
default will include the same directory as the yaml file and the current
|
||||
working directory.
|
||||
|
||||
|
||||
Loading::
|
||||
|
||||
# use the load function provided in this module
|
||||
import local_yaml
|
||||
data = local_yaml.load(open(fn))
|
||||
|
||||
|
||||
# Loading by providing the alternate class to the default yaml load
|
||||
from local_yaml import LocalLoader
|
||||
data = yaml.load(open(fn), LocalLoader)
|
||||
|
||||
# Loading with a search path
|
||||
from local_yaml import LocalLoader
|
||||
import functools
|
||||
data = yaml.load(open(fn), functools.partial(LocalLoader,
|
||||
search_path=['path']))
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
# make sure to pop off any local settings before passing to
|
||||
# the parent constructor as any unknown args may cause errors.
|
||||
self.search_path = set()
|
||||
if 'search_path' in kwargs:
|
||||
for p in kwargs.pop('search_path'):
|
||||
logger.debug("Adding '{0}' to search path for include tags"
|
||||
.format(p))
|
||||
self.search_path.add(os.path.normpath(p))
|
||||
|
||||
if 'escape_callback' in kwargs:
|
||||
self._escape = kwargs.pop('escape_callback')
|
||||
|
||||
super(LocalLoader, self).__init__(*args, **kwargs)
|
||||
|
||||
# Add tag constructors
|
||||
self.add_constructor('!include', self._include_tag)
|
||||
self.add_constructor('!include-raw', self._include_raw_tag)
|
||||
self.add_constructor('!include-raw-escape',
|
||||
self._include_raw_escape_tag)
|
||||
|
||||
if isinstance(self.stream, file):
|
||||
self.search_path.add(os.path.normpath(
|
||||
os.path.dirname(self.stream.name)))
|
||||
self.search_path.add(os.path.normpath(os.path.curdir))
|
||||
|
||||
def _find_file(self, filename):
|
||||
for dirname in self.search_path:
|
||||
candidate = os.path.expanduser(os.path.join(dirname, filename))
|
||||
if os.path.isfile(candidate):
|
||||
logger.info("Including file '{0}' from path '{0}'"
|
||||
.format(filename, dirname))
|
||||
return candidate
|
||||
return filename
|
||||
|
||||
def _include_tag(self, loader, node):
|
||||
filename = self._find_file(loader.construct_yaml_str(node))
|
||||
with open(filename, 'r') as f:
|
||||
data = yaml.load(f, functools.partial(LocalLoader,
|
||||
search_path=self.search_path
|
||||
))
|
||||
return data
|
||||
|
||||
def _include_raw_tag(self, loader, node):
|
||||
filename = self._find_file(loader.construct_yaml_str(node))
|
||||
try:
|
||||
with open(filename, 'r') as f:
|
||||
data = f.read()
|
||||
except:
|
||||
logger.error("Failed to include file using search path: '{0}'"
|
||||
.format(':'.join(self.search_path)))
|
||||
raise
|
||||
return data
|
||||
|
||||
def _include_raw_escape_tag(self, loader, node):
|
||||
return self._escape(self._include_raw_tag(loader, node))
|
||||
|
||||
def _escape(self, data):
|
||||
return re.sub(r'({|})', r'\1\1', data)
|
||||
|
||||
|
||||
def load(stream, **kwargs):
|
||||
return yaml.load(stream, functools.partial(LocalLoader, **kwargs))
|
@ -22,11 +22,12 @@ import logging
|
||||
import os
|
||||
import re
|
||||
import doctest
|
||||
import json
|
||||
import operator
|
||||
import testtools
|
||||
import xml.etree.ElementTree as XML
|
||||
from ConfigParser import ConfigParser
|
||||
import yaml
|
||||
import jenkins_jobs.local_yaml as yaml
|
||||
from jenkins_jobs.builder import XmlJob, YamlParser, ModuleRegistry
|
||||
from jenkins_jobs.modules import (project_flow,
|
||||
project_matrix,
|
||||
@ -34,30 +35,33 @@ from jenkins_jobs.modules import (project_flow,
|
||||
project_multijob)
|
||||
|
||||
|
||||
def get_scenarios(fixtures_path):
|
||||
def get_scenarios(fixtures_path, in_ext='yaml', out_ext='xml'):
|
||||
"""Returns a list of scenarios, each scenario being described
|
||||
by two parameters (yaml and xml filenames).
|
||||
- content of the fixture .xml file (aka expected)
|
||||
by two parameters (yaml and xml filenames by default).
|
||||
- content of the fixture output file (aka expected)
|
||||
"""
|
||||
scenarios = []
|
||||
files = os.listdir(fixtures_path)
|
||||
yaml_files = [f for f in files if re.match(r'.*\.yaml$', f)]
|
||||
input_files = [f for f in files if re.match(r'.*\.{0}$'.format(in_ext), f)]
|
||||
|
||||
for yaml_filename in yaml_files:
|
||||
xml_candidate = re.sub(r'\.yaml$', '.xml', yaml_filename)
|
||||
# Make sure the yaml file has a xml counterpart
|
||||
if xml_candidate not in files:
|
||||
for input_filename in input_files:
|
||||
output_candidate = re.sub(r'\.{0}$'.format(in_ext),
|
||||
'.{0}'.format(out_ext), input_filename)
|
||||
# Make sure the input file has a output counterpart
|
||||
if output_candidate not in files:
|
||||
raise Exception(
|
||||
"No XML file named '%s' to match "
|
||||
"YAML file '%s'" % (xml_candidate, yaml_filename))
|
||||
conf_candidate = re.sub(r'\.yaml$', '.conf', yaml_filename)
|
||||
"No {0} file named '{1}' to match {2} file '{3}'"
|
||||
.format(out_ext.toupper(), output_candidate,
|
||||
in_ext.toupper(), input_filename))
|
||||
|
||||
conf_candidate = re.sub(r'\.yaml$', '.conf', input_filename)
|
||||
# If present, add the configuration file
|
||||
if conf_candidate not in files:
|
||||
conf_candidate = None
|
||||
|
||||
scenarios.append((yaml_filename, {
|
||||
'yaml_filename': yaml_filename,
|
||||
'xml_filename': xml_candidate,
|
||||
scenarios.append((input_filename, {
|
||||
'in_filename': input_filename,
|
||||
'out_filename': output_candidate,
|
||||
'conf_filename': conf_candidate,
|
||||
}))
|
||||
|
||||
@ -74,22 +78,22 @@ class BaseTestCase(object):
|
||||
|
||||
logging.basicConfig()
|
||||
|
||||
def __read_content(self):
|
||||
def _read_content(self):
|
||||
# Read XML content, assuming it is unicode encoded
|
||||
xml_filepath = os.path.join(self.fixtures_path, self.xml_filename)
|
||||
xml_filepath = os.path.join(self.fixtures_path, self.out_filename)
|
||||
xml_content = u"%s" % codecs.open(xml_filepath, 'r', 'utf-8').read()
|
||||
|
||||
yaml_filepath = os.path.join(self.fixtures_path, self.yaml_filename)
|
||||
yaml_filepath = os.path.join(self.fixtures_path, self.in_filename)
|
||||
with file(yaml_filepath, 'r') as yaml_file:
|
||||
yaml_content = yaml.load(yaml_file)
|
||||
|
||||
return (yaml_content, xml_content)
|
||||
|
||||
def test_yaml_snippet(self):
|
||||
if not self.xml_filename or not self.yaml_filename:
|
||||
if not self.out_filename or not self.in_filename:
|
||||
return
|
||||
|
||||
yaml_content, expected_xml = self.__read_content()
|
||||
yaml_content, expected_xml = self._read_content()
|
||||
project = None
|
||||
if ('project-type' in yaml_content):
|
||||
if (yaml_content['project-type'] == "maven"):
|
||||
@ -126,13 +130,13 @@ class BaseTestCase(object):
|
||||
|
||||
class SingleJobTestCase(BaseTestCase):
|
||||
def test_yaml_snippet(self):
|
||||
if not self.xml_filename or not self.yaml_filename:
|
||||
if not self.out_filename or not self.in_filename:
|
||||
return
|
||||
|
||||
xml_filepath = os.path.join(self.fixtures_path, self.xml_filename)
|
||||
xml_filepath = os.path.join(self.fixtures_path, self.out_filename)
|
||||
expected_xml = u"%s" % open(xml_filepath, 'r').read()
|
||||
|
||||
yaml_filepath = os.path.join(self.fixtures_path, self.yaml_filename)
|
||||
yaml_filepath = os.path.join(self.fixtures_path, self.in_filename)
|
||||
|
||||
if self.conf_filename:
|
||||
config = ConfigParser()
|
||||
@ -159,3 +163,23 @@ class SingleJobTestCase(BaseTestCase):
|
||||
doctest.NORMALIZE_WHITESPACE |
|
||||
doctest.REPORT_NDIFF)
|
||||
)
|
||||
|
||||
|
||||
class JsonTestCase(BaseTestCase):
|
||||
|
||||
def test_yaml_snippet(self):
|
||||
if not self.out_filename or not self.in_filename:
|
||||
return
|
||||
|
||||
yaml_content, expected_json = self._read_content()
|
||||
|
||||
pretty_json = json.dumps(yaml_content, indent=4,
|
||||
separators=(',', ': '))
|
||||
|
||||
self.assertThat(
|
||||
pretty_json,
|
||||
testtools.matchers.DocTestMatches(expected_json,
|
||||
doctest.ELLIPSIS |
|
||||
doctest.NORMALIZE_WHITESPACE |
|
||||
doctest.REPORT_NDIFF)
|
||||
)
|
||||
|
0
tests/localyaml/__init__.py
Normal file
0
tests/localyaml/__init__.py
Normal file
24
tests/localyaml/fixtures/include-raw-escaped001.json
Normal file
24
tests/localyaml/fixtures/include-raw-escaped001.json
Normal file
@ -0,0 +1,24 @@
|
||||
[
|
||||
{
|
||||
"template-job": {
|
||||
"builders": [
|
||||
{
|
||||
"shell": "#!/bin/bash\n#\n# Sample script showing how the yaml include-raw tag can be used\n# to inline scripts that are maintained outside of the jenkins\n# job yaml configuration.\n\necho \"hello world\"\n\nexit 0\n"
|
||||
},
|
||||
{
|
||||
"shell": "#!/bin/bash\n#\n# sample script to check that brackets aren't escaped\n# when using the include-raw application yaml tag\n\nVAR1=\"hello\"\nVAR2=\"world\"\nVAR3=\"${{VAR1}} ${{VAR2}}\"\n\n[[ -n \"${{VAR3}}\" ]] && {{\n # this next section is executed as one\n echo \"${{VAR3}}\"\n exit 0\n}}\n\n"
|
||||
}
|
||||
],
|
||||
"name": "test-job-include-raw-{num}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"project": {
|
||||
"num": 1,
|
||||
"jobs": [
|
||||
"test-job-include-raw-{num}"
|
||||
],
|
||||
"name": "test-job-template-1"
|
||||
}
|
||||
}
|
||||
]
|
13
tests/localyaml/fixtures/include-raw-escaped001.yaml
Normal file
13
tests/localyaml/fixtures/include-raw-escaped001.yaml
Normal file
@ -0,0 +1,13 @@
|
||||
- template-job:
|
||||
name: test-job-include-raw-{num}
|
||||
builders:
|
||||
- shell:
|
||||
!include-raw-escape include-raw001-hello-world.sh
|
||||
- shell:
|
||||
!include-raw-escape include-raw001-vars.sh
|
||||
|
||||
- project:
|
||||
name: test-job-template-1
|
||||
num: 1
|
||||
jobs:
|
||||
- 'test-job-include-raw-{num}'
|
9
tests/localyaml/fixtures/include-raw001-hello-world.sh
Normal file
9
tests/localyaml/fixtures/include-raw001-hello-world.sh
Normal file
@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Sample script showing how the yaml include-raw tag can be used
|
||||
# to inline scripts that are maintained outside of the jenkins
|
||||
# job yaml configuration.
|
||||
|
||||
echo "hello world"
|
||||
|
||||
exit 0
|
15
tests/localyaml/fixtures/include-raw001-vars.sh
Normal file
15
tests/localyaml/fixtures/include-raw001-vars.sh
Normal file
@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# sample script to check that brackets aren't escaped
|
||||
# when using the include-raw application yaml tag
|
||||
|
||||
VAR1="hello"
|
||||
VAR2="world"
|
||||
VAR3="${VAR1} ${VAR2}"
|
||||
|
||||
[[ -n "${VAR3}" ]] && {
|
||||
# this next section is executed as one
|
||||
echo "${VAR3}"
|
||||
exit 0
|
||||
}
|
||||
|
15
tests/localyaml/fixtures/include-raw001.json
Normal file
15
tests/localyaml/fixtures/include-raw001.json
Normal file
@ -0,0 +1,15 @@
|
||||
[
|
||||
{
|
||||
"job": {
|
||||
"builders": [
|
||||
{
|
||||
"shell": "#!/bin/bash\n#\n# Sample script showing how the yaml include-raw tag can be used\n# to inline scripts that are maintained outside of the jenkins\n# job yaml configuration.\n\necho \"hello world\"\n\nexit 0\n"
|
||||
},
|
||||
{
|
||||
"shell": "#!/bin/bash\n#\n# sample script to check that brackets aren't escaped\n# when using the include-raw application yaml tag\n\nVAR1=\"hello\"\nVAR2=\"world\"\nVAR3=\"${VAR1} ${VAR2}\"\n\n[[ -n \"${VAR3}\" ]] && {\n # this next section is executed as one\n echo \"${VAR3}\"\n exit 0\n}\n\n"
|
||||
}
|
||||
],
|
||||
"name": "test-job-include-raw-1"
|
||||
}
|
||||
}
|
||||
]
|
7
tests/localyaml/fixtures/include-raw001.yaml
Normal file
7
tests/localyaml/fixtures/include-raw001.yaml
Normal file
@ -0,0 +1,7 @@
|
||||
- job:
|
||||
name: test-job-include-raw-1
|
||||
builders:
|
||||
- shell:
|
||||
!include-raw include-raw001-hello-world.sh
|
||||
- shell:
|
||||
!include-raw include-raw001-vars.sh
|
43
tests/localyaml/fixtures/include001.json
Normal file
43
tests/localyaml/fixtures/include001.json
Normal file
@ -0,0 +1,43 @@
|
||||
[
|
||||
{
|
||||
"job": {
|
||||
"builders": [
|
||||
{
|
||||
"copyartifact": {
|
||||
"filter": "*.tar.gz",
|
||||
"project": "foo",
|
||||
"parameter-filters": "PUBLISH=true",
|
||||
"target": "/home/foo",
|
||||
"flatten": true,
|
||||
"optional": true,
|
||||
"which-build": "last-successful"
|
||||
}
|
||||
},
|
||||
{
|
||||
"copyartifact": {
|
||||
"project": "bar",
|
||||
"parameter-filters": "PUBLISH=true",
|
||||
"target": "/home/foo",
|
||||
"build-number": 123,
|
||||
"which-build": "specific-build",
|
||||
"filter": "*.tar.gz",
|
||||
"flatten": true,
|
||||
"optional": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"copyartifact": {
|
||||
"filter": "*.tar.gz",
|
||||
"project": "baz",
|
||||
"parameter-filters": "PUBLISH=true",
|
||||
"target": "/home/foo",
|
||||
"flatten": true,
|
||||
"optional": true,
|
||||
"which-build": "upstream-build"
|
||||
}
|
||||
}
|
||||
],
|
||||
"name": "test-job-1"
|
||||
}
|
||||
}
|
||||
]
|
4
tests/localyaml/fixtures/include001.yaml
Normal file
4
tests/localyaml/fixtures/include001.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
- job:
|
||||
name: test-job-1
|
||||
builders:
|
||||
!include include001.yaml.inc
|
17
tests/localyaml/fixtures/include001.yaml.inc
Normal file
17
tests/localyaml/fixtures/include001.yaml.inc
Normal file
@ -0,0 +1,17 @@
|
||||
- copyartifact: ©tarball
|
||||
project: foo
|
||||
filter: "*.tar.gz"
|
||||
target: /home/foo
|
||||
which-build: last-successful
|
||||
optional: true
|
||||
flatten: true
|
||||
parameter-filters: PUBLISH=true
|
||||
- copyartifact:
|
||||
<<: *copytarball
|
||||
project: bar
|
||||
which-build: specific-build
|
||||
build-number: 123
|
||||
- copyartifact:
|
||||
<<: *copytarball
|
||||
project: baz
|
||||
which-build: upstream-build
|
29
tests/localyaml/test_localyaml.py
Normal file
29
tests/localyaml/test_localyaml.py
Normal file
@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2013 Darragh Bailey
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import os
|
||||
from testtools import TestCase
|
||||
from testscenarios.testcase import TestWithScenarios
|
||||
from tests.base import get_scenarios, JsonTestCase
|
||||
|
||||
|
||||
class TestCaseLocalYamlInclude(TestWithScenarios, TestCase, JsonTestCase):
|
||||
"""
|
||||
Verify application specific tags independently of any changes to
|
||||
modules XML parsing behaviour
|
||||
"""
|
||||
fixtures_path = os.path.join(os.path.dirname(__file__), 'fixtures')
|
||||
scenarios = get_scenarios(fixtures_path, 'yaml', 'json')
|
12
tests/yamlparser/fixtures/include-raw-escape001-echo-vars.sh
Normal file
12
tests/yamlparser/fixtures/include-raw-escape001-echo-vars.sh
Normal file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# test script containing some variables to show how you can include scripts
|
||||
# into job template definitions provided you use the include-raw-escaped tag
|
||||
|
||||
MSG="hello world"
|
||||
|
||||
[[ -n "${MSG}" ]] && {
|
||||
# this next section is executed as one
|
||||
echo "${MSG}"
|
||||
exit 0
|
||||
}
|
2
tests/yamlparser/fixtures/include-raw-escape001.conf
Normal file
2
tests/yamlparser/fixtures/include-raw-escape001.conf
Normal file
@ -0,0 +1,2 @@
|
||||
[job_builder]
|
||||
include_path=tests/localyaml/fixtures:.
|
43
tests/yamlparser/fixtures/include-raw-escape001.xml
Normal file
43
tests/yamlparser/fixtures/include-raw-escape001.xml
Normal file
@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<project>
|
||||
<actions/>
|
||||
<description><!-- Managed by Jenkins Job Builder --></description>
|
||||
<keepDependencies>false</keepDependencies>
|
||||
<disabled>false</disabled>
|
||||
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
|
||||
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
|
||||
<concurrentBuild>false</concurrentBuild>
|
||||
<quietPeriod>1</quietPeriod>
|
||||
<assignedNode>my-test-node</assignedNode>
|
||||
<canRoam>false</canRoam>
|
||||
<properties>
|
||||
<EnvInjectJobProperty>
|
||||
<info>
|
||||
<loadFilesFromMaster>false</loadFilesFromMaster>
|
||||
</info>
|
||||
<on>true</on>
|
||||
<keepJenkinsSystemVariables>true</keepJenkinsSystemVariables>
|
||||
<keepBuildVariables>true</keepBuildVariables>
|
||||
</EnvInjectJobProperty>
|
||||
</properties>
|
||||
<scm class="hudson.scm.NullSCM"/>
|
||||
<builders>
|
||||
<hudson.tasks.Shell>
|
||||
<command>#!/bin/bash
|
||||
#
|
||||
# test script containing some variables to show how you can include scripts
|
||||
# into job template definitions provided you use the include-raw-escaped tag
|
||||
|
||||
MSG="hello world"
|
||||
|
||||
[[ -n "${MSG}" ]] && {
|
||||
# this next section is executed as one
|
||||
echo "${MSG}"
|
||||
exit 0
|
||||
}
|
||||
</command>
|
||||
</hudson.tasks.Shell>
|
||||
</builders>
|
||||
<publishers/>
|
||||
<buildWrappers/>
|
||||
</project>
|
22
tests/yamlparser/fixtures/include-raw-escape001.yaml
Normal file
22
tests/yamlparser/fixtures/include-raw-escape001.yaml
Normal file
@ -0,0 +1,22 @@
|
||||
# vim: sw=4 ts=4 et
|
||||
- job-template:
|
||||
name: 'test-job-{num}'
|
||||
project-type: freestyle
|
||||
node: my-test-node
|
||||
disabled: false
|
||||
quiet-period: 1
|
||||
properties:
|
||||
- inject:
|
||||
keep-build-variables: true
|
||||
keep-system-variables: true
|
||||
builders:
|
||||
- shell:
|
||||
!include-raw-escape include-raw-escape001-echo-vars.sh
|
||||
|
||||
|
||||
- project:
|
||||
name: test-job-template-1
|
||||
num: 1
|
||||
jobs:
|
||||
- 'test-job-{num}'
|
||||
|
37
tests/yamlparser/fixtures/include-raw001.xml
Normal file
37
tests/yamlparser/fixtures/include-raw001.xml
Normal file
@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<project>
|
||||
<actions/>
|
||||
<description><!-- Managed by Jenkins Job Builder --></description>
|
||||
<keepDependencies>false</keepDependencies>
|
||||
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
|
||||
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
|
||||
<concurrentBuild>false</concurrentBuild>
|
||||
<canRoam>true</canRoam>
|
||||
<properties>
|
||||
<EnvInjectJobProperty>
|
||||
<info>
|
||||
<loadFilesFromMaster>false</loadFilesFromMaster>
|
||||
</info>
|
||||
<on>true</on>
|
||||
<keepJenkinsSystemVariables>true</keepJenkinsSystemVariables>
|
||||
<keepBuildVariables>true</keepBuildVariables>
|
||||
</EnvInjectJobProperty>
|
||||
</properties>
|
||||
<scm class="hudson.scm.NullSCM"/>
|
||||
<builders>
|
||||
<hudson.tasks.Shell>
|
||||
<command>#!/bin/bash
|
||||
#
|
||||
# Sample script showing how the yaml include-raw tag can be used
|
||||
# to inline scripts that are maintained outside of the jenkins
|
||||
# job yaml configuration.
|
||||
|
||||
echo "hello world"
|
||||
|
||||
exit 0
|
||||
</command>
|
||||
</hudson.tasks.Shell>
|
||||
</builders>
|
||||
<publishers/>
|
||||
<buildWrappers/>
|
||||
</project>
|
10
tests/yamlparser/fixtures/include-raw001.yaml
Normal file
10
tests/yamlparser/fixtures/include-raw001.yaml
Normal file
@ -0,0 +1,10 @@
|
||||
- job:
|
||||
name: test-job-2
|
||||
properties:
|
||||
- inject:
|
||||
keep-build-variables: true
|
||||
keep-system-variables: true
|
||||
builders:
|
||||
- shell:
|
||||
!include-raw ../../localyaml/fixtures/include-raw001-hello-world.sh
|
||||
|
2
tests/yamlparser/fixtures/include-raw002-cool.sh
Normal file
2
tests/yamlparser/fixtures/include-raw002-cool.sh
Normal file
@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
echo "Doing somethiung cool"
|
2
tests/yamlparser/fixtures/include-raw002-cool.zsh
Normal file
2
tests/yamlparser/fixtures/include-raw002-cool.zsh
Normal file
@ -0,0 +1,2 @@
|
||||
#!/bin/zsh
|
||||
echo "Doing somethin cool with zsh"
|
65
tests/yamlparser/fixtures/include-raw002.xml
Normal file
65
tests/yamlparser/fixtures/include-raw002.xml
Normal file
@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<project>
|
||||
<actions/>
|
||||
<description><!-- Managed by Jenkins Job Builder --></description>
|
||||
<keepDependencies>false</keepDependencies>
|
||||
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
|
||||
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
|
||||
<concurrentBuild>false</concurrentBuild>
|
||||
<canRoam>true</canRoam>
|
||||
<properties>
|
||||
<EnvInjectJobProperty>
|
||||
<info>
|
||||
<loadFilesFromMaster>false</loadFilesFromMaster>
|
||||
</info>
|
||||
<on>true</on>
|
||||
<keepJenkinsSystemVariables>true</keepJenkinsSystemVariables>
|
||||
<keepBuildVariables>true</keepBuildVariables>
|
||||
</EnvInjectJobProperty>
|
||||
</properties>
|
||||
<scm class="hudson.scm.NullSCM"/>
|
||||
<builders/>
|
||||
<publishers/>
|
||||
<buildWrappers>
|
||||
<hudson.plugins.build__timeout.BuildTimeoutWrapper>
|
||||
<timeoutMinutes>3</timeoutMinutes>
|
||||
<failBuild>true</failBuild>
|
||||
<writingDescription>false</writingDescription>
|
||||
<timeoutPercentage>150</timeoutPercentage>
|
||||
<timeoutMinutesElasticDefault>90</timeoutMinutesElasticDefault>
|
||||
<timeoutType>elastic</timeoutType>
|
||||
</hudson.plugins.build__timeout.BuildTimeoutWrapper>
|
||||
<org.jenkinsci.plugins.preSCMbuildstep.PreSCMBuildStepsWrapper>
|
||||
<buildSteps>
|
||||
<hudson.tasks.Shell>
|
||||
<command>#!/bin/bash
|
||||
echo "Doing somethiung cool"
|
||||
</command>
|
||||
</hudson.tasks.Shell>
|
||||
<hudson.tasks.Shell>
|
||||
<command>#!/bin/zsh
|
||||
echo "Doing somethin cool with zsh"
|
||||
</command>
|
||||
</hudson.tasks.Shell>
|
||||
<hudson.tasks.Ant>
|
||||
<targets>target1 target2</targets>
|
||||
<antName>default</antName>
|
||||
</hudson.tasks.Ant>
|
||||
<EnvInjectBuilder>
|
||||
<info>
|
||||
<propertiesFilePath>example.prop</propertiesFilePath>
|
||||
<propertiesContent>EXAMPLE=foo-bar</propertiesContent>
|
||||
</info>
|
||||
</EnvInjectBuilder>
|
||||
</buildSteps>
|
||||
</org.jenkinsci.plugins.preSCMbuildstep.PreSCMBuildStepsWrapper>
|
||||
<com.michelin.cio.hudson.plugins.copytoslave.CopyToSlaveBuildWrapper>
|
||||
<includes>file1,file2*.txt</includes>
|
||||
<excludes>file2bad.txt</excludes>
|
||||
<flatten>false</flatten>
|
||||
<includeAntExcludes>false</includeAntExcludes>
|
||||
<relativeTo>userContent</relativeTo>
|
||||
<hudsonHomeRelative>false</hudsonHomeRelative>
|
||||
</com.michelin.cio.hudson.plugins.copytoslave.CopyToSlaveBuildWrapper>
|
||||
</buildWrappers>
|
||||
</project>
|
44
tests/yamlparser/fixtures/include-raw002.yaml
Normal file
44
tests/yamlparser/fixtures/include-raw002.yaml
Normal file
@ -0,0 +1,44 @@
|
||||
# vim: sw=4 ts=4 et
|
||||
- wrapper:
|
||||
name: timeout-wrapper
|
||||
wrappers:
|
||||
- timeout:
|
||||
fail: true
|
||||
elastic-percentage: 150
|
||||
elastic-default-timeout: 90
|
||||
type: elastic
|
||||
|
||||
- wrapper:
|
||||
name: pre-scm-shell-ant
|
||||
wrappers:
|
||||
- pre-scm-buildstep:
|
||||
- shell:
|
||||
!include-raw include-raw002-cool.sh
|
||||
- shell:
|
||||
!include-raw include-raw002-cool.zsh
|
||||
- ant: "target1 target2"
|
||||
ant-name: "Standard Ant"
|
||||
- inject:
|
||||
properties-file: example.prop
|
||||
properties-content: EXAMPLE=foo-bar
|
||||
|
||||
- wrapper:
|
||||
name: copy-files
|
||||
wrappers:
|
||||
- copy-to-slave:
|
||||
includes:
|
||||
- file1
|
||||
- file2*.txt
|
||||
excludes:
|
||||
- file2bad.txt
|
||||
|
||||
|
||||
- job:
|
||||
name: test-job-3
|
||||
wrappers:
|
||||
!include include001.yaml.inc
|
||||
properties:
|
||||
- inject:
|
||||
keep-build-variables: true
|
||||
keep-system-variables: true
|
||||
|
65
tests/yamlparser/fixtures/include001.xml
Normal file
65
tests/yamlparser/fixtures/include001.xml
Normal file
@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<project>
|
||||
<actions/>
|
||||
<description><!-- Managed by Jenkins Job Builder --></description>
|
||||
<keepDependencies>false</keepDependencies>
|
||||
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
|
||||
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
|
||||
<concurrentBuild>false</concurrentBuild>
|
||||
<canRoam>true</canRoam>
|
||||
<properties>
|
||||
<EnvInjectJobProperty>
|
||||
<info>
|
||||
<loadFilesFromMaster>false</loadFilesFromMaster>
|
||||
</info>
|
||||
<on>true</on>
|
||||
<keepJenkinsSystemVariables>true</keepJenkinsSystemVariables>
|
||||
<keepBuildVariables>true</keepBuildVariables>
|
||||
</EnvInjectJobProperty>
|
||||
</properties>
|
||||
<scm class="hudson.scm.NullSCM"/>
|
||||
<builders/>
|
||||
<publishers/>
|
||||
<buildWrappers>
|
||||
<hudson.plugins.build__timeout.BuildTimeoutWrapper>
|
||||
<timeoutMinutes>3</timeoutMinutes>
|
||||
<failBuild>true</failBuild>
|
||||
<writingDescription>false</writingDescription>
|
||||
<timeoutPercentage>150</timeoutPercentage>
|
||||
<timeoutMinutesElasticDefault>90</timeoutMinutesElasticDefault>
|
||||
<timeoutType>elastic</timeoutType>
|
||||
</hudson.plugins.build__timeout.BuildTimeoutWrapper>
|
||||
<org.jenkinsci.plugins.preSCMbuildstep.PreSCMBuildStepsWrapper>
|
||||
<buildSteps>
|
||||
<hudson.tasks.Shell>
|
||||
<command>#!/bin/bash
|
||||
echo "Doing somethiung cool"
|
||||
</command>
|
||||
</hudson.tasks.Shell>
|
||||
<hudson.tasks.Shell>
|
||||
<command>#!/bin/zsh
|
||||
echo "Doing somethin cool with zsh"
|
||||
</command>
|
||||
</hudson.tasks.Shell>
|
||||
<hudson.tasks.Ant>
|
||||
<targets>target1 target2</targets>
|
||||
<antName>default</antName>
|
||||
</hudson.tasks.Ant>
|
||||
<EnvInjectBuilder>
|
||||
<info>
|
||||
<propertiesFilePath>example.prop</propertiesFilePath>
|
||||
<propertiesContent>EXAMPLE=foo-bar</propertiesContent>
|
||||
</info>
|
||||
</EnvInjectBuilder>
|
||||
</buildSteps>
|
||||
</org.jenkinsci.plugins.preSCMbuildstep.PreSCMBuildStepsWrapper>
|
||||
<com.michelin.cio.hudson.plugins.copytoslave.CopyToSlaveBuildWrapper>
|
||||
<includes>file1,file2*.txt</includes>
|
||||
<excludes>file2bad.txt</excludes>
|
||||
<flatten>false</flatten>
|
||||
<includeAntExcludes>false</includeAntExcludes>
|
||||
<relativeTo>userContent</relativeTo>
|
||||
<hudsonHomeRelative>false</hudsonHomeRelative>
|
||||
</com.michelin.cio.hudson.plugins.copytoslave.CopyToSlaveBuildWrapper>
|
||||
</buildWrappers>
|
||||
</project>
|
46
tests/yamlparser/fixtures/include001.yaml
Normal file
46
tests/yamlparser/fixtures/include001.yaml
Normal file
@ -0,0 +1,46 @@
|
||||
# vim: sw=4 ts=4 et
|
||||
- wrapper:
|
||||
name: timeout-wrapper
|
||||
wrappers:
|
||||
- timeout:
|
||||
fail: true
|
||||
elastic-percentage: 150
|
||||
elastic-default-timeout: 90
|
||||
type: elastic
|
||||
|
||||
- wrapper:
|
||||
name: pre-scm-shell-ant
|
||||
wrappers:
|
||||
- pre-scm-buildstep:
|
||||
- shell: |
|
||||
#!/bin/bash
|
||||
echo "Doing somethiung cool"
|
||||
- shell: |
|
||||
#!/bin/zsh
|
||||
echo "Doing somethin cool with zsh"
|
||||
- ant: "target1 target2"
|
||||
ant-name: "Standard Ant"
|
||||
- inject:
|
||||
properties-file: example.prop
|
||||
properties-content: EXAMPLE=foo-bar
|
||||
|
||||
- wrapper:
|
||||
name: copy-files
|
||||
wrappers:
|
||||
- copy-to-slave:
|
||||
includes:
|
||||
- file1
|
||||
- file2*.txt
|
||||
excludes:
|
||||
- file2bad.txt
|
||||
|
||||
|
||||
- job:
|
||||
name: test-job-1
|
||||
wrappers:
|
||||
!include include001.yaml.inc
|
||||
properties:
|
||||
- inject:
|
||||
keep-build-variables: true
|
||||
keep-system-variables: true
|
||||
|
3
tests/yamlparser/fixtures/include001.yaml.inc
Normal file
3
tests/yamlparser/fixtures/include001.yaml.inc
Normal file
@ -0,0 +1,3 @@
|
||||
- timeout-wrapper
|
||||
- pre-scm-shell-ant
|
||||
- copy-files
|
Loading…
x
Reference in New Issue
Block a user