示例#1
0
def gerrit(parser, xml_parent, data):
    """yaml: gerrit

    Trigger on a Gerrit event.
    Requires the Jenkins :jenkins-wiki:`Gerrit Trigger Plugin <Gerrit+Trigger>`
    version >= 2.6.0.

    :arg list trigger-on: Events to react on. Please use either the new
      **trigger-on**, or the old **trigger-on-*** events definitions. You
      cannot use both at once.

      .. _trigger_on:

      :Trigger on:

         * **patchset-created-event** (`dict`) -- Trigger upon patchset
           creation.

           :Patchset created:
               * **exclude-drafts** (`bool`) -- exclude drafts (Default: False)
               * **exclude-trivial-rebase** (`bool`) -- exclude trivial rebase
                 (Default: False)
               * **exclude-no-code-change** (`bool`) -- exclude no code change
                 (Default: False)

           Exclude drafts|trivial-rebase|no-code-change needs
           Gerrit Trigger v2.12.0

         * **patchset-uploaded-event** -- Trigger upon patchset creation
           (this is a alias for `patchset-created-event`).

           .. deprecated:: 1.1.0  Please use :ref:`trigger-on <trigger_on>`.

         * **change-abandoned-event** -- Trigger on patchset abandoned.
           Requires Gerrit Trigger Plugin version >= 2.8.0.
         * **change-merged-event** -- Trigger on change merged
         * **change-restored-event** -- Trigger on change restored. Requires
           Gerrit Trigger Plugin version >= 2.8.0
         * **draft-published-event** -- Trigger on draft published event.
         * **ref-updated-event** -- Trigger on ref-updated.
         * **comment-added-event** (`dict`) -- Trigger on comment added.

           :Comment added:
               * **approval-category** (`str`) -- Approval (verdict) category
                 (for example 'APRV', 'CRVW', 'VRIF' -- see `Gerrit access
                 control
                 <http://gerrit.googlecode.com/svn/documentation/2.1/
                 access-control.html#categories>`_

               * **approval-value** -- Approval value for the comment added.
         * **comment-added-contains-event** (`dict`) -- Trigger on comment
           added contains Regular Expression.

           :Comment added contains:
               * **comment-contains-value** (`str`) -- Comment contains
                 Regular Expression value.

    :arg bool trigger-on-patchset-uploaded-event: Trigger on patchset upload.

        .. deprecated:: 1.1.0. Please use :ref:`trigger-on <trigger_on>`.

    :arg bool trigger-on-change-abandoned-event: Trigger on change abandoned.
        Requires Gerrit Trigger Plugin version >= 2.8.0

        .. deprecated:: 1.1.0. Please use :ref:`trigger-on <trigger_on>`.

    :arg bool trigger-on-change-merged-event: Trigger on change merged

        .. deprecated:: 1.1.0. Please use :ref:`trigger-on <trigger_on>`.

    :arg bool trigger-on-change-restored-event: Trigger on change restored.
        Requires Gerrit Trigger Plugin version >= 2.8.0

        .. deprecated:: 1.1.0. Please use :ref:`trigger-on <trigger_on>`.

    :arg bool trigger-on-comment-added-event: Trigger on comment added

        .. deprecated:: 1.1.0. Please use :ref:`trigger-on <trigger_on>`.

    :arg bool trigger-on-draft-published-event: Trigger on draft published
        event

        .. deprecated:: 1.1.0  Please use :ref:`trigger-on <trigger_on>`.

    :arg bool trigger-on-ref-updated-event: Trigger on ref-updated

        .. deprecated:: 1.1.0. Please use :ref:`trigger-on <trigger_on>`.

    :arg str trigger-approval-category: Approval category for comment added

        .. deprecated:: 1.1.0. Please use :ref:`trigger-on <trigger_on>`.

    :arg int trigger-approval-value: Approval value for comment added

        .. deprecated:: 1.1.0. Please use :ref:`trigger-on <trigger_on>`.

    :arg bool override-votes: Override default vote values
    :arg int gerrit-build-started-verified-value: Started ''Verified'' value
    :arg int gerrit-build-successful-verified-value: Successful ''Verified''
        value
    :arg int gerrit-build-failed-verified-value: Failed ''Verified'' value
    :arg int gerrit-build-unstable-verified-value: Unstable ''Verified'' value
    :arg int gerrit-build-notbuilt-verified-value: Not built ''Verified''
        value
    :arg int gerrit-build-started-codereview-value: Started ''CodeReview''
        value
    :arg int gerrit-build-successful-codereview-value: Successful
        ''CodeReview'' value
    :arg int gerrit-build-failed-codereview-value: Failed ''CodeReview'' value
    :arg int gerrit-build-unstable-codereview-value: Unstable ''CodeReview''
        value
    :arg int gerrit-build-notbuilt-codereview-value: Not built ''CodeReview''
        value
    :arg str failure-message: Message to leave on failure (default '')
    :arg str successful-message: Message to leave on success (default '')
    :arg str unstable-message: Message to leave when unstable (default '')
    :arg str notbuilt-message: Message to leave when not built (default '')
    :arg str failure-message-file: Sets the filename within the workspace from
        which to retrieve the unsuccessful review message. (optional)
    :arg list projects: list of projects to match

      :Project: * **project-compare-type** (`str`) --  ''PLAIN'', ''ANT'' or
                  ''REG_EXP''
                * **project-pattern** (`str`) -- Project name pattern to match
                * **branch-compare-type** (`str`) -- ''PLAIN'', ''ANT'' or
                  ''REG_EXP'' (not used if `branches` list is specified)

                  .. deprecated:: 1.1.0  Please use :ref:`branches <branches>`.

                * **branch-pattern** (`str`) -- Branch name pattern to match
                  (not used if `branches` list is specified)

                  .. deprecated:: 1.1.0  Please use :ref:`branches <branches>`.

                .. _branches:

                * **branches** (`list`) -- List of branches to match
                  (optional)

                  :Branch: * **branch-compare-type** (`str`) -- ''PLAIN'',
                             ''ANT'' or ''REG_EXP'' (optional) (default
                             ''PLAIN'')
                           * **branch-pattern** (`str`) -- Branch name pattern
                             to match

                * **file-paths** (`list`) -- List of file paths to match
                  (optional)

                  :File Path: * **compare-type** (`str`) -- ''PLAIN'', ''ANT''
                                or ''REG_EXP'' (optional) (default ''PLAIN'')
                              * **pattern** (`str`) -- File path pattern to
                                match

                * **topics** (`list`) -- List of topics to match
                  (optional)

                  :File Path: * **compare-type** (`str`) -- ''PLAIN'', ''ANT''
                                or ''REG_EXP'' (optional) (default ''PLAIN'')
                              * **pattern** (`str`) -- Topic name pattern to
                                match

    :arg dict skip-vote: map of build outcomes for which Jenkins must skip
        vote. Requires Gerrit Trigger Plugin version >= 2.7.0

        :Outcome: * **successful** (`bool`)
                  * **failed** (`bool`)
                  * **unstable** (`bool`)
                  * **notbuilt** (`bool`)

    :arg bool silent:  When silent mode is on there will be no communication
        back to Gerrit, i.e. no build started/failed/successful approve
        messages etc. If other non-silent jobs are triggered by the same
        Gerrit event as this job, the result of this job's build will not be
        counted in the end result of the other jobs. (default false)
    :arg bool silent-start: Sets silent start mode to on or off. When silent
        start mode is on there will be no 'build started' messages sent back
        to Gerrit. (default false)
    :arg bool escape-quotes: escape quotes in the values of Gerrit change
        parameters (default true)
    :arg bool no-name-and-email: Do not pass compound 'name and email'
        parameters (default false)
    :arg bool readable-message: If parameters regarding multiline text,
        e.g. commit message, should be as human readable or not. If false,
        those parameters are Base64 encoded to keep environment variables
        clean. (default false)
    :arg str dependency-jobs: All jobs on which this job depends. If a commit
        should trigger both a dependency and this job, the dependency will be
        built first. Use commas to separate job names. Beware of cyclic
        dependencies. (optional)
    :arg str notification-level: Defines to whom email notifications should be
        sent. This can either be nobody ('NONE'), the change owner ('OWNER'),
        reviewers and change owner ('OWNER_REVIEWERS'), all interested users
        i.e. owning, reviewing, watching, and starring ('ALL') or server
        default ('SERVER_DEFAULT'). (default 'SERVER_DEFAULT')
    :arg bool dynamic-trigger-enabled: Enable/disable the dynamic trigger
        (default false)
    :arg str dynamic-trigger-url: if you specify this option, the Gerrit
        trigger configuration will be fetched from there on a regular interval
    :arg bool trigger-for-unreviewed-patches: trigger patchset-created events
        for changes that were uploaded while connection to Gerrit was down
        (default false). Requires Gerrit Trigger Plugin version >= 2.11.0
    :arg str custom-url: Custom URL for a message sent to Gerrit. Build
        details URL will be used if empty. (default '')
    :arg str server-name: Name of the server to trigger on, or ''__ANY__'' to
        trigger on any configured Gerrit server (default '__ANY__'). Requires
        Gerrit Trigger Plugin version >= 2.11.0

    You may select one or more Gerrit events upon which to trigger.
    You must also supply at least one project and branch, optionally
    more.  If you select the comment-added trigger, you should also
    indicate which approval category and value you want to trigger the
    job.

    Until version 0.4.0 of Jenkins Job Builder, camelCase keys were used to
    configure Gerrit Trigger Plugin, instead of hyphenated-keys.  While still
    supported, camedCase keys are deprecated and should not be used. Support
    for this will be removed after 1.0.0 is released.

    Example:

    .. literalinclude:: /../../tests/triggers/fixtures/gerrit004.yaml
       :language: yaml

    """

    gerrit_handle_legacy_configuration(data)

    projects = data['projects']
    gtrig = XML.SubElement(
        xml_parent, 'com.sonyericsson.hudson.plugins.gerrit.trigger.'
        'hudsontrigger.GerritTrigger')
    XML.SubElement(gtrig, 'spec')
    gprojects = XML.SubElement(gtrig, 'gerritProjects')
    for project in projects:
        gproj = XML.SubElement(
            gprojects, 'com.sonyericsson.hudson.plugins.gerrit.'
            'trigger.hudsontrigger.data.GerritProject')
        XML.SubElement(gproj, 'compareType').text = \
            project['project-compare-type']
        XML.SubElement(gproj, 'pattern').text = project['project-pattern']

        branches = XML.SubElement(gproj, 'branches')
        project_branches = project.get('branches', [])

        if 'branch-compare-type' in project and 'branch-pattern' in project:
            warning = 'branch-compare-type and branch-pattern at project ' \
                      'level are deprecated and support will be removed ' \
                      'in a later version of Jenkins Job Builder; '
            if project_branches:
                warning += 'discarding values and using values from ' \
                           'branches section'
            else:
                warning += 'please use branches section instead'
            logger.warn(warning)
        if not project_branches:
            project_branches = [{
                'branch-compare-type':
                project['branch-compare-type'],
                'branch-pattern':
                project['branch-pattern']
            }]
        for branch in project_branches:
            gbranch = XML.SubElement(
                branches, 'com.sonyericsson.hudson.plugins.'
                'gerrit.trigger.hudsontrigger.data.Branch')
            XML.SubElement(gbranch, 'compareType').text = \
                branch['branch-compare-type']
            XML.SubElement(gbranch, 'pattern').text = branch['branch-pattern']

        project_file_paths = project.get('file-paths', [])
        if project_file_paths:
            fps_tag = XML.SubElement(gproj, 'filePaths')
            for file_path in project_file_paths:
                fp_tag = XML.SubElement(
                    fps_tag, 'com.sonyericsson.hudson.plugins.'
                    'gerrit.trigger.hudsontrigger.data.'
                    'FilePath')
                XML.SubElement(fp_tag, 'compareType').text = \
                    file_path.get('compare-type', 'PLAIN')
                XML.SubElement(fp_tag, 'pattern').text = file_path['pattern']

        topics = project.get('topics', [])
        if topics:
            topics_tag = XML.SubElement(gproj, 'topics')
            for topic in topics:
                topic_tag = XML.SubElement(
                    topics_tag, 'com.sonyericsson.hudson.plugins.'
                    'gerrit.trigger.hudsontrigger.data.'
                    'Topic')
                XML.SubElement(topic_tag, 'compareType').text = \
                    topic.get('compare-type', 'PLAIN')
                XML.SubElement(topic_tag, 'pattern').text = topic['pattern']

    build_gerrit_skip_votes(gtrig, data)
    XML.SubElement(gtrig, 'silentMode').text = str(data.get('silent',
                                                            False)).lower()
    XML.SubElement(gtrig, 'silentStartMode').text = str(
        data.get('silent-start', False)).lower()
    XML.SubElement(gtrig,
                   'escapeQuotes').text = str(data.get('escape-quotes',
                                                       True)).lower()
    XML.SubElement(gtrig, 'noNameAndEmailParameters').text = str(
        data.get('no-name-and-email', False)).lower()
    XML.SubElement(gtrig, 'readableMessage').text = str(
        data.get('readable-message', False)).lower()
    XML.SubElement(gtrig, 'dependencyJobsNames').text = str(
        data.get('dependency-jobs', ''))
    notification_levels = [
        'NONE', 'OWNER', 'OWNER_REVIEWERS', 'ALL', 'SERVER_DEFAULT'
    ]
    notification_level = data.get('notification-level', 'SERVER_DEFAULT')
    if notification_level not in notification_levels:
        raise InvalidAttributeError('notification-level', notification_level,
                                    notification_levels)
    if notification_level == 'SERVER_DEFAULT':
        XML.SubElement(gtrig, 'notificationLevel').text = ''
    else:
        XML.SubElement(gtrig, 'notificationLevel').text = notification_level
    XML.SubElement(gtrig, 'dynamicTriggerConfiguration').text = str(
        data.get('dynamic-trigger-enabled', False))
    XML.SubElement(gtrig, 'triggerConfigURL').text = str(
        data.get('dynamic-trigger-url', ''))
    XML.SubElement(gtrig, 'allowTriggeringUnreviewedPatches').text = str(
        data.get('trigger-for-unreviewed-patches', False)).lower()
    build_gerrit_triggers(gtrig, data)
    override = str(data.get('override-votes', False)).lower()
    if override == 'true':
        for yamlkey, xmlkey in [('gerrit-build-started-verified-value',
                                 'gerritBuildStartedVerifiedValue'),
                                ('gerrit-build-successful-verified-value',
                                 'gerritBuildSuccessfulVerifiedValue'),
                                ('gerrit-build-failed-verified-value',
                                 'gerritBuildFailedVerifiedValue'),
                                ('gerrit-build-unstable-verified-value',
                                 'gerritBuildUnstableVerifiedValue'),
                                ('gerrit-build-notbuilt-verified-value',
                                 'gerritBuildNotBuiltVerifiedValue'),
                                ('gerrit-build-started-codereview-value',
                                 'gerritBuildStartedCodeReviewValue'),
                                ('gerrit-build-successful-codereview-value',
                                 'gerritBuildSuccessfulCodeReviewValue'),
                                ('gerrit-build-failed-codereview-value',
                                 'gerritBuildFailedCodeReviewValue'),
                                ('gerrit-build-unstable-codereview-value',
                                 'gerritBuildUnstableCodeReviewValue'),
                                ('gerrit-build-notbuilt-codereview-value',
                                 'gerritBuildNotBuiltCodeReviewValue')]:
            if data.get(yamlkey) is not None:
                # str(int(x)) makes input values like '+1' work
                XML.SubElement(gtrig,
                               xmlkey).text = str(int(data.get(yamlkey)))
    XML.SubElement(gtrig, 'buildStartMessage').text = str(
        data.get('start-message', ''))
    XML.SubElement(gtrig, 'buildFailureMessage').text = \
        data.get('failure-message', '')
    XML.SubElement(gtrig, 'buildSuccessfulMessage').text = str(
        data.get('successful-message', ''))
    XML.SubElement(gtrig, 'buildUnstableMessage').text = str(
        data.get('unstable-message', ''))
    XML.SubElement(gtrig, 'buildNotBuiltMessage').text = str(
        data.get('notbuilt-message', ''))
    XML.SubElement(gtrig, 'buildUnsuccessfulFilepath').text = str(
        data.get('failure-message-file', ''))
    XML.SubElement(gtrig, 'customUrl').text = str(data.get('custom-url', ''))
    XML.SubElement(gtrig,
                   'serverName').text = str(data.get('server-name', '__ANY__'))
