Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 35 additions & 8 deletions jenkinsapi/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,14 @@ def __init__(self, url: str, name: str, jenkins_obj: "Jenkins") -> None:
self._scm_prefix = ""
self._scm_map = {
"hudson.scm.SubversionSCM": "svn",
"jenkins.scm.impl.subversion.SubversionSCMSource": "svn",
"hudson.plugins.git.GitSCM": "git",
"jenkins.plugins.git.GitSCMSource": "git",
"hudson.plugins.mercurial.MercurialSCM": "hg",
"org.jenkinsci.plugins.github_branch_source.GitHubSCMSource": "github",
"com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMSource": "bitbucket",
"io.jenkins.plugins.gitlabbranchsource.GitLabSCMSource": "gitlab",
"org.jenkinsci.plugins.gitea.GiteaSCMSource": "gitea",
"hudson.scm.NullSCM": "NullSCM",
}
self._scmurlmap = {
Expand Down Expand Up @@ -528,17 +534,38 @@ def get_config(self):
def load_config(self):
self._config = self.get_config()

def _get_scm_from_branch_job_property(self, element_tree):
"""Check element_tree for BranchJobProperty"""
scm_element = None
log.debug("Check BranchJobProperty for scm type")
multibranch_scm_prefix = "properties/org.jenkinsci.plugins.\
workflow.multibranch.BranchJobProperty/branch/"
multibranch_path = multibranch_scm_prefix + "scm"
scm_element = element_tree.find(multibranch_path)
return scm_element

def _get_scm_from_branch_source(self, element_tree):
"""Check for scm type from BranchSource"""
source_class = None
log.debug("Check BranchSource for scm type")
branch_source_path = ".//sources//data//jenkins.branch.BranchSource"
scm_element = element_tree.find(branch_source_path)
if not scm_element:
scm_element = element_tree.find(".//sources/..")

if scm_element:
source_class = scm_element.find(".//source")

return source_class

def get_scm_type(self):
element_tree = self._get_config_element_tree()
scm_element = element_tree.find("scm")
scm_element = element_tree.find(".//scm")
if not scm_element:
scm_element = self._get_scm_from_branch_job_property(element_tree)
if not scm_element:
multibranch_scm_prefix = "properties/org.jenkinsci.plugins.\
workflow.multibranch.BranchJobProperty/branch/"
multibranch_path = multibranch_scm_prefix + "scm"
scm_element = element_tree.find(multibranch_path)
if scm_element:
# multibranch pipeline.
self._scm_prefix = multibranch_scm_prefix
scm_element = self._get_scm_from_branch_source(element_tree)

scm_class = scm_element.get("class") if scm_element else None
scm = self._scm_map.get(scm_class)
if not scm:
Expand Down
12 changes: 12 additions & 0 deletions jenkinsapi_tests/systests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@

# Extra plugins required by the systests
PLUGIN_DEPENDENCIES = [
"https://updates.jenkins.io/latest/cloudbees-folder.hpi",
"https://updates.jenkins.io/latest/branch-api.hpi",
"https://updates.jenkins.io/latest/workflow-job.hpi",
"https://updates.jenkins.io/latest/workflow-cps.hpi",
"https://updates.jenkins.io/latest/workflow-multibranch.hpi",
"https://updates.jenkins.io/latest/okhttp-api.hpi",
"https://updates.jenkins.io/latest/github-api.hpi",
"https://updates.jenkins.io/latest/json-path-api.hpi",
"https://updates.jenkins.io/latest/token-macro.hpi",
"https://updates.jenkins.io/latest/github.hpi",
"https://updates.jenkins.io/latest/jjwt-api.hpi",
"https://updates.jenkins.io/latest/github-branch-source.hpi",
"https://updates.jenkins.io/latest/apache-httpcomponents-client-4-api.hpi",
"https://updates.jenkins.io/latest/mina-sshd-api-common.hpi",
"https://updates.jenkins.io/latest/mina-sshd-api-core.hpi",
Expand Down
167 changes: 167 additions & 0 deletions jenkinsapi_tests/systests/job_configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,3 +339,170 @@
</buildWrappers>
</project>
""".strip()

PIPELINE_SCM_JOB = """
<?xml version='1.0' encoding='UTF-8'?>
<flow-definition>
<definition class="org.jenkinsci.plugins.workflow.cps.CpsScmFlowDefinition">
<scm class="hudson.plugins.git.GitSCM">
<configVersion>2</configVersion>
<userRemoteConfigs>
<hudson.plugins.git.UserRemoteConfig>
<url>https://github.com/salimfadhley/jenkinsapi.git</url>
</hudson.plugins.git.UserRemoteConfig>
</userRemoteConfigs>
<branches>
<hudson.plugins.git.BranchSpec>
<name>main</name>
</hudson.plugins.git.BranchSpec>
</branches>
</scm>
</definition>
</flow-definition>""".strip()

MULTIBRANCH_GIT_SCM_JOB = """
<?xml version='1.0' encoding='UTF-8'?>
<org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject plugin="[email protected]_4ea_780798">
<actions/>
<description/>
<properties/>
<folderViews class="jenkins.branch.MultiBranchProjectViewHolder" plugin="[email protected]">
<owner class="org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject" reference="../.."/>
</folderViews>
<healthMetrics/>
<icon class="jenkins.branch.MetadataActionFolderIcon" plugin="[email protected]">
<owner class="org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject" reference="../.."/>
</icon>
<orphanedItemStrategy class="com.cloudbees.hudson.plugins.folder.computed.DefaultOrphanedItemStrategy" plugin="[email protected]_7888eb_dd514">
<pruneDeadBranches>true</pruneDeadBranches>
<daysToKeep>-1</daysToKeep>
<numToKeep>-1</numToKeep>
<abortBuilds>false</abortBuilds>
</orphanedItemStrategy>
<triggers/>
<disabled>false</disabled>
<sources class="jenkins.branch.MultiBranchProject$BranchSourceList" plugin="[email protected]">
<data>
<jenkins.branch.BranchSource>
<source class="jenkins.plugins.git.GitSCMSource" plugin="[email protected]">
<id>e0a4ce06-e537-4893-9ba4-2dd4f18d7a44</id>
<remote>https://github.com/pycontribs/jenkinsapi</remote>
<credentialsId/>
<traits>
<jenkins.plugins.git.traits.BranchDiscoveryTrait/>
<jenkins.scm.impl.trait.RegexSCMHeadFilterTrait plugin="[email protected]">
<regex>(master.*)</regex>
</jenkins.scm.impl.trait.RegexSCMHeadFilterTrait>
</traits>
</source>
<strategy class="jenkins.branch.DefaultBranchPropertyStrategy">
<properties class="empty-list"/>
</strategy>
</jenkins.branch.BranchSource>
</data>
<owner class="org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject" reference="../.."/>
</sources>
<factory class="org.jenkinsci.plugins.workflow.multibranch.WorkflowBranchProjectFactory">
<owner class="org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject" reference="../.."/>
<scriptPath>uv.lock</scriptPath>
</factory>
</org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject>
""".strip()

MULTIBRANCH_GIT_BRANCH_JOB_PROPERTY = """
<?xml version='1.0' encoding='UTF-8'?>
<flow-definition plugin="[email protected]_a_533730b_ea_d">
<actions/>
<keepDependencies>false</keepDependencies>
<properties>
<org.jenkinsci.plugins.workflow.multibranch.BranchJobProperty plugin="[email protected]_4ea_780798">
<branch plugin="[email protected]">
<sourceId>bc1f7bd0-b8d0-48db-ac98-bcae92939715</sourceId>
<head plugin="[email protected]">
<name>a</name>
</head>
<scm class="hudson.plugins.git.GitSCM" plugin="[email protected]">
<configVersion>2</configVersion>
<userRemoteConfigs>
<hudson.plugins.git.UserRemoteConfig>
<url>https://github.com/pycontribs/jenkinsapi.git</url>
</hudson.plugins.git.UserRemoteConfig>
</userRemoteConfigs>
<branches>
<hudson.plugins.git.BranchSpec>
<name>*/master</name>
</hudson.plugins.git.BranchSpec>
</branches>
<doGenerateSubmoduleConfigurations>false</doGenerateSubmoduleConfigurations>
<submoduleCfg class="empty-list"/>
<extensions/>
</scm>
<properties/>
<actions/>
</branch>
</org.jenkinsci.plugins.workflow.multibranch.BranchJobProperty>
</properties>
<definition class="org.jenkinsci.plugins.workflow.multibranch.SCMBinder" plugin="[email protected]_4ea_780798">
<scriptPath>uv.lock</scriptPath>
</definition>
<triggers/>
<disabled>false</disabled>
</flow-definition>
""".strip()

MULTIBRANCH_GITHUB_SCM_JOB = """
<?xml version='1.0' encoding='UTF-8'?>
<org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject plugin="[email protected]_4ea_780798">
<actions/>
<description/>
<properties/>
<folderViews class="jenkins.branch.MultiBranchProjectViewHolder" plugin="[email protected]">
<owner class="org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject" reference="../.."/>
</folderViews>
<healthMetrics/>
<icon class="jenkins.branch.MetadataActionFolderIcon" plugin="[email protected]">
<owner class="org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject" reference="../.."/>
</icon>
<orphanedItemStrategy class="com.cloudbees.hudson.plugins.folder.computed.DefaultOrphanedItemStrategy" plugin="[email protected]_7888eb_dd514">
<pruneDeadBranches>true</pruneDeadBranches>
<daysToKeep>-1</daysToKeep>
<numToKeep>-1</numToKeep>
<abortBuilds>false</abortBuilds>
</orphanedItemStrategy>
<triggers/>
<disabled>false</disabled>
<sources class="jenkins.branch.MultiBranchProject$BranchSourceList" plugin="[email protected]">
<data>
<jenkins.branch.BranchSource>
<source class="org.jenkinsci.plugins.github_branch_source.GitHubSCMSource" plugin="[email protected]_39b_3d0d">
<id>e82f0840-83c9-44b3-a903-3825f776da38</id>
<apiUri>https://api.github.com</apiUri>
<repoOwner>pycontribs</repoOwner>
<repository>jenkinsapi</repository>
<repositoryUrl>https://github.com/pycontribs/jenkinsapi</repositoryUrl>
<traits>
<org.jenkinsci.plugins.github__branch__source.BranchDiscoveryTrait>
<strategyId>1</strategyId>
</org.jenkinsci.plugins.github__branch__source.BranchDiscoveryTrait>
<org.jenkinsci.plugins.github__branch__source.OriginPullRequestDiscoveryTrait>
<strategyId>2</strategyId>
</org.jenkinsci.plugins.github__branch__source.OriginPullRequestDiscoveryTrait>
<org.jenkinsci.plugins.github__branch__source.ForkPullRequestDiscoveryTrait>
<strategyId>2</strategyId>
<trust class="org.jenkinsci.plugins.github_branch_source.ForkPullRequestDiscoveryTrait$TrustPermission"/>
</org.jenkinsci.plugins.github__branch__source.ForkPullRequestDiscoveryTrait>
</traits>
</source>
<strategy class="jenkins.branch.DefaultBranchPropertyStrategy">
<properties class="empty-list"/>
</strategy>
</jenkins.branch.BranchSource>
</data>
<owner class="org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject" reference="../.."/>
</sources>
<factory class="org.jenkinsci.plugins.workflow.multibranch.WorkflowBranchProjectFactory">
<owner class="org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject" reference="../.."/>
<scriptPath>uv.lock</scriptPath>
</factory>
</org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject>
"""
99 changes: 70 additions & 29 deletions jenkinsapi_tests/systests/test_scm.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,73 @@
# '''
# System tests for `jenkinsapi.jenkins` module.
# '''
# To run unittests on python 2.6 please use unittest2 library
# try:
# import unittest2 as unittest
# except ImportError:
# import unittest
# from jenkinsapi_tests.systests.base import BaseSystemTest
# from jenkinsapi_tests.test_utils.random_strings import random_string
# from jenkinsapi_tests.systests.job_configs import SCM_GIT_JOB

# # Maybe have a base class for all SCM test activites?
# class TestSCMGit(BaseSystemTest):
# # Maybe it makes sense to move plugin dependencies outside the code.
# # Have a config to dependencies mapping from the launcher can use
# # to install plugins.
# def test_get_revision(self):
# job_name = 'git_%s' % random_string()
# job = self.jenkins.create_job(job_name, SCM_GIT_JOB)
# ii = job.invoke()
# ii.block(until='completed')
# self.assertFalse(ii.is_running())
# b = ii.get_build()
# try:
# self.assertIsInstance(b.get_revision(), basestring)
# except NameError:
# # Python3
# self.assertIsInstance(b.get_revision(), str)

# if __name__ == '__main__':
# unittest.main()
from testfixtures import compare
from time import sleep

from jenkinsapi_tests.test_utils.random_strings import random_string
from jenkinsapi_tests.systests.job_configs import (
SCM_GIT_JOB,
MULTIBRANCH_GIT_BRANCH_JOB_PROPERTY,
MULTIBRANCH_GIT_SCM_JOB,
MULTIBRANCH_GITHUB_SCM_JOB,
)


def wait_for_job_setup(jenkins, job_name):
for _ in range(5):
for _url, name in list(jenkins.get_jobs_info()):
if job_name in name:
return True
else:
sleep(10)


def test_get_scm_type(jenkins):
job_name = "git_%s" % random_string()
job = jenkins.create_job(job_name, SCM_GIT_JOB)
queueItem = job.invoke()
queueItem.block_until_complete()

wait_for_job_setup(jenkins, job_name)
compare(job.get_scm_type(), "git")
jenkins.delete_job(job_name)


def test_get_scm_type_pipeline_scm_multibranch_BranchJobProperty(
jenkins,
):
job_name = "git_%s" % random_string()
job = jenkins.create_job(job_name, MULTIBRANCH_GIT_BRANCH_JOB_PROPERTY)
queueItem = job.invoke()
queueItem.block_until_complete()
wait_for_job_setup(jenkins, job_name)
compare(job.get_scm_type(), "git")


## Disabling for now, running into permissions errors
def test_get_scm_type_pipeline_scm_multibranch_BranchSource(
jenkins,
):
job_name = "git_%s" % random_string()
job = jenkins.create_multibranch_pipeline_job(
job_name, MULTIBRANCH_GIT_SCM_JOB
)
queueItem = job.invoke()
queueItem.block_until_complete()
wait_for_job_setup(jenkins, job_name)
job.invoke(block=True, delay=20)
compare(job[0].get_scm_type(), "git")


def test_get_scm_type_pipeline_github_multibranch_BranchSource(
jenkins,
):
job_name = "git_%s" % random_string()
job = jenkins.create_multibranch_pipeline_job(
job_name, MULTIBRANCH_GITHUB_SCM_JOB
)
queueItem = job.invoke()
queueItem.block_until_complete()
wait_for_job_setup(jenkins, job_name)
job.invoke(block=True, delay=20)
compare(job.get_scm_type(), "github")
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ dev = [
"mock>=5.1.0",
"requests-kerberos>=0.15.0",
"ruff>=0.9.6",
"testfixtures>=8.3.0",
]
docs = [
"docutils>=0.20.1",
Expand Down
Loading
Loading