Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F96132958
PhabricatorJenkinsJobController.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sun, Dec 22, 23:45
Size
22 KB
Mime Type
text/x-php
Expires
Tue, Dec 24, 23:45 (2 d)
Engine
blob
Format
Raw Data
Handle
23128961
Attached To
rPH Phabricator
PhabricatorJenkinsJobController.php
View Options
<?php
final
class
PhabricatorJenkinsJobController
extends
PhabricatorController
{
protected
function
buildSideNav
()
{
$nav
=
new
AphrontSideNavFilterView
();
$nav
->
setBaseURI
(
new
PhutilURI
(
'/jobs/'
));
$nav
->
addLabel
(
pht
(
'Jenkins Jobs'
));
$nav
->
addFilter
(
'list'
,
'List Jobs'
);
$nav
->
addFilter
(
'create'
,
'Create Job'
);
$nav
->
selectFilter
(
null
);
return
$nav
;
}
public
function
buildApplicationMenu
()
{
return
$this
->
buildSideNav
()->
getMenu
();
}
protected
function
buildApplicationCrumbs
()
{
$crumbs
=
parent
::
buildApplicationCrumbs
();
return
$crumbs
;
}
public
function
shouldAllowPublic
()
{
return
false
;
}
public
function
handleRequest
(
AphrontRequest
$request
)
{
if
(
$request
->
getPath
()
==
'/jobs/create/'
)
{
return
$this
->
handleCreate
(
$request
);
}
else
if
(
strpos
(
$request
->
getPath
(),
'/jobs/delete/'
)
===
0
)
{
return
$this
->
handleDelete
(
$request
);
}
return
$this
->
handleList
(
$request
);
}
private
static
function
createJob
(
$repo
,
$proj
,
$branch
,
$viewer
)
{
$errors
=
array
();
if
(!
empty
(
$repo
)
&&
!
empty
(
$proj
)
&&
!
empty
(
$branch
))
{
$repo
=
head
(
$repo
);
// Get Repository information
$repo_query
=
id
(
new
PhabricatorRepositoryQuery
())
->
withPHIDs
(
array
(
$repo
))
->
setViewer
(
$viewer
)
->
needURIs
(
true
)
->
executeOne
();
if
(!
$repo_query
)
{
$errors
[]
=
"Repository '$repo' doesn't exist."
;
return
$errors
;
}
$repo_name
=
$repo_query
->
getCloneName
();
$repo_id
=
$repo_query
->
getID
();
$repo_browse
=
$repo_query
->
getURI
();
$job_name
=
self
::
getJobName
(
$repo_name
,
$repo_id
,
$branch
);
$job_token
=
hash
(
'sha256'
,
microtime
(
true
).
mt_rand
());
$username
=
$viewer
->
getUsername
();
if
(!
$repo_query
->
isGit
())
{
$errors
[]
=
"'$repo_name' is not a GIT Repository."
;
return
$errors
;
}
// Check branch
$branches
=
DiffusionQuery
::
callConduitWithDiffusionRequest
(
$viewer
,
DiffusionRequest
::
newFromDictionary
(
array
(
'repository'
=>
$repo_query
,
'user'
=>
$viewer
,
)),
'diffusion.branchquery'
,
array
(
'repository'
=>
$repo_query
->
getPHID
(),
));
$branches
=
ipull
(
$branches
,
'shortName'
);
if
(!
in_array
(
$branch
,
$branches
))
{
$errors
[]
=
"Branch '$branch' doesn't exist for Repository '$repo_name'."
;
return
$errors
;
}
// Get URI
$display_never
=
PhabricatorRepositoryURI
::
DISPLAY_NEVER
;
$repo_cred
=
PhabricatorEnv
::
getEnvConfig
(
'jenkins.repo_cred'
);
$repo_uri
=
''
;
foreach
(
$repo_query
->
getURIs
()
as
$uri
)
{
if
(
$uri
->
getIsDisabled
()
||
$uri
->
getEffectiveDisplayType
()
==
$display_never
)
{
continue
;
}
if
(
strpos
(
$uri
->
getDisplayURI
(),
'ssh://'
)
===
0
)
{
$repo_uri
=
(
string
)
$uri
->
getDisplayURI
();
break
;
}
}
if
(
empty
(
$repo_uri
))
{
$errors
[]
=
'Repository has no URI.'
;
return
$errors
;
}
// Jenkins Job configuration
$proj_xml
=
''
;
foreach
(
$proj
as
$p
)
{
$proj_xml
.=
<<<EOF
<permission>hudson.model.Item.Cancel:$p</permission>
<permission>hudson.model.Item.Read:$p</permission>
<permission>hudson.model.Run.Delete:$p</permission>
<permission>hudson.model.Item.Build:$p</permission>
<permission>hudson.model.Run.Replay:$p</permission>
<permission>hudson.model.Item.ViewStatus:$p</permission>
<permission>hudson.model.Run.Update:$p</permission>
EOF;
}
$job_xml
=
<<<EOF
<?xml version='1.0' encoding='UTF-8'?>
<flow-definition plugin="workflow-job@2.10">
<actions/>
<description></description>
<keepDependencies>false</keepDependencies>
<properties>
<hudson.security.AuthorizationMatrixProperty>
$proj_xml
<permission>hudson.model.Item.Cancel:$username</permission>
<permission>hudson.model.Item.Read:$username</permission>
<permission>hudson.model.Run.Delete:$username</permission>
<permission>hudson.model.Item.Build:$username</permission>
<permission>hudson.model.Run.Replay:$username</permission>
<permission>hudson.model.Item.ViewStatus:$username</permission>
<permission>hudson.model.Run.Update:$username</permission>
</hudson.security.AuthorizationMatrixProperty>
<!--<hudson.model.ParametersDefinitionProperty>
<parameterDefinitions>
<hudson.model.StringParameterDefinition>
<name>PHID</name>
<description/>
<defaultValue/>
</hudson.model.StringParameterDefinition>
<hudson.model.StringParameterDefinition>
<name>DIFF_ID</name>
<description/>
<defaultValue/>
</hudson.model.StringParameterDefinition>
</parameterDefinitions>
</hudson.model.ParametersDefinitionProperty>
-->
<org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty>
<triggers/>
</org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty>
</properties>
<definition class="org.jenkinsci.plugins.workflow.cps.CpsScmFlowDefinition" plugin="workflow-cps@2.30">
<scm class="hudson.plugins.git.GitSCM" plugin="git@3.3.0">
<configVersion>2</configVersion>
<userRemoteConfigs>
<hudson.plugins.git.UserRemoteConfig>
<url>$repo_uri</url>
<credentialsId>$repo_cred</credentialsId>
</hudson.plugins.git.UserRemoteConfig>
</userRemoteConfigs>
<branches>
<hudson.plugins.git.BranchSpec>
<name>refs/heads/$branch</name>
</hudson.plugins.git.BranchSpec>
</branches>
<doGenerateSubmoduleConfigurations>false</doGenerateSubmoduleConfigurations>
<browser class="hudson.plugins.git.browser.Phabricator">
<url>$repo_browse</url>
<repo>$repo_name</repo>
</browser>
<submoduleCfg class="list"/>
<extensions/>
</scm>
<scriptPath>Jenkinsfile</scriptPath>
<lightweight>true</lightweight>
</definition>
<triggers/>
<authToken>$job_token</authToken>
</flow-definition>
EOF;
$jenkins_user
=
PhabricatorEnv
::
getEnvConfig
(
'jenkins.user'
);
$jenkins_token
=
new
PhutilOpaqueEnvelope
(
PhabricatorEnv
::
getEnvConfig
(
'jenkins.token'
));
$jenkins_url
=
PhabricatorEnv
::
getEnvConfig
(
'jenkins.url'
);
// Get CSRF cookie from Jenkins
$csrf
=
self
::
getJenkinsCsrf
(
$jenkins_url
,
$jenkins_user
,
$jenkins_token
);
// Check if Job already exists
$url
=
$jenkins_url
.
"/checkJobName?value=$job_name"
;
$future
=
id
(
new
HTTPSFuture
(
$url
))
->
addHeader
(
$csrf
[
0
],
$csrf
[
1
])
->
setHTTPBasicAuthCredentials
(
$jenkins_user
,
$jenkins_token
);
list
(
$status
,
$body
,
$headers
)
=
$future
->
resolve
();
if
(
strpos
(
$body
,
'job already exists'
)
!==
false
)
{
$errors
[]
=
"A job already exists with the name '$job_name'."
;
return
$errors
;
}
if
(
$status
->
getStatusCode
()
!==
200
)
{
$errors
[]
=
phutil_tag
(
$status
->
getMessage
());
return
$errors
;
}
// Create Jenkins Job
$url
=
$jenkins_url
.
"/createItem?name=$job_name"
;
$future
=
id
(
new
HTTPSFuture
(
$url
))
->
setData
(
$job_xml
)
->
addHeader
(
'Content-Type'
,
'text/xml'
)
->
addHeader
(
$csrf
[
0
],
$csrf
[
1
])
->
setHTTPBasicAuthCredentials
(
$jenkins_user
,
$jenkins_token
)
->
setMethod
(
'POST'
);
list
(
$status
,
$body
,
$headers
)
=
$future
->
resolve
();
if
(
$status
->
getStatusCode
()
!==
200
)
{
$errors
[]
=
phutil_tag
(
$status
->
getMessage
());
return
$errors
;
}
// Custom policy
$rules
=
array
(
array
(
'action'
=>
PhabricatorPolicy
::
ACTION_ALLOW
,
'rule'
=>
'PhabricatorProjectsPolicyRule'
,
'value'
=>
$proj
,
)
);
$policy
=
id
(
new
PhabricatorPolicy
())
->
setRules
(
$rules
)
->
save
();
// Create Harbormaster Build Plan
$plan
=
HarbormasterBuildPlan
::
initializeNewBuildPlan
(
$viewer
)
->
setName
(
$job_name
.
' on jenkins'
)
->
setViewPolicy
(
$policy
->
getPHID
())
->
setEditPolicy
(
$policy
->
getPHID
())
->
save
();
$project_type
=
PhabricatorProjectObjectHasProjectEdgeType
::
EDGECONST
;
$xactions
=
array
();
$xactions
[]
=
id
(
new
HarbormasterBuildPlanTransaction
())
->
setTransactionType
(
PhabricatorTransactions
::
TYPE_EDGE
)
->
setMetadataValue
(
'edge:type'
,
$project_type
)
->
setNewValue
(
array
(
'='
=>
array_fuse
(
$proj
)));
$editor
=
id
(
new
HarbormasterBuildPlanEditor
())
->
setActor
(
$viewer
)
->
setContentSource
(
PhabricatorContentSource
::
newForSource
(
'web'
))
->
applyTransactions
(
$plan
,
$xactions
);
$step
=
HarbormasterBuildStep
::
initializeNewStep
(
$viewer
)
->
setBuildPlanPHID
(
$plan
->
getPHID
())
->
setClassName
(
'HarbormasterHTTPRequestBuildStepImplementation'
)
// ->setDetail('builtin.wait-for-message', 'wait')
->
setDetail
(
'method'
,
'GET'
)
->
setDetail
(
'uri'
,
$jenkins_url
.
"/buildByToken/build?job=${job_name}&token=${job_token}"
)
// ->setDetail('uri', $jenkins_url .
// '/buildByToken/buildWithParameters?' .
// 'DIFF_ID=\${buildable.diff}&' .
// 'PHID=\${target.phid}&' .
// "token=$job_token&job=$job_name")
->
setName
(
'Start Job on Jenkins'
)
->
save
();
// Create Herald Rule
$herald
=
id
(
new
HeraldRule
())
->
setMustMatchAll
(
true
)
->
setAuthorPHID
(
$viewer
->
getPHID
())
->
setRuleType
(
HeraldRuleTypeConfig
::
RULE_TYPE_OBJECT
)
->
setRepetitionPolicy
(
1
)
->
setTriggerObjectPHID
(
$repo
)
->
setContentType
(
'commit'
)
->
setName
(
"Run Jenkins Job $job_name on new commit"
)
->
save
();
$branch_escaped
=
str_replace
(
'/'
,
'
\\
/'
,
$branch
);
$conditions
=
array
(
id
(
new
HeraldCondition
())
->
setFieldName
(
'diffusion.commit.repository'
)
->
setFieldCondition
(
'isany'
)
->
setValue
(
array
(
$repo
))
->
setRuleID
(
$herald
->
getID
())
->
save
(),
id
(
new
HeraldCondition
())
->
setFieldName
(
'diffusion.commit.branches'
)
->
setFieldCondition
(
'regexp'
)
->
setValue
(
"/^${branch_escaped}$/"
)
->
setRuleID
(
$herald
->
getID
())
->
save
(),
);
$herald
->
attachConditions
(
$conditions
);
$actions
=
array
(
id
(
new
HeraldActionRecord
())
->
setAction
(
'harbormaster.build'
)
->
setTarget
(
array
(
$plan
->
getPHID
()))
->
setRuleID
(
$herald
->
getID
())
->
save
(),
);
$herald
->
attachActions
(
$actions
);
// Create Job object
$job
=
id
(
new
PhabricatorJenkinsJob
())
->
setRepository
(
$repo
)
->
setProject
(
implode
(
','
,
$proj
))
->
setBuildPlan
(
$plan
->
getPHID
())
->
setRule
(
$herald
->
getPHID
())
->
setViewPolicy
(
$policy
->
getPHID
())
->
setEditPolicy
(
$policy
->
getPHID
())
->
setOwnerPHID
(
$viewer
->
getPHID
())
->
setBranch
(
$branch
);
try
{
$job
->
save
();
}
catch
(
AphrontDuplicateKeyQueryException
$ex
)
{
$errors
[]
=
pht
(
'Only one job per repository and branch is allowed.'
);
self
::
deleteJenkinsJob
(
$job_name
,
$viewer
);
self
::
disableHerald
(
$herald
,
$viewer
);
self
::
disableBuildPlan
(
$plan
,
$viewer
);
}
}
else
{
if
(
empty
(
$repo
))
{
$errors
[]
=
pht
(
'You must specify a Repository.'
);
}
if
(
empty
(
$proj
))
{
$errors
[]
=
pht
(
'You must specify a Project.'
);
}
if
(
empty
(
$branch
))
{
$errors
[]
=
pht
(
'You must specify a Branch.'
);
}
}
return
$errors
;
}
private
static
function
deleteJenkinsJob
(
$job_name
,
$viewer
)
{
$jenkins_url
=
PhabricatorEnv
::
getEnvConfig
(
'jenkins.url'
);
$jenkins_user
=
PhabricatorEnv
::
getEnvConfig
(
'jenkins.user'
);
$jenkins_token
=
new
PhutilOpaqueEnvelope
(
PhabricatorEnv
::
getEnvConfig
(
'jenkins.token'
));
$csrf
=
self
::
getJenkinsCsrf
(
$jenkins_url
,
$jenkins_user
,
$jenkins_token
);
$url
=
$jenkins_url
.
"/job/$job_name/doDelete"
;
$future
=
id
(
new
HTTPSFuture
(
$url
))
->
addHeader
(
$csrf
[
0
],
$csrf
[
1
])
->
setHTTPBasicAuthCredentials
(
$jenkins_user
,
$jenkins_token
)
->
setMethod
(
'POST'
);
list
(
$status
,
$body
,
$headers
)
=
$future
->
resolve
();
}
private
static
function
disableHerald
(
$herald
,
$viewer
)
{
$xaction
=
id
(
new
HeraldRuleTransaction
())
->
setTransactionType
(
HeraldRuleTransaction
::
TYPE_DISABLE
)
->
setNewValue
(
true
);
id
(
new
HeraldRuleEditor
())
->
setActor
(
$viewer
)
->
setContentSource
(
PhabricatorContentSource
::
newForSource
(
'web'
))
->
applyTransactions
(
$herald
,
array
(
$xaction
));
}
private
function
disableBuildPlan
(
$plan
,
$viewer
)
{
$xaction
=
id
(
new
HarbormasterBuildPlanTransaction
())
->
setTransactionType
(
HarbormasterBuildPlanTransaction
::
TYPE_STATUS
)
->
setNewValue
(
HarbormasterBuildPlan
::
STATUS_DISABLED
);
id
(
new
HarbormasterBuildPlanEditor
())
->
setActor
(
$viewer
)
->
setContentSource
(
PhabricatorContentSource
::
newForSource
(
'web'
))
->
applyTransactions
(
$plan
,
array
(
$xaction
));
}
private
function
handleDelete
(
AphrontRequest
$request
)
{
$errors
=
array
();
$text
=
''
;
$viewer
=
$request
->
getViewer
();
$job_id
=
$request
->
getInt
(
'job'
,
-
1
);
$job
=
id
(
new
PhabricatorJenkinsJobQuery
())
->
setViewer
(
$viewer
)
->
withIDs
(
array
(
$job_id
))
->
executeOne
();
if
(!
$job
)
{
$errors
[]
=
"Job with id $job_id doesn't exist."
;
}
else
{
// Show dialog
$repo
=
id
(
new
PhabricatorRepositoryQuery
())
->
setViewer
(
$viewer
)
->
withPHIDs
(
array
(
$job
->
getRepository
()))
->
executeOne
();
$job_name
=
self
::
getJobName
(
$repo
->
getCloneName
(),
$repo
->
getID
(),
$job
->
getBranch
());
$plan_phid
=
$job
->
getBuildPlan
();
$plan
=
id
(
new
HarbormasterBuildPlanQuery
())
->
setViewer
(
$viewer
)
->
withPHIDs
(
array
(
$plan_phid
))
->
executeOne
();
$herald_phid
=
$job
->
getRule
();
$herald
=
id
(
new
HeraldRuleQuery
())
->
setViewer
(
$viewer
)
->
withPHIDs
(
array
(
$herald_phid
))
->
executeOne
();
$text
=
"Are you sure you want to delete the Job '$job_name' ?"
;
// Confirm and delete
if
(
$request
->
isFormPost
())
{
self
::
deleteJenkinsJob
(
$job_name
,
$viewer
);
self
::
disableHerald
(
$herald
,
$viewer
);
self
::
disableBuildPlan
(
$plan
,
$viewer
);
$job
->
delete
();
return
id
(
new
AphrontRedirectResponse
())->
setURI
(
'/jobs/list/'
);
}
}
$dialog
=
id
(
new
AphrontDialogView
())
->
setUser
(
$viewer
)
->
setErrors
(
$errors
)
->
setWidth
(
AphrontDialogView
::
WIDTH_FORM
)
->
setTitle
(
pht
(
'Delete Jenkins Job'
))
->
appendChild
(
$text
)
->
addCancelButton
(
'/jobs'
);
if
(
empty
(
$errors
))
{
$dialog
->
addSubmitButton
(
pht
(
'Delete'
));
}
return
$dialog
;
}
private
function
handleCreate
(
AphrontRequest
$request
)
{
$project
=
$request
->
getStr
(
'with_project'
,
null
);
$dialog
=
self
::
createForm
(
$request
,
$project
);
return
$dialog
;
}
public
static
function
createForm
(
$request
,
$with_project
)
{
$viewer
=
$request
->
getViewer
();
$errors
=
array
();
$repo
=
array
();
$proj
=
array
();
$branch
=
'master'
;
if
(
$request
->
isFormPost
())
{
// Get form values
$repo
=
$request
->
getArr
(
'repository'
,
array
());
$proj
=
$request
->
getArr
(
'project'
,
array
(
$with_project
));
$branch
=
$request
->
getStr
(
'branch'
,
'master'
);
// Create the Job
$errors
=
self
::
createJob
(
$repo
,
$proj
,
$branch
,
$viewer
);
if
(!
$errors
)
{
return
id
(
new
AphrontRedirectResponse
())->
setURI
(
'/jobs/list/'
);
}
}
$jobs
=
id
(
new
PhabricatorJenkinsJobQuery
())
->
setViewer
(
$viewer
)
->
execute
();
$form
=
id
(
new
AphrontFormView
())
->
setUser
(
$viewer
);
$form_proj
=
id
(
new
PhabricatorDatasourceEditField
())
->
setKey
(
'project'
)
->
setLabel
(
pht
(
'Project'
))
->
setValue
(
$proj
)
->
setIsRequired
(
true
)
->
setDatasource
(
new
PhabricatorProjectDatasource
());
if
(!
empty
(
$with_project
))
{
$form_proj
->
setIsHidden
(
true
);
}
$form_proj
->
appendToForm
(
$form
);
$form_repo
=
id
(
new
PhabricatorDatasourceEditField
())
->
setKey
(
'repository'
)
->
setLabel
(
pht
(
'Repository'
))
->
setValue
(
$repo
)
->
setIsRequired
(
true
)
->
setDatasource
(
new
DiffusionRepositoryDatasource
());
$form_repo
->
appendToForm
(
$form
);
$form_branch
=
id
(
new
PhabricatorTextEditField
())
->
setKey
(
'branch'
)
->
setLabel
(
'Branch'
)
->
setValue
(
$branch
)
->
setIsRequired
(
true
);
$form_branch
->
appendToForm
(
$form
);
$dialog_text
=
<<<EOF
Create a Pipeline Job on c4science Jenkins instance.
- The Project will be used as Policy access to the job.
- The Repository and Branch will be checked out in the job workspace.
- The Repository must contain a Jenkinsfile at the root, see [[https://jenkins.io/doc/book/pipeline/jenkinsfile/ | Using a Jenkinsfile]]
EOF;
$dialog
=
id
(
new
AphrontDialogView
())
->
setErrors
(
$errors
)
->
setUser
(
$viewer
)
->
setWidth
(
AphrontDialogView
::
WIDTH_FORM
)
->
setTitle
(
pht
(
'Create Jenkins Job'
))
->
appendChild
(
new
PHUIRemarkupView
(
$viewer
,
$dialog_text
))
->
appendParagraph
(
''
)
->
appendChild
(
$form
->
buildLayoutView
())
->
addSubmitButton
(
pht
(
'Create'
))
->
addCancelButton
(
'/jobs'
);
return
$dialog
;
}
private
function
handleList
(
AphrontRequest
$request
)
{
$viewer
=
$request
->
getViewer
();
$title
=
pht
(
'Jenkins Jobs List'
);
$list
=
self
::
createObjectList
(
$viewer
,
null
,
null
);
$box
=
id
(
new
PHUIObjectBoxView
())
->
setHeaderText
(
$title
)
->
setObjectList
(
$list
);
$nav
=
$this
->
buildSideNav
();
$nav
->
setCrumbs
(
$this
->
buildApplicationCrumbs
()
->
addTextCrumb
(
$title
));
$nav
->
appendChild
(
$box
);
$nav
->
selectFilter
(
'list'
);
return
$this
->
newPage
()
->
setTitle
(
$title
)
->
appendChild
(
$nav
);
}
public
static
function
createObjectList
(
PhabricatorUser
$viewer
,
$with_project
,
$with_repo
)
{
$jenkins_url
=
PhabricatorEnv
::
getEnvConfig
(
'jenkins.url'
);
$jenkins_user
=
PhabricatorEnv
::
getEnvConfig
(
'jenkins.user'
);
$jenkins_token
=
new
PhutilOpaqueEnvelope
(
PhabricatorEnv
::
getEnvConfig
(
'jenkins.token'
));
$csrf
=
self
::
getJenkinsCsrf
(
$jenkins_url
,
$jenkins_user
,
$jenkins_token
);
// Get jobs
$jobs
=
id
(
new
PhabricatorJenkinsJobQuery
())
->
setViewer
(
$viewer
);
if
(!
empty
(
$with_project
))
{
$jobs
->
withProjects
(
array
(
$with_project
));
}
if
(!
empty
(
$with_repo
))
{
$jobs
->
withRepositories
(
array
(
$with_repo
));
}
$jobs
=
$jobs
->
execute
();
$list
=
new
PHUIObjectItemListView
();
$list
->
setNoDataString
(
'No Jenkins Job. Create a Job from a Project for this Repository.'
);
foreach
(
$jobs
as
$job
)
{
// Get repo and project information
$repo
=
id
(
new
PhabricatorRepositoryQuery
())
->
setViewer
(
$viewer
)
->
withPHIDs
(
array
(
$job
->
getRepository
()))
->
executeOne
();
$project
=
id
(
new
PhabricatorProjectQuery
())
->
setViewer
(
$viewer
)
->
withPHIDs
(
explode
(
','
,
$job
->
getProject
()))
->
execute
();
$job_name
=
self
::
getJobName
(
$repo
->
getCloneName
(),
$repo
->
getID
(),
$job
->
getBranch
());
// Display
$item
=
id
(
new
PHUIObjectItemView
());
$item
->
setHeader
(
$job_name
);
// $item->setHref(
// $jenkins_url .
// '/blue/organizations/jenkins/' .
// $job_name . '/activity');
$item
->
setHref
(
"${jenkins_url}/job/${job_name}/"
);
if
(
empty
(
$with_repo
))
{
$item
->
addAttribute
(
id
(
new
PHUITagView
())
->
setType
(
PHUITagView
::
TYPE_OBJECT
)
->
setHref
(
$repo
->
getURI
().
'repository/'
.
$job
->
getBranch
().
'/'
)
->
setName
(
$repo
->
getMonogram
().
' '
.
$repo
->
getName
()));
}
$item
->
addAttribute
(
$job
->
getBranch
());
if
(
empty
(
$with_project
))
{
foreach
(
$project
as
$p
)
{
$item
->
addAttribute
(
id
(
new
PHUITagView
())
->
setType
(
PHUITagView
::
TYPE_OBJECT
)
->
setHref
(
$p
->
getURI
())
->
setName
(
$p
->
getName
()));
}
}
if
(
$viewer
->
isOmnipotent
())
{
$user
=
id
(
new
PhabricatorPeopleQuery
())
->
setViewer
(
$viewer
)
->
withPHIDs
(
array
(
$job
->
getOwnerPHID
()))
->
executeOne
();
if
(
$user
)
{
$item
->
addAttribute
(
$user
->
getUsername
());
}
}
$item
->
addAction
(
id
(
new
PHUIListItemView
())
->
setHref
(
'/jobs/delete/?job='
.
$job
->
getID
())
->
setWorkflow
(
true
)
->
setIcon
(
'fa-times'
));
$list
->
addItem
(
$item
);
// Get Job status
$url
=
$jenkins_url
.
"/job/${job_name}/lastBuild/api/json"
;
$future
=
id
(
new
HTTPSFuture
(
$url
))
->
addHeader
(
$csrf
[
0
],
$csrf
[
1
])
->
setHTTPBasicAuthCredentials
(
$jenkins_user
,
$jenkins_token
);
list
(
$status
,
$body
,
$headers
)
=
$future
->
resolve
();
if
(
$status
->
getStatusCode
()
==
200
)
{
$json
=
json_decode
(
$body
,
true
);
$result
=
$json
[
'result'
];
$building
=
$json
[
'building'
];
$icon
=
'fa-question-circle'
;
$text
=
'unknown'
;
if
(
$building
)
{
$icon
=
'fa-cogs'
;
$text
=
'building'
;
}
else
{
if
(
$result
==
'SUCCESS'
)
{
$icon
=
'fa-sun-o'
;
$text
=
'success'
;
}
else
if
(
$result
==
'FAILURE'
)
{
$icon
=
'fa-bolt'
;
$text
=
'failure'
;
}
}
$item
->
setStatusIcon
(
$icon
,
$text
);
}
}
return
$list
;
}
private
static
function
getJobName
(
$repo_name
,
$repo_id
,
$branch
)
{
// phutil_escape_uri() doen't escape /
$branch
=
str_replace
(
'/'
,
'-'
,
$branch
);
return
phutil_escape_uri
(
"${repo_name}-${branch}-${repo_id}"
);
}
private
static
function
getJenkinsCsrf
(
$jenkins_url
,
$jenkins_user
,
$jenkins_token
)
{
$url
=
$jenkins_url
.
'/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)'
;
list
(
$status
,
$csrf
,
$headers
)
=
id
(
new
HTTPSFuture
(
$url
))
->
setHTTPBasicAuthCredentials
(
$jenkins_user
,
$jenkins_token
)
->
resolve
();
if
(
$status
->
getStatusCode
()
!==
200
)
{
return
array
(
0
,
0
);
}
return
explode
(
':'
,
$csrf
);
}
}
Event Timeline
Log In to Comment