示例#2
0
def github_scm(xml_parent, data):
    """Configure GitHub SCM

    Requires the :jenkins-wiki:`GitHub Branch Source Plugin
    <GitHub+Branch+Source+Plugin>`.

    :arg str api-uri: The GitHub API uri for hosted / on-site GitHub. Must
        first be configured in Global Configuration. (default GitHub)
    :arg str credentials-id: Credentials used to scan branches and pull
        requests, check out sources and mark commit statuses. (optional)
    :arg str repo-owner: Specify the name of the GitHub Organization or
        GitHub User Account. (required)
    :arg str repo: The GitHub repo. (required)

    :arg str branch-discovery: Discovers branches on the repository.
        Valid options: no-pr, only-pr, all, false. (default 'no-pr')
    :arg str discover-pr-forks-strategy: Fork strategy. Valid options:
        merge-current, current, both, false. (default 'merge-current')
    :arg str discover-pr-forks-trust: Discovers pull requests where the origin
        repository is a fork of the target repository.
        Valid options: contributors, everyone, permission or nobody.
        (default 'contributors')
    :arg str discover-pr-origin: Discovers pull requests where the origin
        repository is the same as the target repository.
        Valid options: merge-current, current, both.  (default 'merge-current')

    Minimal Example:

    .. literalinclude::
       /../../tests/multibranch/fixtures/scm_github_minimal.yaml

    Full Example:

    .. literalinclude::
       /../../tests/multibranch/fixtures/scm_github_full.yaml
    """
    github_path = 'org.jenkinsci.plugins.github_branch_source'
    github_path_dscore = 'org.jenkinsci.plugins.github__branch__source'

    source = XML.SubElement(
        xml_parent, 'source', {
            'class': ''.join([github_path, '.GitHubSCMSource']),
            'plugin': 'github-branch-source',
        })
    mapping = [
        ('', 'id', str(uuid.uuid4())),
        ('repo-owner', 'repoOwner', None),
        ('repo', 'repository', None),
    ]
    helpers.convert_mapping_to_xml(source, data, mapping, fail_required=True)

    mapping_optional = [
        ('api-uri', 'apiUri', None),
        ('credentials-id', 'credentialsId', None),
    ]
    helpers.convert_mapping_to_xml(source,
                                   data,
                                   mapping_optional,
                                   fail_required=False)

    traits = XML.SubElement(source, 'traits')

    # no-pr value is assumed if branch-discovery not mentioned.
    if data.get('branch-discovery', 'no-pr'):
        bd = XML.SubElement(
            traits, ''.join([github_path_dscore, '.BranchDiscoveryTrait']))
        bd_strategy = {
            'no-pr': '1',
            'only-pr': '2',
            'all': '3',
        }
        bd_mapping = [('branch-discovery', 'strategyId', 'no-pr', bd_strategy)]
        helpers.convert_mapping_to_xml(bd,
                                       data,
                                       bd_mapping,
                                       fail_required=True)

    if data.get('discover-pr-forks-strategy', 'merged-current'):
        dprf = XML.SubElement(
            traits,
            ''.join([github_path_dscore, '.ForkPullRequestDiscoveryTrait']))
        dprf_strategy = {
            'merge-current': '1',
            'current': '2',
            'both': '3',
        }
        dprf_mapping = [('discover-pr-forks-strategy', 'strategyId',
                         'merge-current', dprf_strategy)]
        helpers.convert_mapping_to_xml(dprf,
                                       data,
                                       dprf_mapping,
                                       fail_required=True)

        trust = data.get('discover-pr-forks-trust', 'contributors')
        trust_map = {
            'contributors':
            ''.join([
                github_path, '.ForkPullRequestDiscoveryTrait$TrustContributors'
            ]),
            'everyone':
            ''.join(
                [github_path, '.ForkPullRequestDiscoveryTrait$TrustEveryone']),
            'permission':
            ''.join([
                github_path, '.ForkPullRequestDiscoveryTrait$TrustPermission'
            ]),
            'nobody':
            ''.join(
                [github_path, '.ForkPullRequestDiscoveryTrait$TrustNobody']),
        }
        if trust not in trust_map:
            raise InvalidAttributeError('discover-pr-forks-trust', trust,
                                        trust_map.keys())
        XML.SubElement(dprf, 'trust').attrib['class'] = trust_map[trust]

    dpro_strategy = data.get('discover-pr-origin', 'merge-current')
    dpro = XML.SubElement(
        traits,
        ''.join([github_path_dscore, '.OriginPullRequestDiscoveryTrait']))
    dpro_strategy_map = {
        'merge-current': '1',
        'current': '2',
        'both': '3',
    }
    if dpro_strategy not in dpro_strategy_map:
        raise InvalidAttributeError('discover-pr-origin', dpro_strategy,
                                    dpro_strategy_map.keys())
    if trust not in trust_map:
        raise InvalidAttributeError('discover-pr-forks-trust', trust,
                                    trust_map.keys())
    dpro_mapping = [('discover-pr-origin', 'strategyId', 'merge-current',
                     dpro_strategy_map)]
    helpers.convert_mapping_to_xml(dpro,
                                   data,
                                   dpro_mapping,
                                   fail_required=True)
