| |
@@ -0,0 +1,192 @@
|
| |
+ def route
|
| |
+ def has_built = false
|
| |
+
|
| |
+ pipeline {
|
| |
+ agent none
|
| |
+ parameters {
|
| |
+ string(name: 'prnumber', defaultValue: '', description: 'Pull-Request ID')
|
| |
+ string(name: 'project', defaultValue: '', description: 'Pagure Project FullName')
|
| |
+ choice(
|
| |
+ choices: [
|
| |
+ 'pull-request.updated',
|
| |
+ 'pull-request.rebased',
|
| |
+ 'pull-request.comment.added',
|
| |
+ 'pull-request.new',
|
| |
+ 'pull-request.closed'
|
| |
+ ],
|
| |
+ description: 'fedmsg topic',
|
| |
+ name: 'topic')
|
| |
+ string(name: 'last_comment', defaultValue: '', description: 'PR\'s last comment')
|
| |
+ booleanParam(defaultValue: true, description: 'Post job status on PR?', name: 'notify')
|
| |
+ }
|
| |
+ options {
|
| |
+ skipDefaultCheckout(true)
|
| |
+ disableConcurrentBuilds()
|
| |
+ }
|
| |
+ triggers {
|
| |
+ GenericTrigger(
|
| |
+ causeString: 'Triggered by PR#$prnumber on $project',
|
| |
+ genericVariables: [
|
| |
+ [
|
| |
+ defaultValue: '',
|
| |
+ key: 'topic',
|
| |
+ regexpFilter: '',
|
| |
+ value: '$.topic'
|
| |
+ ],
|
| |
+ [
|
| |
+ defaultValue: '',
|
| |
+ key: 'prnumber',
|
| |
+ regexpFilter: '',
|
| |
+ value: '$.msg.pullrequest.id'
|
| |
+ ],
|
| |
+ [
|
| |
+ defaultValue: '',
|
| |
+ key: 'project',
|
| |
+ regexpFilter: '',
|
| |
+ value: '$.msg.project_fullname'
|
| |
+ ],
|
| |
+ [
|
| |
+ defaultValue: '',
|
| |
+ key: 'last_comment',
|
| |
+ regexpFilter: '',
|
| |
+ value: '$.msg.pullrequest.comments[-1].comment'
|
| |
+ ]
|
| |
+ ],
|
| |
+ printContributedVariables: true,
|
| |
+ printPostContent: true,
|
| |
+ /* topic of interrest:
|
| |
+ pull-request.new
|
| |
+ pull-request.comment.added
|
| |
+ pull-request.rebased
|
| |
+ pull-request.updated
|
| |
+ pull-request.closed
|
| |
+ */
|
| |
+ regexpFilterExpression: '^pull-request\\.(new|closed|rebased|updated|comment\\.added)$',
|
| |
+ regexpFilterText: '$topic',
|
| |
+ tokenCredentialId: 'PagureWebHook'
|
| |
+ )
|
| |
+ }
|
| |
+
|
| |
+ stages {
|
| |
+ stage('Check requirements') {
|
| |
+ /* run the pipeline only if we get the right topic */
|
| |
+ when {
|
| |
+ beforeAgent true
|
| |
+ anyOf {
|
| |
+ expression { topic ==~ /^pull-request\.(new|closed|rebased|updated)/ }
|
| |
+ allOf {
|
| |
+ expression { topic ==~ /^pull-request\.comment\.added/ }
|
| |
+ expression { last_comment ==~ /^pretty please pagure-ci rebuild/ }
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+ stages {
|
| |
+ stage('Clean-up previous build') {
|
| |
+ /* Remove all existing openshift objects related to this PR */
|
| |
+ agent any
|
| |
+ steps {
|
| |
+ cleanAll(pr: "${prnumber}", project: "${project}")
|
| |
+ }
|
| |
+ }
|
| |
+ stage('Stop here if PR closed') {
|
| |
+ /* If pull-request.closed, we don't go further */
|
| |
+ when {
|
| |
+ expression { topic ==~ /^pull-request\.closed/ }
|
| |
+ }
|
| |
+ steps {
|
| |
+ script {
|
| |
+ currentBuild.result = 'ABORTED'
|
| |
+ error("PR Closed. Nothing left to do.")
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+
|
| |
+
|
| |
+ /*
|
| |
+ Here we can run pre-build tests like syntax check, formatting and/or unit tests
|
| |
+ following example with flake8:
|
| |
+ */
|
| |
+
|
| |
+ stage('Pre build tests') {
|
| |
+ agent {
|
| |
+ kubernetes {
|
| |
+ cloud 'openshift'
|
| |
+ inheritFrom 'Base'
|
| |
+ yamlFile '.ci/jenkins-pod-agent.yml'
|
| |
+ }
|
| |
+ }
|
| |
+ steps {
|
| |
+ checkout scm
|
| |
+ checkout(
|
| |
+ [
|
| |
+ $class: 'GitSCM',
|
| |
+ branches: [[name: 'origin/pr/${prnumber}']],
|
| |
+ ]
|
| |
+ )
|
| |
+ catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
| |
+ container("python"){
|
| |
+ sh "pytest --flake8 --junit-xml=flake8_junit.xml"
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+ post {
|
| |
+ always {
|
| |
+ container("python"){
|
| |
+ junit('flake8_junit.xml')
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+
|
| |
+ stage('Build Websites') {
|
| |
+ /* Try to build all websites */
|
| |
+ agent any
|
| |
+ steps {
|
| |
+ script {
|
| |
+ buildPod(pr: "${prnumber}", project: "${project}")
|
| |
+ has_built = true
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+ stage('Expose Preview') {
|
| |
+ /* If last step is a success, we create a route to expose websites preview */
|
| |
+ agent any
|
| |
+ steps {
|
| |
+ script {
|
| |
+ route = exposeBuild(pr: "${prnumber}")
|
| |
+ currentBuild.description = "${route}"
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+
|
| |
+ /* Post-build test goes here
|
| |
+ You can use ${route} as target URL
|
| |
+ */
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+ post {
|
| |
+ success {
|
| |
+ /* Post a success flag on the PR, but only if we've actually built something */
|
| |
+ node(null){
|
| |
+ script {
|
| |
+ if (has_built && params.notify) {
|
| |
+ updatePr( pr: "${prnumber}", project: "${project}", url: "${route}", success: 100 )
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+
|
| |
+ failure {
|
| |
+ /* Post an error flag on the PR if something has failed */
|
| |
+ node(null){
|
| |
+ script {
|
| |
+ if (params.notify) {
|
| |
+ updatePr( pr: "${prnumber}", project: "${project}", success: 0 )
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+
|
| |
+ }
|
| |
+ }
|
| |
Right now, this pipeline "only" build all websites, and share a link to preview your PR.
From there, we can add other tasks like pre or post build tasks (linter, unit tests, ...). I've already added a flake8 task as an example.
For now, this pipeline is manual, but it's meant to be automatically triggered on PR creation & update.
This require an admin to add the required hook to this project, which I'll gladly share with you once merged.
note that I've never used Jenkins before. So let me know if you see something wrong that need to be fixed.
If there are no blockers to it, I'll merge it sometime next week.