示例#3
0
    def root_xml(self, data):
        xml_parent = XML.Element(self.jenkins_class)
        xml_parent.attrib['plugin'] = 'workflow-multibranch'
        XML.SubElement(xml_parent, 'properties')

        #########
        # Views #
        #########

        views = XML.SubElement(xml_parent, 'views')
        all_view = XML.SubElement(views, 'hudson.model.AllView')
        all_view_mapping = [
            ('', 'name', 'All'),
            ('', 'filterExecutors', False),
            ('', 'filterQueue', False),
        ]
        helpers.convert_mapping_to_xml(all_view, {},
                                       all_view_mapping,
                                       fail_required=True)

        XML.SubElement(all_view, 'properties',
                       {'class': 'hudson.model.View$PropertyList'})

        XML.SubElement(all_view, 'owner', {
            'class': self.jenkins_class,
            'reference': '../../..'
        })

        XML.SubElement(xml_parent, 'viewsTabBar',
                       {'class': 'hudson.views.DefaultViewsTabBar'})

        ################
        # Folder Views #
        ################

        folderViews = XML.SubElement(
            xml_parent, 'folderViews', {
                'class': 'jenkins.branch.MultiBranchProjectViewHolder',
                'plugin': 'branch-api',
            })

        XML.SubElement(folderViews, 'owner', {
            'class': self.jenkins_class,
            'reference': '../..'
        })

        ##################
        # Health Metrics #
        ##################

        hm = XML.SubElement(xml_parent, 'healthMetrics')
        hm_path = ('com.cloudbees.hudson.plugins.folder.health'
                   '.WorstChildHealthMetric')
        hm_plugin = XML.SubElement(hm, hm_path, {
            'plugin': 'cloudbees-folder',
        })
        XML.SubElement(hm_plugin, 'nonRecursive').text = 'false'

        ########
        # Icon #
        ########

        icon = XML.SubElement(
            xml_parent, 'icon', {
                'class': 'jenkins.branch.MetadataActionFolderIcon',
                'plugin': 'branch-api',
            })
        XML.SubElement(icon, 'owner', {
            'class': self.jenkins_class,
            'reference': '../..'
        })

        ########################
        # Orphan Item Strategy #
        ########################

        ois_default_strategy = ('com.cloudbees.hudson.plugins.'
                                'folder.computed.DefaultOrphanedItemStrategy')
        ois = XML.SubElement(xml_parent, 'orphanedItemStrategy', {
            'class': ois_default_strategy,
            'plugin': 'cloudbees-folder',
        })

        ois_mapping = [
            ('prune-dead-branches', 'pruneDeadBranches', True, [True, False]),
            ('days-to-keep', 'daysToKeep', -1),
            ('number-to-keep', 'numToKeep', -1),
        ]
        helpers.convert_mapping_to_xml(ois, data, ois_mapping)

        ###########################
        # Periodic Folder Trigger #
        ###########################

        triggers = XML.SubElement(xml_parent, 'triggers')

        # Valid options for the periodic trigger interval.
        pft_map = collections.OrderedDict([
            ("1m", ("* * * * *", '60000')),
            ("2m", ("*/2 * * * *", '120000')),
            ("5m", ("*/5 * * * *", '300000')),
            ("10m", ("H/6 * * * *", '600000')),
            ("15m", ("H/6 * * * *", '900000')),
            ("20m", ("H/3 * * * *", '1200000')),
            ("25m", ("H/3 * * * *", '1500000')),
            ("30m", ("H/2 * * * *", '1800000')),
            ("1h", ("H * * * *", '3600000')),
            ("2h", ("H * * * *", '7200000')),
            ("4h", ("H * * * *", '14400000')),
            ("8h", ("H * * * *", '28800000')),
            ("12h", ("H H * * *", '43200000')),
            ("1d", ("H H * * *", '86400000')),
            ("2d", ("H H * * *", '172800000')),
            ("1w", ("H H * * *", '604800000')),
            ("2w", ("H H * * *", '1209600000')),
            ("4w", ("H H * * *", '2419200000')),
        ])

        pft_val = data.get('periodic-folder-trigger')
        if pft_val:
            if not pft_map.get(pft_val):
                raise InvalidAttributeError('periodic-folder-trigger', pft_val,
                                            pft_map.keys())

            pft_path = ('com.cloudbees.hudson.plugins.folder.computed.'
                        'PeriodicFolderTrigger')
            pft = XML.SubElement(triggers, pft_path,
                                 {'plugin': 'cloudbees-folder'})
            XML.SubElement(pft, 'spec').text = pft_map[pft_val][0]
            XML.SubElement(pft, 'interval').text = pft_map[pft_val][1]

        ###########
        # Sources #
        ###########

        sources = XML.SubElement(
            xml_parent, 'sources', {
                'class': 'jenkins.branch.MultiBranchProject$BranchSourceList',
                'plugin': 'branch-api',
            })
        sources_data = XML.SubElement(sources, 'data')
        XML.SubElement(sources, 'owner', {
            'class': self.jenkins_class,
            'reference': '../..',
        })

        valid_scm = [
            'bitbucket',
            'gerrit',
            'git',
            'github',
        ]
        for scm_data in data.get('scm', None):
            for scm in scm_data:
                bs = XML.SubElement(sources_data,
                                    'jenkins.branch.BranchSource')

                if scm == 'bitbucket':
                    bitbucket_scm(bs, scm_data[scm])

                elif scm == 'gerrit':
                    gerrit_scm(bs, scm_data[scm])

                elif scm == 'git':
                    git_scm(bs, scm_data[scm])

                elif scm == 'github':
                    github_scm(bs, scm_data[scm])

                else:
                    raise InvalidAttributeError('scm', scm_data, valid_scm)

        ###########
        # Factory #
        ###########

        factory = XML.SubElement(xml_parent, 'factory', {
            'class': self.jenkins_factory_class,
        })
        XML.SubElement(factory, 'owner', {
            'class': self.jenkins_class,
            'reference': '../..'
        })
        XML.SubElement(factory,
                       'scriptPath').text = data.get('script-path',
                                                     'Jenkinsfile')

        return xml_parent
示例#4
0
def throttle(registry, xml_parent, data):
    """yaml: throttle
    Throttles the number of builds for this job.
    Requires the Jenkins :jenkins-wiki:`Throttle Concurrent Builds Plugin
    <Throttle+Concurrent+Builds+Plugin>`.

    :arg str option: throttle `project` (throttle the project alone)
         or `category` (throttle the project as part of one or more categories)
    :arg int max-per-node: max concurrent builds per node (default 0)
    :arg int max-total: max concurrent builds (default 0)
    :arg bool enabled: whether throttling is enabled (default true)
    :arg list categories: multiproject throttle categories
    :arg bool matrix-builds: throttle matrix master builds (default true)
    :arg bool matrix-configs: throttle matrix config builds (default false)
    :arg str parameters-limit: prevent jobs with matching parameters from
         running concurrently (default false)
    :arg list parameters-check-list: Comma-separated list of parameters
        to use when comparing jobs (optional)

    Example:

    .. literalinclude:: /../../tests/properties/fixtures/throttle001.yaml
       :language: yaml
    """
    throttle = XML.SubElement(xml_parent,
                              'hudson.plugins.throttleconcurrents.'
                              'ThrottleJobProperty')
    mapping = [
        ('max-per-node', 'maxConcurrentPerNode', '0'),
        ('max-total', 'maxConcurrentTotal', '0'),
        ('enabled', 'throttleEnabled', True),
    ]
    helpers.convert_mapping_to_xml(throttle, data, mapping, fail_required=True)
    cat = data.get('categories', [])
    if cat:
        cn = XML.SubElement(throttle, 'categories')
        for c in cat:
            XML.SubElement(cn, 'string').text = str(c)

    options_list = ('category', 'project')
    option = data.get('option')
    if option not in options_list:
        raise InvalidAttributeError('option', option, options_list)
    mapping = [
        ('', 'throttleOption', option),
        ('', 'configVersion', '1'),
        ('parameters-limit', 'limitOneJobWithMatchingParams', False),
    ]
    helpers.convert_mapping_to_xml(throttle, data, mapping, fail_required=True)

    matrixopt = XML.SubElement(throttle, 'matrixOptions')
    mapping = [
        ('matrix-builds', 'throttleMatrixBuilds', True),
        ('matrix-configs', 'throttleMatrixConfigurations', False),
    ]
    helpers.convert_mapping_to_xml(
        matrixopt, data, mapping, fail_required=True)

    params_to_use = data.get('parameters-check-list', [])
    XML.SubElement(throttle, 'paramsToUseForLimit').text = ",".join(
        params_to_use)
示例#5
0
def authorization(registry, xml_parent, data):
    """yaml: authorization
    Specifies an authorization matrix

    .. _authorization:

    :arg list <name>: `<name>` is the name of the group or user, containing
        the list of rights to grant.

       :<name> rights:
            * **credentials-create**
            * **credentials-delete**
            * **credentials-manage-domains**
            * **credentials-update**
            * **credentials-view**
            * **job-build**
            * **job-cancel**
            * **job-configure**
            * **job-delete**
            * **job-discover**
            * **job-extended-read**
            * **job-move**
            * **job-read**
            * **job-status**
            * **job-workspace**
            * **ownership-jobs**
            * **run-delete**
            * **run-replay**
            * **run-update**
            * **scm-tag**

    Example:

    .. literalinclude:: /../../tests/properties/fixtures/authorization.yaml
       :language: yaml
    """

    credentials = 'com.cloudbees.plugins.credentials.CredentialsProvider.'
    ownership = 'com.synopsys.arc.jenkins.plugins.ownership.OwnershipPlugin.'

    mapping = {
        'credentials-create': ''.join((credentials, 'Create')),
        'credentials-delete': ''.join((credentials, 'Delete')),
        'credentials-manage-domains': ''.join((credentials, 'ManageDomains')),
        'credentials-update': ''.join((credentials, 'Update')),
        'credentials-view': ''.join((credentials, 'View')),
        'job-build': 'hudson.model.Item.Build',
        'job-cancel': 'hudson.model.Item.Cancel',
        'job-configure': 'hudson.model.Item.Configure',
        'job-delete': 'hudson.model.Item.Delete',
        'job-discover': 'hudson.model.Item.Discover',
        'job-extended-read': 'hudson.model.Item.ExtendedRead',
        'job-move': 'hudson.model.Item.Move',
        'job-read': 'hudson.model.Item.Read',
        'job-status': 'hudson.model.Item.ViewStatus',
        'job-workspace': 'hudson.model.Item.Workspace',
        'ownership-jobs': ''.join((ownership, 'Jobs')),
        'run-delete': 'hudson.model.Run.Delete',
        'run-replay': 'hudson.model.Run.Replay',
        'run-update': 'hudson.model.Run.Update',
        'scm-tag': 'hudson.scm.SCM.Tag',
    }

    if data:
        matrix = XML.SubElement(xml_parent,
                                'hudson.security.AuthorizationMatrixProperty')
        for (username, perms) in data.items():
            for perm in perms:
                pe = XML.SubElement(matrix, 'permission')
                try:
                    pe.text = "{0}:{1}".format(mapping[perm], username)
                except KeyError:
                    raise InvalidAttributeError(username, perm, mapping.keys())
示例#6
0
def credentials_param(registry, xml_parent, data):
    """yaml: credentials
    A credentials selection parameter.

    Requires the Jenkins :jenkins-plugins:`Credentials Plugin <credentials>`.

    :arg str name: the name of the parameter
    :arg str type: credential type (optional, default 'any')

        :Allowed Values: * **any** Any credential type (default)
                    * **usernamepassword** Username with password
                    * **sshkey** SSH Username with private key
                    * **secretfile** Secret file
                    * **secrettext** Secret text
                    * **certificate** Certificate

    :arg bool required: whether this parameter is required (optional, default
        false)
    :arg str default: default credentials ID (optional)
    :arg str description: a description of the parameter (optional)

    Example:

    .. literalinclude:: \
    /../../tests/parameters/fixtures/credentials-param001.yaml
       :language: yaml

    """
    cred_impl_types = {
        "any":
        "com.cloudbees.plugins.credentials.common.StandardCredentials",
        "usernamepassword":
        "******" +
        "UsernamePasswordCredentialsImpl",
        "sshkey":
        "com.cloudbees.jenkins.plugins.sshcredentials.impl." +
        "BasicSSHUserPrivateKey",
        "secretfile":
        "org.jenkinsci.plugins.plaincredentials.impl." + "FileCredentialsImpl",
        "secrettext":
        "org.jenkinsci.plugins.plaincredentials.impl." +
        "StringCredentialsImpl",
        "certificate":
        "com.cloudbees.plugins.credentials.impl." +
        "CertificateCredentialsImpl",
    }

    cred_type = data.get("type", "any").lower()
    if cred_type not in cred_impl_types:
        raise InvalidAttributeError("type", cred_type, cred_impl_types.keys())

    pdef = base_param(
        registry,
        xml_parent,
        data,
        False,
        "com.cloudbees.plugins.credentials." +
        "CredentialsParameterDefinition",
    )
    XML.SubElement(pdef, "defaultValue").text = data.get("default", "")
    XML.SubElement(pdef, "credentialType").text = cred_impl_types[cred_type]
    XML.SubElement(pdef, "required").text = str(data.get("required",
                                                         False)).lower()
示例#7
0
def maven_metadata_param(registry, xml_parent, data):
    """yaml: maven-metadata
    This parameter allows the resolution of maven artifact versions
    by contacting the repository and reading the maven-metadata.xml.

    Requires the Jenkins :jenkins-plugins:`Maven Metadata Plugin
    <maven-metadata-plugin>`.

    :arg str name: Name of the parameter
    :arg str description: Description of the parameter (optional)
    :arg str repository-base-url: URL from where you retrieve your artifacts
        (default '')
    :arg str repository-username: Repository's username if authentication is
        required. (default '')
    :arg str repository-password: Repository's password if authentication is
        required. (default '')
    :arg str artifact-group-id: Unique project identifier (default '')
    :arg str artifact-id: Name of the artifact without version (default '')
    :arg str packaging: Artifact packaging option. Could be something such as
        jar, zip, pom.... (default '')
    :arg str versions-filter: Specify a regular expression which will be used
        to filter the versions which are actually displayed when triggering a
        new build. (default '')
    :arg str default-value: For features such as SVN polling a default value
        is required. If job will only be started manually, this field is not
        necessary. (default '')
    :arg str maximum-versions-to-display: The maximum number of versions to
        display in the drop-down. Any non-number value as well as 0 or negative
        values will default to all. (default 10)
    :arg str sorting-order: ascending or descending
        (default descending)

    Example:

    .. literalinclude::
       /../../tests/parameters/fixtures/maven-metadata-param001.yaml
       :language: yaml

    """
    pdef = base_param(
        registry,
        xml_parent,
        data,
        False,
        "eu.markov.jenkins.plugin.mvnmeta."
        "MavenMetadataParameterDefinition",
    )
    mapping = [
        ("repository-base-url", "repoBaseUrl", ""),
        ("artifact-group-id", "groupId", ""),
        ("artifact-id", "artifactId", ""),
        ("packaging", "packaging", ""),
        ("default-value", "defaultValue", ""),
        ("versions-filter", "versionFilter", ""),
    ]
    helpers.convert_mapping_to_xml(pdef, data, mapping, fail_required=True)

    sort_order = data.get("sorting-order", "descending").lower()
    sort_dict = {"descending": "DESC", "ascending": "ASC"}

    if sort_order not in sort_dict:
        raise InvalidAttributeError(sort_order, sort_order, sort_dict.keys())

    XML.SubElement(pdef, "sortOrder").text = sort_dict[sort_order]
    mapping = [
        ("maximum-versions-to-display", "maxVersions", 10),
        ("repository-username", "username", ""),
        ("repository-password", "password", ""),
    ]
    helpers.convert_mapping_to_xml(pdef, data, mapping, fail_required=True)
示例#8
0
def bitbucket_scm(xml_parent, data):
    r"""Configure BitBucket scm

    Requires the :jenkins-wiki:`Bitbucket Branch Source Plugin
    <Bitbucket+Branch+Source+Plugin>`.

    :arg str credentials-id: The credential to use to scan BitBucket.
        (required)
    :arg str repo-owner: Specify the name of the Bitbucket Team or Bitbucket
        User Account. (required)
    :arg str repo: The BitBucket repo. (required)

    :arg bool discover-tags: Discovers tags on the repository.
        (default false)
    :arg str server-url: The address of the bitbucket server. (optional)
    :arg str head-filter-regex: A regular expression for filtering
        discovered source branches. Requires the :jenkins-wiki:`SCM API Plugin
        <SCM+API+Plugin>`.
    :arg str discovery-branch: Discovers branches on the repository.
        Valid options: ex-pr, only-pr, all.
        Value is not specified by default.
    :arg str discover-pr-origin: Discovers pull requests where the origin
        repository is the same as the target repository.
        Valid options: mergeOnly, headOnly, mergeAndHead.
        Value is not specified by default.
    :arg str discover-pr-forks-strategy: Fork strategy. Valid options:
        merge-current, current, both, false. (default 'merge-current')
    :arg str discover-pr-forks-trust: Discovers pull requests where the origin
        repository is a fork of the target repository.
        Valid options: contributors, everyone, permission or nobody.
        (default 'contributors')
    :arg list build-strategies: Provides control over whether to build a branch
        (or branch like things such as change requests and tags) whenever it is
        discovered initially or a change from the previous revision has been
        detected. (optional)
        Refer to :func:`~build_strategies <build_strategies>`.
    :arg dict property-strategies: Provides control over how to build a branch
        (like to disable SCM triggering or to override the pipeline durability)
        (optional)
        Refer to :func:`~property_strategies <property_strategies>`.
    :arg bool local-branch: Check out to matching local branch
        If given, checkout the revision to build as HEAD on this branch.
        If selected, then the branch name is computed from the remote branch
        without the origin. In that case, a remote branch origin/master will
        be checked out to a local branch named master, and a remote branch
        origin/develop/new-feature will be checked out to a local branch
        named develop/newfeature.
        Requires the :jenkins-wiki:`Git Plugin <Git+Plugin>`.
    :arg dict checkout-over-ssh: Checkout repo over ssh.

        * **credentials** ('str'): Credentials to use for
            checkout of the repo over ssh.

    :arg dict filter-by-name-wildcard: Enable filter by name with wildcards.
        Requires the :jenkins-wiki:`SCM API Plugin <SCM+API+Plugin>`.

        * **includes** ('str'): Space-separated list
            of name patterns to consider. You may use * as a wildcard;
            for example: `master release*`
        * **excludes** ('str'): Name patterns to
            ignore even if matched by the includes list.
            For example: `release*`

    :extensions:

        * **clean** (`dict`)
            * **after** (`bool`) - Clean the workspace after checkout
            * **before** (`bool`) - Clean the workspace before checkout
        * **prune** (`bool`) - Prune remote branches (default false)
        * **shallow-clone** (`bool`) - Perform shallow clone (default false)
        * **depth** (`int`) - Set shallow clone depth (default 1)
        * **do-not-fetch-tags** (`bool`) - Perform a clone without tags
            (default false)
        * **submodule** (`dict`)
            * **disable** (`bool`) - By disabling support for submodules you
              can still keep using basic git plugin functionality and just have
              Jenkins to ignore submodules completely as if they didn't exist.
            * **recursive** (`bool`) - Retrieve all submodules recursively
              (uses '--recursive' option which requires git>=1.6.5)
            * **tracking** (`bool`) - Retrieve the tip of the configured
              branch in .gitmodules (Uses '\-\-remote' option which requires
              git>=1.8.2)
            * **parent-credentials** (`bool`) - Use credentials from default
              remote of parent repository (default false).
            * **reference-repo** (`str`) - Path of the reference repo to use
              during clone (optional)
            * **timeout** (`int`) - Specify a timeout (in minutes) for
              submodules operations (default 10).
        * **timeout** (`str`) - Timeout for git commands in minutes (optional)
        * **use-author** (`bool`): Use author rather than committer in Jenkin's
            build changeset (default false)
        * **wipe-workspace** (`bool`) - Wipe out workspace before build
            (default true)


    Minimal Example:

    .. literalinclude::
       /../../tests/multibranch/fixtures/scm_bitbucket_minimal.yaml

    Full Example:

    .. literalinclude::
       /../../tests/multibranch/fixtures/scm_bitbucket_full.yaml
    """
    source = XML.SubElement(xml_parent, 'source', {
        'class': 'com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMSource',
        'plugin': 'cloudbees-bitbucket-branch-source',
    })
    source_mapping = [
        ('', 'id', '-'.join(['bb', data.get('repo-owner', ''),
            data.get('repo', '')])),
        ('repo-owner', 'repoOwner', None),
        ('repo', 'repository', None),
    ]
    helpers.convert_mapping_to_xml(
        source, data, source_mapping, fail_required=True)

    mapping_optional = [
        ('credentials-id', 'credentialsId', None),
        ('server-url', 'serverUrl', None),
    ]
    helpers.convert_mapping_to_xml(
        source, data, mapping_optional, fail_required=False)

    traits = XML.SubElement(source, 'traits')
    if data.get('discover-tags', False):
        XML.SubElement(traits,
            'com.cloudbees.jenkins.plugins.bitbucket.TagDiscoveryTrait')
    if data.get('head-filter-regex', None):
        rshf = XML.SubElement(traits,
            'jenkins.scm.impl.trait.RegexSCMHeadFilterTrait')
        XML.SubElement(rshf, 'regex').text = data.get('head-filter-regex')

    if data.get('discover-pr-origin', None):
        dpro = XML.SubElement(traits,
            'com.cloudbees.jenkins.plugins.bitbucket'
            '.OriginPullRequestDiscoveryTrait')
        dpro_strategies = {
            'mergeOnly': '1',
            'headOnly': '2',
            'mergeAndHead': '3'
        }
        dpro_mapping = [
            ('discover-pr-origin', 'strategyId', None, dpro_strategies)
        ]
        helpers.convert_mapping_to_xml(
            dpro, data, dpro_mapping, fail_required=True)

    if data.get('discover-pr-forks-strategy'):
        dprf = XML.SubElement(traits,
             'com.cloudbees.jenkins.plugins.bitbucket'
             '.ForkPullRequestDiscoveryTrait')
        dprf_strategy = {
            'merge-current': '1',
            'current': '2',
            'both': '3',
        }
        dprf_mapping = [
            ('discover-pr-forks-strategy', 'strategyId', 'merge-current',
            dprf_strategy)
        ]
        helpers.convert_mapping_to_xml(
            dprf, data, dprf_mapping, fail_required=True)

        trust = data.get('discover-pr-forks-trust', 'contributors')
        trust_map = {
            'contributors': ''.join([
                'com.cloudbees.jenkins.plugins.bitbucket'
                '.ForkPullRequestDiscoveryTrait$TrustContributors']),
            'everyone': ''.join([
                'com.cloudbees.jenkins.plugins.bitbucket'
                '.ForkPullRequestDiscoveryTrait$TrustEveryone']),
            'permission': ''.join([
                'com.cloudbees.jenkins.plugins.bitbucket'
                '.ForkPullRequestDiscoveryTrait$TrustPermission']),
            'nobody': ''.join([
                'com.cloudbees.jenkins.plugins.bitbucket'
                '.ForkPullRequestDiscoveryTrait$TrustNobody']),
        }
        if trust not in trust_map:
            raise InvalidAttributeError('discover-pr-forks-trust',
                                        trust,
                                        trust_map.keys())
        XML.SubElement(dprf, 'trust').attrib['class'] = trust_map[trust]

    if data.get('discover-branch', None):
        dbr = XML.SubElement(traits,
            'com.cloudbees.jenkins.plugins.bitbucket.BranchDiscoveryTrait')
        dbr_strategies = {
            'ex-pr': '1',
            'only-pr': '2',
            'all': '3'
        }
        dbr_mapping = [
            ('discover-branch', 'strategyId', None, dbr_strategies)
        ]
        helpers.convert_mapping_to_xml(
            dbr, data, dbr_mapping, fail_required=True)

    if data.get('property-strategies', None):
        property_strategies(xml_parent, data)

    if data.get('build-strategies', None):
        build_strategies(xml_parent, data)

    if data.get('local-branch', False):
        lbr = XML.SubElement(traits,
            'jenkins.plugins.git.traits.LocalBranchTrait', {
                'plugin': 'git',
            }
        )
        lbr_extension = XML.SubElement(lbr,
            'extension', {
                'class': 'hudson.plugins.git.extensions.impl.LocalBranch',
            }
        )
        XML.SubElement(lbr_extension,
            'localBranch').text = "**"

    if data.get('checkout-over-ssh', None):
        cossh = XML.SubElement(traits,
            'com.cloudbees.jenkins.plugins.bitbucket.SSHCheckoutTrait')
        cossh_credentials = [
            ('credentials', 'credentialsId', ''),
        ]
        helpers.convert_mapping_to_xml(
            cossh,
            data.get('checkout-over-ssh'),
            cossh_credentials,
            fail_required=True)

    if data.get('filter-by-name-wildcard', None):
        wscmf_name = XML.SubElement(traits,
            'jenkins.scm.impl.trait.WildcardSCMHeadFilterTrait', {
                'plugin': 'scm-api',
            }
        )
        wscmf_name_mapping = [
            ('includes', 'includes', ''),
            ('excludes', 'excludes', '')
        ]
        helpers.convert_mapping_to_xml(
            wscmf_name,
            data.get('filter-by-name-wildcard', ''),
            wscmf_name_mapping,
            fail_required=True)

    # handle the default git extensions like:
    # - clean
    # - shallow-clone
    # - timeout
    # - do-not-fetch-tags
    # - submodule
    # - prune
    # - wipe-workspace
    # - use-author
    git_extensions(traits, data)
示例#9
0
def github_scm(xml_parent, data):
    r"""Configure GitHub SCM

    Requires the :jenkins-wiki:`GitHub Branch Source Plugin
    <GitHub+Branch+Source+Plugin>`.

    :arg str api-uri: The GitHub API uri for hosted / on-site GitHub. Must
        first be configured in Global Configuration. (default GitHub)
    :arg bool ssh-checkout: Checkout over SSH.

        * **credentials** ('str'): Credentials to use for
            checkout of the repo over ssh.

    :arg str credentials-id: Credentials used to scan branches and pull
        requests, check out sources and mark commit statuses. (optional)
    :arg str repo-owner: Specify the name of the GitHub Organization or
        GitHub User Account. (required)
    :arg str repo: The GitHub repo. (required)

    :arg str branch-discovery: Discovers branches on the repository.
        Valid options: no-pr, only-pr, all, false. (default 'no-pr')
    :arg str discover-pr-forks-strategy: Fork strategy. Valid options:
        merge-current, current, both, false. (default 'merge-current')
    :arg str discover-pr-forks-trust: Discovers pull requests where the origin
        repository is a fork of the target repository.
        Valid options: contributors, everyone, permission or nobody.
        (default 'contributors')
    :arg str discover-pr-origin: Discovers pull requests where the origin
        repository is the same as the target repository.
        Valid options: merge-current, current, both.  (default 'merge-current')
    :arg bool discover-tags: Discovers tags on the repository.
        (default false)
    :arg list build-strategies: Provides control over whether to build a branch
        (or branch like things such as change requests and tags) whenever it is
        discovered initially or a change from the previous revision has been
        detected. (optional)
        Refer to :func:`~build_strategies <build_strategies>`.
    :arg dict property-strategies: Provides control over how to build a branch
        (like to disable SCM triggering or to override the pipeline durability)
        (optional)
        Refer to :func:`~property_strategies <property_strategies>`.

    :extensions:

        * **clean** (`dict`)
            * **after** (`bool`) - Clean the workspace after checkout
            * **before** (`bool`) - Clean the workspace before checkout
        * **prune** (`bool`) - Prune remote branches (default false)
        * **shallow-clone** (`bool`) - Perform shallow clone (default false)
        * **depth** (`int`) - Set shallow clone depth (default 1)
        * **do-not-fetch-tags** (`bool`) - Perform a clone without tags
            (default false)
        * **disable-pr-notifications** (`bool`) - Disable default github status
            notifications on pull requests (default false) (Requires the
            :jenkins-plugins:`GitHub Branch Source Plugin
            <disable-github-multibranch-status>`.)
        * **submodule** (`dict`)
            * **disable** (`bool`) - By disabling support for submodules you
              can still keep using basic git plugin functionality and just have
              Jenkins to ignore submodules completely as if they didn't exist.
            * **recursive** (`bool`) - Retrieve all submodules recursively
              (uses '--recursive' option which requires git>=1.6.5)
            * **tracking** (`bool`) - Retrieve the tip of the configured
              branch in .gitmodules (Uses '\-\-remote' option which requires
              git>=1.8.2)
            * **parent-credentials** (`bool`) - Use credentials from default
              remote of parent repository (default false).
            * **reference-repo** (`str`) - Path of the reference repo to use
              during clone (optional)
            * **timeout** (`int`) - Specify a timeout (in minutes) for
              submodules operations (default 10).
        * **timeout** (`str`) - Timeout for git commands in minutes (optional)
        * **use-author** (`bool`): Use author rather than committer in Jenkin's
            build changeset (default false)
        * **wipe-workspace** (`bool`) - Wipe out workspace before build
            (default true)

    Minimal Example:

    .. literalinclude::
       /../../tests/multibranch/fixtures/scm_github_minimal.yaml

    Full Example:

    .. literalinclude::
       /../../tests/multibranch/fixtures/scm_github_full.yaml
    """
    github_path = 'org.jenkinsci.plugins.github_branch_source'
    github_path_dscore = 'org.jenkinsci.plugins.github__branch__source'

    source = XML.SubElement(xml_parent, 'source', {
        'class': ''.join([github_path, '.GitHubSCMSource']),
        'plugin': 'github-branch-source',
    })
    mapping = [
        ('', 'id', '-'.join(['gh', data.get('repo-owner', ''),
            data.get('repo', '')])),
        ('repo-owner', 'repoOwner', None),
        ('repo', 'repository', None),
    ]
    helpers.convert_mapping_to_xml(
        source, data, mapping, fail_required=True)

    mapping_optional = [
        ('api-uri', 'apiUri', None),
        ('credentials-id', 'credentialsId', None),
    ]
    helpers.convert_mapping_to_xml(
        source, data, mapping_optional, fail_required=False)

    traits = XML.SubElement(source, 'traits')

    # no-pr value is assumed if branch-discovery not mentioned.
    if data.get('branch-discovery', 'no-pr'):
        bd = XML.SubElement(traits, ''.join([
            github_path_dscore, '.BranchDiscoveryTrait']))
        bd_strategy = {
            'no-pr': '1',
            'only-pr': '2',
            'all': '3',
        }
        bd_mapping = [
            ('branch-discovery', 'strategyId', 'no-pr', bd_strategy)
        ]
        helpers.convert_mapping_to_xml(
            bd, data, bd_mapping, fail_required=True)

    if data.get('ssh-checkout', None):
        cossh = XML.SubElement(
            traits, ''.join([
                github_path_dscore, '.SSHCheckoutTrait'
            ])
        )
        if not isinstance(data.get('ssh-checkout'), bool):
            cossh_credentials = [
                ('credentials', 'credentialsId', ''),
            ]
            helpers.convert_mapping_to_xml(
                cossh,
                data.get('ssh-checkout'),
                cossh_credentials,
                fail_required=True)

    if data.get('discover-tags', False):
        XML.SubElement(
            traits, ''.join([
                github_path_dscore, '.TagDiscoveryTrait'
            ])
        )

    if data.get('discover-pr-forks-strategy', 'merged-current'):
        dprf = XML.SubElement(
            traits, ''.join([
                github_path_dscore, '.ForkPullRequestDiscoveryTrait'
            ])
        )
        dprf_strategy = {
            'merge-current': '1',
            'current': '2',
            'both': '3',
        }
        dprf_mapping = [
            ('discover-pr-forks-strategy', 'strategyId', 'merge-current',
            dprf_strategy)
        ]
        helpers.convert_mapping_to_xml(
            dprf, data, dprf_mapping, fail_required=True)

        trust = data.get('discover-pr-forks-trust', 'contributors')
        trust_map = {
            'contributors': ''.join([
                github_path,
                '.ForkPullRequestDiscoveryTrait$TrustContributors']),
            'everyone': ''.join([
                github_path,
                '.ForkPullRequestDiscoveryTrait$TrustEveryone']),
            'permission': ''.join([
                github_path,
                '.ForkPullRequestDiscoveryTrait$TrustPermission']),
            'nobody': ''.join([
                github_path,
                '.ForkPullRequestDiscoveryTrait$TrustNobody']),
        }
        if trust not in trust_map:
            raise InvalidAttributeError('discover-pr-forks-trust',
                                        trust,
                                        trust_map.keys())
        XML.SubElement(dprf, 'trust').attrib['class'] = trust_map[trust]

    dpro_strategy = data.get('discover-pr-origin', 'merge-current')
    dpro = XML.SubElement(traits, ''.join([
        github_path_dscore,
        '.OriginPullRequestDiscoveryTrait'
    ]))
    dpro_strategy_map = {
        'merge-current': '1',
        'current': '2',
        'both': '3',
    }
    if dpro_strategy not in dpro_strategy_map:
        raise InvalidAttributeError('discover-pr-origin',
                                    dpro_strategy,
                                    dpro_strategy_map.keys())
    dpro_mapping = [
        ('discover-pr-origin', 'strategyId', 'merge-current',
        dpro_strategy_map)
    ]
    helpers.convert_mapping_to_xml(
        dpro, data, dpro_mapping, fail_required=True)

    if data.get('property-strategies', None):
        property_strategies(xml_parent, data)

    if data.get('build-strategies', None):
        build_strategies(xml_parent, data)

    # handle the default git extensions like:
    # - clean
    # - shallow-clone
    # - timeout
    # - do-not-fetch-tags
    # - submodule
    # - prune
    # - wipe-workspace
    # - use-author
    git_extensions(traits, data)

    # github-only extensions
    disable_github_status_path_dscore = (
        'com.adobe.jenkins.disable__github__multibranch__status')
    if data.get('disable-pr-notifications', False):
        XML.SubElement(
            traits, ''.join([
                disable_github_status_path_dscore, '.DisableStatusUpdateTrait'
            ]), {
                'plugin': 'disable-github-multibranch-status'
            }
        )
    def root_xml(self, data):
        root = XML.Element('matrix-project')

        # Default to 'execution-strategy'
        strategies = ([s for s in data.keys() if s.endswith('-strategy')]
                      or ['execution-strategy'])

        # Job can not have multiple strategies
        if len(strategies) > 1:
            raise ValueError(
                'matrix-project does not support multiple strategies. '
                'Given %s: %s' % (len(strategies), ', '.join(strategies)))
        strategy_name = strategies[0]

        if strategy_name not in self.supported_strategies:
            raise ValueError(
                'Given strategy %s. Only %s strategies are supported' %
                (strategy_name, self.supported_strategies.keys()))

        ex_r = XML.SubElement(
            root, 'executionStrategy',
            {'class': self.supported_strategies[strategy_name]})

        strategy = data.get(strategy_name, {})

        if strategy_name == 'execution-strategy':
            XML.SubElement(root, 'combinationFilter').text = (str(
                strategy.get('combination-filter', '')).rstrip())
            XML.SubElement(ex_r, 'runSequentially').text = (str(
                strategy.get('sequential', False)).lower())
            if 'touchstone' in strategy:
                XML.SubElement(ex_r,
                               'touchStoneCombinationFilter').text = (str(
                                   strategy['touchstone'].get('expr', '')))

                threshold = strategy['touchstone'].get('result',
                                                       'stable').upper()
                supported_thresholds = ('STABLE', 'UNSTABLE')
                if threshold not in supported_thresholds:
                    raise InvalidAttributeError('touchstone', threshold,
                                                supported_thresholds)

                # Web ui uses Stable but hudson.model.Result has Success
                if threshold == 'STABLE':
                    threshold = 'SUCCESS'

                t_r = XML.SubElement(ex_r, 'touchStoneResultCondition')
                for sub_elem in ('name', 'ordinal', 'color'):
                    XML.SubElement(t_r, sub_elem).text = (
                        hudson_model.THRESHOLDS[threshold][sub_elem])

        elif strategy_name == 'yaml-strategy':
            filename = str(strategy.get('filename', ''))
            text = str(strategy.get('text', ''))
            exclude_key = str(strategy.get('exclude-key', ''))

            if bool(filename) == bool(text):  # xor with str
                raise ValueError('yaml-strategy must be given '
                                 'either "filename" or "text"')

            yamlType = (filename and 'file') or (text and 'text')
            XML.SubElement(ex_r, 'yamlType').text = yamlType

            XML.SubElement(ex_r, 'yamlFile').text = filename
            XML.SubElement(ex_r, 'yamlText').text = text

            XML.SubElement(ex_r, 'excludeKey').text = exclude_key

        ax_root = XML.SubElement(root, 'axes')
        for axis_ in data.get('axes', []):
            axis = axis_['axis']
            axis_type = axis['type']
            if axis_type not in self.supported_axis:
                raise ValueError('Only %s axes types are supported' %
                                 self.supported_axis.keys())
            axis_name = self.supported_axis.get(axis_type)
            lbl_root = XML.SubElement(ax_root, axis_name)
            name, values = axis.get('name', ''), axis.get('values', [''])
            if axis_type == 'jdk':
                XML.SubElement(lbl_root, 'name').text = 'jdk'
            elif axis_type == 'python':
                XML.SubElement(lbl_root, 'name').text = 'PYTHON'
            elif axis_type == 'tox':
                XML.SubElement(lbl_root, 'name').text = 'TOXENV'
            else:
                XML.SubElement(lbl_root, 'name').text = str(name)
            if axis_type != "groovy":
                v_root = XML.SubElement(lbl_root, 'values')
            if axis_type == "dynamic":
                XML.SubElement(v_root, 'string').text = str(values[0])
                XML.SubElement(lbl_root, 'varName').text = str(values[0])
                v_root = XML.SubElement(lbl_root, 'axisValues')
                XML.SubElement(v_root, 'string').text = 'default'
            elif axis_type == "groovy":
                command = XML.SubElement(lbl_root, 'groovyString')
                command.text = axis.get('command')
                XML.SubElement(lbl_root, 'computedValues').text = ''
            elif axis_type == "yaml":
                XML.SubElement(v_root, 'string').text = axis.get('filename')
            else:
                for v in values:
                    XML.SubElement(v_root, 'string').text = str(v)

        return root
示例#11
0
    def root_xml(self, data):
        root = XML.Element("matrix-project")

        # Default to 'execution-strategy'
        strategies = [s for s in data.keys() if s.endswith("-strategy")] or [
            "execution-strategy"
        ]

        # Job can not have multiple strategies
        if len(strategies) > 1:
            raise ValueError(
                "matrix-project does not support multiple strategies. "
                "Given %s: %s" % (len(strategies), ", ".join(strategies))
            )
        strategy_name = strategies[0]

        if strategy_name not in self.supported_strategies:
            raise ValueError(
                "Given strategy %s. Only %s strategies are supported"
                % (strategy_name, self.supported_strategies.keys())
            )

        ex_r = XML.SubElement(
            root,
            "executionStrategy",
            {"class": self.supported_strategies[strategy_name]},
        )

        strategy = data.get(strategy_name, {})

        if strategy_name == "execution-strategy":
            XML.SubElement(root, "combinationFilter").text = str(
                strategy.get("combination-filter", "")
            ).rstrip()
            XML.SubElement(ex_r, "runSequentially").text = str(
                strategy.get("sequential", False)
            ).lower()
            if "touchstone" in strategy:
                XML.SubElement(ex_r, "touchStoneCombinationFilter").text = str(
                    strategy["touchstone"].get("expr", "")
                )

                threshold = strategy["touchstone"].get("result", "stable").upper()
                supported_thresholds = ("STABLE", "UNSTABLE")
                if threshold not in supported_thresholds:
                    raise InvalidAttributeError(
                        "touchstone", threshold, supported_thresholds
                    )

                # Web ui uses Stable but hudson.model.Result has Success
                if threshold == "STABLE":
                    threshold = "SUCCESS"

                t_r = XML.SubElement(ex_r, "touchStoneResultCondition")
                for sub_elem in ("name", "ordinal", "color"):
                    XML.SubElement(t_r, sub_elem).text = hudson_model.THRESHOLDS[
                        threshold
                    ][sub_elem]

        elif strategy_name == "yaml-strategy":
            filename = str(strategy.get("filename", ""))
            text = str(strategy.get("text", ""))
            exclude_key = str(strategy.get("exclude-key", ""))

            if bool(filename) == bool(text):  # xor with str
                raise ValueError(
                    "yaml-strategy must be given " 'either "filename" or "text"'
                )

            yamlType = (filename and "file") or (text and "text")
            XML.SubElement(ex_r, "yamlType").text = yamlType

            XML.SubElement(ex_r, "yamlFile").text = filename
            XML.SubElement(ex_r, "yamlText").text = text

            XML.SubElement(ex_r, "excludeKey").text = exclude_key

        elif strategy_name == "p4-strategy":
            XML.SubElement(ex_r, "runSequentially").text = str(
                strategy.get("sequential", False)
            ).lower()

            XML.SubElement(ex_r, "buildParent").text = str(
                strategy.get("build-parent", False)
            ).lower()

        ax_root = XML.SubElement(root, "axes")
        for axis_ in data.get("axes", []):
            axis = axis_["axis"]
            axis_type = axis["type"]
            if axis_type not in self.supported_axis:
                raise ValueError(
                    "Only %s axes types are supported" % self.supported_axis.keys()
                )
            axis_name = self.supported_axis.get(axis_type)
            lbl_root = XML.SubElement(ax_root, axis_name)
            name, values = axis.get("name", ""), axis.get("values", [""])
            if axis_type == "jdk":
                XML.SubElement(lbl_root, "name").text = "jdk"
            elif axis_type == "python":
                XML.SubElement(lbl_root, "name").text = "PYTHON"
            elif axis_type == "tox":
                XML.SubElement(lbl_root, "name").text = "TOXENV"
            else:
                XML.SubElement(lbl_root, "name").text = str(name)
            if axis_type != "groovy":
                v_root = XML.SubElement(lbl_root, "values")
            if axis_type == "dynamic":
                XML.SubElement(v_root, "string").text = str(values[0])
                XML.SubElement(lbl_root, "varName").text = str(values[0])
                v_root = XML.SubElement(lbl_root, "axisValues")
                XML.SubElement(v_root, "string").text = "default"
            elif axis_type == "groovy":
                command = XML.SubElement(lbl_root, "groovyString")
                command.text = axis.get("command")
                XML.SubElement(lbl_root, "computedValues").text = ""
            elif axis_type == "yaml":
                XML.SubElement(v_root, "string").text = axis.get("filename")
            else:
                for v in values:
                    XML.SubElement(v_root, "string").text = str(v)

        return root
示例#12
0
def config_file_provider_settings(xml_parent, data):
    SETTINGS_TYPES = ['file', 'cfp']
    settings = {
        'default-settings':
        'jenkins.mvn.DefaultSettingsProvider',
        'settings':
        'jenkins.mvn.FilePathSettingsProvider',
        'config-file-provider-settings':
        'org.jenkinsci.plugins.configfiles.maven.job.MvnSettingsProvider',
        'default-global-settings':
        'jenkins.mvn.DefaultGlobalSettingsProvider',
        'global-settings':
        'jenkins.mvn.FilePathGlobalSettingsProvider',
        'config-file-provider-global-settings':
        'org.jenkinsci.plugins.configfiles.maven.job.'
        'MvnGlobalSettingsProvider',
    }

    if 'settings' in data:
        # Support for Config File Provider
        settings_file = str(data['settings'])
        settings_type = data.get('settings-type', 'file')

        # For cfp versions <2.10.0 we are able to detect cfp via the config
        # settings name.
        if settings_file.startswith('org.jenkinsci.plugins.configfiles.maven.'
                                    'MavenSettingsConfig'):
            settings_type = 'cfp'

        if settings_type == 'file':
            lsettings = XML.SubElement(xml_parent, 'settings',
                                       {'class': settings['settings']})
            XML.SubElement(lsettings, 'path').text = settings_file
        elif settings_type == 'cfp':
            lsettings = XML.SubElement(
                xml_parent, 'settings',
                {'class': settings['config-file-provider-settings']})
            XML.SubElement(lsettings, 'settingsConfigId').text = settings_file
        else:
            raise InvalidAttributeError('settings-type', settings_type,
                                        SETTINGS_TYPES)
    else:
        XML.SubElement(xml_parent, 'settings',
                       {'class': settings['default-settings']})

    if 'global-settings' in data:
        # Support for Config File Provider
        global_settings_file = str(data['global-settings'])
        global_settings_type = data.get('settings-type', 'file')

        # For cfp versions <2.10.0 we are able to detect cfp via the config
        # settings name.
        if global_settings_file.startswith(
                'org.jenkinsci.plugins.configfiles.maven.'
                'GlobalMavenSettingsConfig'):
            global_settings_type = 'cfp'

        if global_settings_type == 'file':
            gsettings = XML.SubElement(xml_parent, 'globalSettings',
                                       {'class': settings['global-settings']})
            XML.SubElement(gsettings, 'path').text = global_settings_file
        elif global_settings_type == 'cfp':
            gsettings = XML.SubElement(
                xml_parent, 'globalSettings',
                {'class': settings['config-file-provider-global-settings']})
            XML.SubElement(gsettings,
                           'settingsConfigId').text = global_settings_file
        else:
            raise InvalidAttributeError('settings-type', global_settings_type,
                                        SETTINGS_TYPES)
    else:
        XML.SubElement(xml_parent, 'globalSettings',
                       {'class': settings['default-global-settings']})
示例#13
0
def git(parser, xml_parent, data):
    """yaml: git
    Specifies the git SCM repository for this job.
    Requires the Jenkins :jenkins-wiki:`Git Plugin <Git+Plugin>`.

    :arg str url: URL of the git repository
    :arg str credentials-id: ID of credential to use to connect, which is the
      last field(a 32-digit hexadecimal code) of the path of URL visible after
      you clicked the credential under Jenkins Global credentials. (optional)
    :arg str refspec: refspec to fetch (default '+refs/heads/\*:refs/remotes/\
remoteName/\*')
    :arg str name: name to fetch (default 'origin')
    :arg list(str) remotes: list of remotes to set up (optional, only needed if
      multiple remotes need to be set up)

        :Remote: * **url** (`string`) - url of remote repo
                 * **refspec** (`string`) - refspec to fetch (optional)
                 * **credentials-id** - ID of credential to use to connect,
                   which is the last field of the path of URL
                   (a 32-digit hexadecimal code) visible after you clicked
                   credential under Jenkins Global credentials. (optional)
    :arg list(str) branches: list of branch specifiers to build (default '**')
    :arg list(str) excluded-users: list of users to ignore revisions from
      when polling for changes. (if polling is enabled, optional)
    :arg list(str) included-regions: list of file/folders to include (optional)
    :arg list(str) excluded-regions: list of file/folders to exclude (optional)
    :arg str local-branch: Checkout/merge to local branch (optional)
    :arg dict merge:
        :merge:
            * **remote** (`string`) - name of repo that contains branch to
              merge to (default 'origin')
            * **branch** (`string`) - name of the branch to merge to
            * **strategy** (`string`) - merge strategy. Can be one of
              'default', 'resolve', 'recursive', 'octopus', 'ours',
              'subtree'. (default 'default')
            * **fast-forward-mode** (`string`) - merge fast-forward mode.
              Can be one of 'FF', 'FF_ONLY' or 'NO_FF'. (default 'FF')
    :arg str basedir: location relative to the workspace root to clone to
             (default: workspace)
    :arg bool skip-tag: Skip tagging (default false)
    :arg bool shallow-clone: Perform shallow clone (default false)
    :arg bool prune: Prune remote branches (default false)
    :arg bool clean: Clean after checkout (default false)

        .. deprecated:: 1.1.1. Please use clean extension format.

    :arg bool fastpoll: Use fast remote polling (default false)
    :arg bool disable-submodules: Disable submodules (default false)

        .. deprecated:: 1.1.1. Please use submodule extension.

    :arg bool recursive-submodules: Recursively update submodules (default
      false)

        .. deprecated:: 1.1.1. Please use submodule extension.

    :arg bool use-author: Use author rather than committer in Jenkin's build
      changeset (default false)
    :arg str git-tool: The name of the Git installation to use (default
      'Default')
    :arg str reference-repo: Path of the reference repo to use during clone
      (optional)
    :arg str scm-name: The unique scm name for this Git SCM (optional)
    :arg bool ignore-notify: Ignore notifyCommit URL accesses (default false)
    :arg str browser: what repository browser to use (default '(Auto)')
    :arg str browser-url: url for the repository browser (required if browser
      is not '(Auto)', no default)
    :arg str browser-version: version of the repository browser (GitLab only,
      default '0.0')
    :arg str project-name: project name in Gitblit and ViewGit repobrowser
      (optional)
    :arg str repo-name: repository name in phabricator repobrowser (optional)
    :arg str choosing-strategy: Jenkins class for selecting what to build
      (default 'default')
    :arg str git-config-name: Configure name for Git clone (optional)
    :arg str git-config-email: Configure email for Git clone (optional)


    :extensions:
        :arg dict changelog-against:
            :changelog-against:
                * **remote** (`string`) - name of repo that contains branch to
                  create changelog against (default 'origin')
                * **branch** (`string`) - name of the branch to create
                  changelog against (default 'master')

        :arg dict clean:
            :clean:
                * **after** (`bool`) - Clean the workspace after checkout
                * **before** (`bool`) - Clean the workspace before checkout

        :arg list(str) ignore-commits-with-messages: Revisions committed with
            messages matching these patterns will be ignored. (optional)

        :arg bool force-polling-using-workspace: Force polling using workspace
            (default false)

        :arg dict sparse-checkout:
            :sparse-checkout:
                * **paths** (`list`) - List of paths to sparse checkout.
                  (optional)

        :arg dict submodule:
            :submodule:
                * **disable** (`bool`) - By disabling support for submodules
                  you can still keep using basic git plugin functionality
                  and just have Jenkins to ignore submodules completely as
                  if they didn't exist.
                * **recursive** (`bool`) - Retrieve all submodules recursively
                  (uses '--recursive' option which requires git>=1.6.5)
                * **tracking** (`bool`) - Retrieve the tip of the configured
                  branch in .gitmodules (Uses '--remote' option which
                  requires git>=1.8.2)
                * **timeout** (`int`) - Specify a timeout (in minutes) for
                  submodules operations (default: 10).

        :arg str timeout: Timeout for git commands in minutes (optional)
        :arg bool wipe-workspace: Wipe out workspace before build
          (default true)

    :browser values:
        :auto:
        :assemblaweb:
        :bitbucketweb:
        :cgit:
        :fisheye:
        :gitblit:
        :githubweb:
        :gitiles:
        :gitlab:
        :gitlist:
        :gitoriousweb:
        :gitweb:
        :kiln:
        :microsoft-tfs-2013:
        :phabricator:
        :redmineweb:
        :rhodecode:
        :stash:
        :viewgit:

    :choosing-strategy values:
        :default:
        :inverse:
        :gerrit:

    Example:

    .. literalinclude:: /../../tests/scm/fixtures/git001.yaml
    """
    logger = logging.getLogger("%s:git" % __name__)

    # XXX somebody should write the docs for those with option name =
    # None so we have a sensible name/key for it.
    mapping = [
        # option, xml name, default value (text), attributes (hard coded)
        ("disable-submodules", 'disableSubmodules', False),
        ("recursive-submodules", 'recursiveSubmodules', False),
        (None, 'doGenerateSubmoduleConfigurations', False),
        ("use-author", 'authorOrCommitter', False),
        ("wipe-workspace", 'wipeOutWorkspace', True),
        ("prune", 'pruneBranches', False),
        ("fastpoll", 'remotePoll', False),
        ("git-tool", 'gitTool', "Default"),
        (None, 'submoduleCfg', '', {'class': 'list'}),
        ('basedir', 'relativeTargetDir', ''),
        ('reference-repo', 'reference', ''),
        ("git-config-name", 'gitConfigName', ''),
        ("git-config-email", 'gitConfigEmail', ''),
        ('skip-tag', 'skipTag', False),
        ('scm-name', 'scmName', ''),
        ("shallow-clone", "useShallowClone", False),
        ("ignore-notify", "ignoreNotifyCommit", False),
    ]

    choosing_strategies = {
        'default': 'hudson.plugins.git.util.DefaultBuildChooser',
        'gerrit': ('com.sonyericsson.hudson.plugins.'
                   'gerrit.trigger.hudsontrigger.GerritTriggerBuildChooser'),
        'inverse': 'hudson.plugins.git.util.InverseBuildChooser',
    }

    scm = XML.SubElement(xml_parent,
                         'scm', {'class': 'hudson.plugins.git.GitSCM'})
    XML.SubElement(scm, 'configVersion').text = '2'
    user = XML.SubElement(scm, 'userRemoteConfigs')
    if 'remotes' not in data:
        data['remotes'] = [{data.get('name', 'origin'): data.copy()}]
    for remoteData in data['remotes']:
        huser = XML.SubElement(user, 'hudson.plugins.git.UserRemoteConfig')
        remoteName = next(iter(remoteData.keys()))
        XML.SubElement(huser, 'name').text = remoteName
        remoteParams = next(iter(remoteData.values()))
        if 'refspec' in remoteParams:
            refspec = remoteParams['refspec']
        else:
            refspec = '+refs/heads/*:refs/remotes/' + remoteName + '/*'
        XML.SubElement(huser, 'refspec').text = refspec
        if 'url' in remoteParams:
            remoteURL = remoteParams['url']
        else:
            raise JenkinsJobsException('Must specify a url for git remote \"' +
                                       remoteName + '"')
        XML.SubElement(huser, 'url').text = remoteURL
        if 'credentials-id' in remoteParams:
            credentialsId = remoteParams['credentials-id']
            XML.SubElement(huser, 'credentialsId').text = credentialsId
    xml_branches = XML.SubElement(scm, 'branches')
    branches = data.get('branches', ['**'])
    for branch in branches:
        bspec = XML.SubElement(xml_branches, 'hudson.plugins.git.BranchSpec')
        XML.SubElement(bspec, 'name').text = branch
    excluded_users = '\n'.join(data.get('excluded-users', []))
    XML.SubElement(scm, 'excludedUsers').text = excluded_users
    if 'merge' in data:
        merge = data['merge']
        merge_strategies = ['default', 'resolve', 'recursive', 'octopus',
                            'ours', 'subtree']
        fast_forward_modes = ['FF', 'FF_ONLY', 'NO_FF']
        name = merge.get('remote', 'origin')
        branch = merge['branch']
        urc = XML.SubElement(scm, 'userMergeOptions')
        XML.SubElement(urc, 'mergeRemote').text = name
        XML.SubElement(urc, 'mergeTarget').text = branch
        strategy = merge.get('strategy', 'default')
        if strategy not in merge_strategies:
            raise InvalidAttributeError('strategy', strategy, merge_strategies)
        XML.SubElement(urc, 'mergeStrategy').text = strategy
        fast_forward_mode = merge.get('fast-forward-mode', 'FF')
        if fast_forward_mode not in fast_forward_modes:
            raise InvalidAttributeError('fast-forward-mode', fast_forward_mode,
                                        fast_forward_modes)
        XML.SubElement(urc, 'fastForwardMode').text = fast_forward_mode

    try:
        choosing_strategy = choosing_strategies[data.get('choosing-strategy',
                                                         'default')]
    except KeyError:
        raise ValueError('Invalid choosing-strategy %r' %
                         data.get('choosing-strategy'))
    XML.SubElement(scm, 'buildChooser', {'class': choosing_strategy})

    for elem in mapping:
        (optname, xmlname, val) = elem[:3]

        # Throw warning for deprecated settings and skip if the 'submodule' key
        # is available.
        submodule_cfgs = ['disable-submodules', 'recursive-submodules']
        if optname in submodule_cfgs:
            if optname in data:
                logger.warn("'{0}' is deprecated, please convert to use the "
                            "'submodule' section instead as support for this "
                            "top level option will be removed in a future "
                            "release.".format(optname))
            if 'submodule' in data:
                continue

        attrs = {}
        if len(elem) >= 4:
            attrs = elem[3]
        xe = XML.SubElement(scm, xmlname, attrs)
        if optname and optname in data:
            val = data[optname]
        if type(val) == bool:
            xe.text = str(val).lower()
        else:
            xe.text = val

    if 'local-branch' in data:
        XML.SubElement(scm, 'localBranch').text = data['local-branch']

    exts_node = XML.SubElement(scm, 'extensions')
    impl_prefix = 'hudson.plugins.git.extensions.impl.'
    if 'included-regions' in data or 'excluded-regions' in data:
        ext_name = XML.SubElement(exts_node,
                                  'hudson.plugins.git.extensions.impl.'
                                  'PathRestriction')
        if 'included-regions' in data:
            include_string = '\n'.join(data['included-regions'])
            XML.SubElement(ext_name, 'includedRegions').text = include_string
        if 'excluded-regions' in data:
            exclude_string = '\n'.join(data['excluded-regions'])
            XML.SubElement(ext_name, 'excludedRegions').text = exclude_string
    if 'changelog-against' in data:
        ext_name = impl_prefix + 'ChangelogToBranch'
        ext = XML.SubElement(exts_node, ext_name)
        opts = XML.SubElement(ext, 'options')
        change_remote = data['changelog-against'].get('remote', 'origin')
        change_branch = data['changelog-against'].get('branch', 'master')
        XML.SubElement(opts, 'compareRemote').text = change_remote
        XML.SubElement(opts, 'compareTarget').text = change_branch
    if 'clean' in data:
        # Keep support for old format 'clean' configuration by checking
        # if 'clean' is boolean. Else we're using the new extensions style.
        if isinstance(data['clean'], bool):
            clean_after = data['clean']
            clean_before = False
            logger.warn("'clean: bool' configuration format is deprecated, "
                        "please use the extension style format to configure "
                        "this option.")
        else:
            clean_after = data['clean'].get('after', False)
            clean_before = data['clean'].get('before', False)
        if clean_after:
            ext_name = impl_prefix + 'CleanCheckout'
            ext = XML.SubElement(exts_node, ext_name)
        if clean_before:
            ext_name = impl_prefix + 'CleanBeforeCheckout'
            ext = XML.SubElement(exts_node, ext_name)
    if 'ignore-commits-with-messages' in data:
        for msg in data['ignore-commits-with-messages']:
            ext_name = impl_prefix + 'MessageExclusion'
            ext = XML.SubElement(exts_node, ext_name)
            XML.SubElement(ext, 'excludedMessage').text = msg
    if 'sparse-checkout' in data:
        ext_name = impl_prefix + 'SparseCheckoutPaths'
        ext = XML.SubElement(exts_node, ext_name)
        sparse_co = XML.SubElement(ext, 'sparseCheckoutPaths')
        sparse_paths = data['sparse-checkout'].get('paths')
        if sparse_paths is not None:
            path_tagname = impl_prefix + 'SparseCheckoutPath'
            for path in sparse_paths:
                path_tag = XML.SubElement(sparse_co, path_tagname)
                XML.SubElement(path_tag, 'path').text = path
    if 'submodule' in data:
        ext_name = impl_prefix + 'SubmoduleOption'
        ext = XML.SubElement(exts_node, ext_name)
        XML.SubElement(ext, 'disableSubmodules').text = str(
            data['submodule'].get('disable', False)).lower()
        XML.SubElement(ext, 'recursiveSubmodules').text = str(
            data['submodule'].get('recursive', False)).lower()
        XML.SubElement(ext, 'trackingSubmodules').text = str(
            data['submodule'].get('tracking', False)).lower()
        XML.SubElement(ext, 'timeout').text = str(
            data['submodule'].get('timeout', 10))
    if 'timeout' in data:
        co = XML.SubElement(exts_node, impl_prefix + 'CheckoutOption')
        XML.SubElement(co, 'timeout').text = str(data['timeout'])
    polling_using_workspace = str(data.get('force-polling-using-workspace',
                                           False)).lower()
    if polling_using_workspace == 'true':
        ext_name = impl_prefix + 'DisableRemotePoll'
        ext = XML.SubElement(exts_node, ext_name)
    # By default we wipe the workspace
    wipe_workspace = str(data.get('wipe-workspace', True)).lower()
    if wipe_workspace == 'true':
        ext_name = impl_prefix + 'WipeWorkspace'
        ext = XML.SubElement(exts_node, ext_name)

    browser = data.get('browser', 'auto')
    browserdict = {'auto': 'auto',
                   'assemblaweb': 'AssemblaWeb',
                   'bitbucketweb': 'BitbucketWeb',
                   'cgit': 'CGit',
                   'fisheye': 'FisheyeGitRepositoryBrowser',
                   'gitblit': 'GitBlitRepositoryBrowser',
                   'githubweb': 'GithubWeb',
                   'gitiles': 'Gitiles',
                   'gitlab': 'GitLab',
                   'gitlist': 'GitList',
                   'gitoriousweb': 'GitoriousWeb',
                   'gitweb': 'GitWeb',
                   'kiln': 'KilnGit',
                   'microsoft-tfs-2013': 'TFS2013GitRepositoryBrowser',
                   'phabricator': 'Phabricator',
                   'redmineweb': 'RedmineWeb',
                   'rhodecode': 'RhodeCode',
                   'stash': 'Stash',
                   'viewgit': 'ViewGitWeb'}
    if browser not in browserdict:
        valid = sorted(browserdict.keys())
        raise JenkinsJobsException("Browser entered is not valid must be one "
                                   "of: %s or %s." % (", ".join(valid[:-1]),
                                                      valid[-1]))
    if browser != 'auto':
        bc = XML.SubElement(scm, 'browser', {'class':
                                             'hudson.plugins.git.browser.' +
                                             browserdict[browser]})
        XML.SubElement(bc, 'url').text = data['browser-url']
        if browser in ['gitblit', 'viewgit']:
            XML.SubElement(bc, 'projectName').text = str(
                data.get('project-name', ''))
        if browser == 'gitlab':
            XML.SubElement(bc, 'version').text = str(
                data.get('browser-version', '0.0'))
        if browser == 'phabricator':
            XML.SubElement(bc, 'repo').text = str(
                data.get('repo-name', ''))
示例#14
0
def authorization(registry, xml_parent, data):
    """yaml: authorization
    Specifies an authorization matrix

    .. _authorization:

    :arg list <name>: `<name>` is the name of the group or user, containing
        the list of rights to grant.

       :<name> rights:
            * **credentials-create**
            * **credentials-delete**
            * **credentials-manage-domains**
            * **credentials-update**
            * **credentials-view**
            * **job-build**
            * **job-cancel**
            * **job-configure**
            * **job-delete**
            * **job-discover**
            * **job-extended-read**
            * **job-move**
            * **job-read**
            * **job-status**
            * **job-workspace**
            * **ownership-jobs**
            * **run-delete**
            * **run-replay**
            * **run-update**
            * **scm-tag**

    Example:

    .. literalinclude:: /../../tests/properties/fixtures/authorization.yaml
       :language: yaml
    """

    # get the folder name if it exists
    in_a_folder = data.pop("_use_folder_perms")

    credentials = "com.cloudbees.plugins.credentials.CredentialsProvider."
    ownership = "com.synopsys.arc.jenkins.plugins.ownership.OwnershipPlugin."

    mapping = {
        "credentials-create": "".join((credentials, "Create")),
        "credentials-delete": "".join((credentials, "Delete")),
        "credentials-manage-domains": "".join((credentials, "ManageDomains")),
        "credentials-update": "".join((credentials, "Update")),
        "credentials-view": "".join((credentials, "View")),
        "job-build": "hudson.model.Item.Build",
        "job-cancel": "hudson.model.Item.Cancel",
        "job-configure": "hudson.model.Item.Configure",
        "job-delete": "hudson.model.Item.Delete",
        "job-discover": "hudson.model.Item.Discover",
        "job-extended-read": "hudson.model.Item.ExtendedRead",
        "job-move": "hudson.model.Item.Move",
        "job-read": "hudson.model.Item.Read",
        "job-status": "hudson.model.Item.ViewStatus",
        "job-workspace": "hudson.model.Item.Workspace",
        "ownership-jobs": "".join((ownership, "Jobs")),
        "run-delete": "hudson.model.Run.Delete",
        "run-replay": "hudson.model.Run.Replay",
        "run-update": "hudson.model.Run.Update",
        "scm-tag": "hudson.scm.SCM.Tag",
    }

    if data:
        if in_a_folder:
            matrix = XML.SubElement(
                xml_parent,
                "com.cloudbees.hudson.plugins.folder.properties.AuthorizationMatrixProperty",
            )
            XML.SubElement(
                matrix,
                "inheritanceStrategy",
                {
                    "class":
                    "org.jenkinsci.plugins.matrixauth.inheritance.InheritParentStrategy"
                },
            )
        else:
            matrix = XML.SubElement(
                xml_parent, "hudson.security.AuthorizationMatrixProperty")

        for (username, perms) in data.items():
            for perm in perms:
                pe = XML.SubElement(matrix, "permission")
                try:
                    pe.text = "{0}:{1}".format(mapping[perm], username)
                except KeyError:
                    raise InvalidAttributeError(username, perm, mapping.keys())