phabricator-jenkins-plugin icon indicating copy to clipboard operation
phabricator-jenkins-plugin copied to clipboard

Jenkinsfile support

Open aadis opened this issue 8 years ago • 33 comments

Hiya,

We've been using the plugin and it's been a godsend.

We've also migrated to using Jenkinsfile to enable tests-as-code tooling. Is it possible to call this plugin from Jenkinsfile (or pipeline groovy scripts) ?

Basically, we want to enable uberalls and running coverage report on all commits on master branch.

aadis avatar Jan 19 '17 13:01 aadis

See #156 for previous discussion.

We'd love to support Jenkinsfile! I have never used it and don't have the bandwidth to work on it. If there's anybody in the community with experience/advice, we'd love a PR :)

Thanks

ascandella avatar Jan 24 '17 23:01 ascandella

I'll have a crack at this. I'm not a java programmer, but I really need this feature.

ananthb avatar Feb 10 '17 14:02 ananthb

How did your crack at adding pipeline / jenkinsfile support go @ananthb ? I would like to add notifications in a similar situation to how #108 describes them to a multi-branch pipeline job. If you had some code even partly working that would be a big help.

TafThorne avatar Aug 08 '17 12:08 TafThorne

I'm looking for this feature as well. We are finally moving to use phabricator for more of our code and pipeline for more of the builds. Would be a shame not be able to combine the two ;)

anitakrueger avatar Nov 15 '17 21:11 anitakrueger

I noticed that there's a stalled PR for this: https://github.com/uber/phabricator-jenkins-plugin/pull/185. I echo @anitakrueger that this would be really great to have, at least as a start. I'm trying to get to having differentials go through the pipeline but I guess we're still a long way from that.

danielbprice avatar Dec 14 '17 19:12 danielbprice

As workaround: Phabricator -> freestyle build with this plugin -> Pipeline build also you can archive *.xml with test resuts and copy them back to freestyle build and publish. In that case plugin will pass them to phabricator

fallenworld1 avatar Dec 15 '17 09:12 fallenworld1

It will be very grateful to support Jenkinsfile, we have similar use case to integrate Jenkins with Phabricator.

xiaogaozi avatar Dec 20 '17 08:12 xiaogaozi

@fallenworld1 I am interested in that workaround, and have been trying to implement it − how do you make the Pipeline build aware of the Differential changes?

In my attempted setup for my repo dummy-app, Harbormaster triggers a job differential-trigger, which makes a Conduit lookup to retrieve the repo name, and pass it all to differential-apply, which 1/ clones the dummy-app Git repository, 2/ applies the Differential revision (using the uber plugin); 3/ archives the result (using the “Clone Workspace SCM” plugin) ; 4/ trigger a build of the Pipeline-style job dummy-app. That job which would "clone" the repo from the previous job, detect the Jenkinsfile there and run the pipeline. However the “Clone Workspace SCM” appears incompatible with Pipeline :-/

Would you be able to detail a bit more your solution ? :)

JeanFred avatar Mar 06 '18 18:03 JeanFred

@JeanFred I am using next setup:

  1. Phabricator triggers manager-job with parameters passing diffid
  2. manager-job triggers pipeline with same parameters
  3. pipeline performs git and conduit calls

Pipeline code is separated: boilerplate is in job configuration, common parts are in global library.

But if I understand correctly, you want to use 'pipeline as code' idiom, so can't use pipeline before full checkout) may be 'staging area' config in phabricator could help.

fallenworld1 avatar Mar 06 '18 20:03 fallenworld1

My colleague and I have been working more on this problem in the last couple of days. I thought I would share our recipe in more detail. We now have Harbormaster triggering Jenkins declarative pipelines, and the notifier replying back to Phabricator with build status.

We took the PR @balihb produced-- https://github.com/uber/phabricator-jenkins-plugin/pull/185 -- and rebased it on top of the lastest version of this plugin (it applies cleanly). We built the plugin using gradle assemble and then loaded the resultant .hpi file into jenkins.

Even with @balihb's patch, the plugin still lacks "build wrapper" support-- the part which applies the arc patch to the checked out source. So we have configured Phabricator to use a staging repo (see https://secure.phabricator.com/book/phabricator/article/harbormaster/). We have found the staging repo approach to be superior anyway, since it allows reviews between arbitrary changes.

Then we have harbormaster trigger the build via HTTP, and have configured git in our jenkins job as follows:

screen shot 2018-04-27 at 2 13 19 pm

It's very important not to miss the hint from @balihb in his sample jenkinsfile. You need to do something like this:

    post {
        always {
            script {
                if (currentBuild.result == null) {
                    currentBuild.result = currentBuild.currentResult
                }
                step([$class: 'PhabricatorNotifier', commentOnSuccess: true, commentWithConsoleLinkOnFailure: true])
            }
        }
    }

I missed this assignment the first time, and the plugin was crashing. Setting currentBuild.result (which is basically a global) is critical because the plugin references it, and, despite being in the 'post' step in the pipeline, it seems to be null most of the time, whereas currentResult is documented never to be null. More on this in the Jenkins Global Variable Reference inside of your Jenkins instance (for example: http://localhost:8080/pipeline-syntax/globals#currentBuild).

Not tested:

  • We didn't test anything with coverage, or unit test results.

Things that need more work:

  • Not having the build wrapper means that phabricator won't get an initial reply from jenkins saying "here is my URI". Presumably the right incantation to arc conduit would solve this in the short-term.

Anyway, I hope this helps the next person.

danielbprice avatar Apr 27 '18 21:04 danielbprice

#185 has been accepted. This is probably good to close once it is made available through a release.

youngmit avatar May 21 '18 18:05 youngmit

@danielbprice Really helpful - thank you! One quick question did you still need to configure the pipeline job in Jenkins to accept build parameters? I have had to but I was hoping that I could avoid this if at all possible as they are also in the Jenkinsfile

ghost avatar Aug 14 '18 14:08 ghost

Even with @balihb's patch, the plugin still lacks "build wrapper" support-- the part which applies the arc patch to the checked out source. So we have configured Phabricator to use a staging repo (see https://secure.phabricator.com/book/phabricator/article/harbormaster/). We have found the staging repo approach to be superior anyway, since it allows reviews between arbitrary changes.

Maybe I'm over simplifying things but wouldn't it be relatively easy to implement an "arc patch" step (the logic is already in the PhabricatorBuildWrapper class)?

You could then use that step after GIT SCM, something like:

stage('Checkout source') {
  steps {
    git([url: 'ssh://[email protected]/source/test-repository.git', branch: 'master', credentialsId: 'foo-bar'])
  }
}

stage('Apply diff') {
  steps {
    step([$class: 'PhabricatorArcPatch'])
  }
}

Is there an advantage to use it as a build wrapper?

siepkes avatar Aug 14 '18 15:08 siepkes

@Sykomaniac our pipeline jobs take DIFF_ID and PHID as input parameters which we pass from Harbormaster. Possibly you are referring to something else? So basically in harbormaster we hit jenkins as follows:

screen shot 2018-08-14 at 10 05 28 am

And our jenkins jobs are then called differential-<repoCallsign>. This lets us have a single Harbormaster rule for Differential for a variety of repositories. I'm not sure if I really answered your question, though.

@siepkes Yes, I expect that it could work, however I have not tested it. I have found the staging repo approach to be superior, as it supports a wider range of development patterns, and it is a built-in feature of core Phabricator. If I recall correctly, the other useful function of the build wrapper is that it notifies Phabricator that it is starting the job-- if there was a recipe to get that working, I would be glad to have it. I believe that it's possible by piping some json into arc conduit but I haven't had time to work out an exact recipe.

We have continued to use the above recipe for several months without modification, and it has been great.

danielbprice avatar Aug 14 '18 17:08 danielbprice

@danielbprice yes you did that's fine that is similar to what I had configured :)

ghost avatar Aug 14 '18 17:08 ghost

I want to recommend this: https://github.com/balihb/drydock-docker-jenkins whith this the trigger token plugin is not needed anymore.

On Tue, Aug 14, 2018, 19:21 Ash Sykes [email protected] wrote:

@danielbprice https://github.com/danielbprice yes you did that's fine that is similar to what I had configured :)

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/uber/phabricator-jenkins-plugin/issues/198#issuecomment-412949574, or mute the thread https://github.com/notifications/unsubscribe-auth/ACvMmGDgHQLjZfJPbAASyFWRSKKgYxp2ks5uQwczgaJpZM4LoGK3 .

balihb avatar Aug 14 '18 17:08 balihb

@danielbprice While I think the automatic staging repo's (which aren't implemented in Phabricator yet) would be great I don't really like the manual ones we have to use. For example they require manual maintenance like deleting and recreating the repo since it will be ever growing. Also everyone needs to have access to this staging repo since arc just pushes the entire repo + diff it to this second repo.

While I appreciate it's a working solution for you (can't argue with that, though I'm still going to ;-) and it might be a "built-in feature" of Phabricator it's basically a built-in hack. Even the Phabricator guys themselves are not happy with it:

D13019

This is a bit leaky and I intend for it to eventually be positioned as a less-preferred solution, but from the perspective of build systems it's the same as the real (virtual ref) solution that I want to build.

T8238

We see how bad this is (does pushing tags to the same repository create a big user-facing mess?) and then go from there.

Ideally we would get the automatic staging area's. Basically just ref's in GIT for diff like GitHub has for PR's (T8092). Though I don't think these will be implemented anytime soon.

I'm going to take a stab at either fixing the BuildWrapper or maybe implement an arc patch apply step.

siepkes avatar Aug 15 '18 08:08 siepkes

@siepkes any luck fixing the BuildWrapper? I've seen some snippets where people seem to be using it, but I'm not able on my jenkins instance.

https://github.com/SW7JKMMTT/SW7-Rapport/blob/6aa7a99f3e96b6b85b9bb8a2b11d6d908850637d/Jenkinsfile-phabricator#L22

uSpike avatar Dec 21 '18 22:12 uSpike

@uSpike In the end I got side tracked with other work and wasn't able to finish it. At the moment I use the Phabricator staging area (so one gigantic GIT repo where arc pushes all diffs to). This is still somewhere on my wishlist.

I also toyed with the idea of instead of calling (and requiring) arc it might be easier to just request the diff from Phabricator and apply it to the right base commit.

siepkes avatar Dec 24 '18 08:12 siepkes

          stage("apply-patch") {
              steps {
                  container("mxnetone") {
                    sh """
                      env
                      whoami
                      pwd

                      echo -e "## Getting base rev for diff"
                      BASE_GIT_COMMIT=\$( echo "{\\"diff_id\\": \${DIFF_ID}}" | /phacility/arcanis/bin/arc call-conduit differential.getdiff --conduit-token \"cli-uvlhcptydhpaaaaaaa\" --conduit-uri \"http://ph.yoursite/\" | awk -v RS=',' -v FS=':' '\$1~/\\"sourceControlBaseRevision\\"/ {print \$2}' | tr -d \\")
                      echo \${BASE_GIT_COMMIT}

                      echo -e "## Reset to base commit"
                      git reset --hard \${BASE_GIT_COMMIT}

                      echo -e "## Cleaning out repo"
                      git clean -fdx

                      echo -e "## Apply diff"
                      /phacility/arcanis/bin/arc  patch --nobranch --no-ansi --diff \${DIFF_ID} --nocommit --conduit-token \"cli-uvlhcptydhpaaaaaaa\" --conduit-uri \"http://ph.yoursite/\" 

                      """
                  }
              }
          }

zmoon111 avatar Feb 28 '19 08:02 zmoon111

I ran into this issue today, realizing that the BuildWrapper is also the reason we cannot use the ABORT_ON_REVISION_ID feature.

I reimplemented that portion as a Groovy function. In case it's helpful to anyone else:

package com.company.jenkins
import com.uber.jenkins.phabricator.PhabricatorCauseOfInterruption
class Utils implements Serializable {
  /**
   * Aborts all running builds with the given ABORT_ON_REVISION_ID value.
   * This replicates the behavior of the phabricator-jenkins-plugin.
   *
   * @param revisionId current build's ABORT_ON_REVISION_ID value
   */
  @NonCPS
  def abortBuildsWithRevisionId(String revisionId) {
    // Iterate over all of the other running builds for this project
    script.currentBuild.rawBuild.parent.builds.each { build ->
      if (build.isBuilding() && build.number != script.currentBuild.number) {
        // Find the "ABORT_ON_REVISION_ID" value of the previous running build
        // .parameters gives us an ArrayList of length 1 containing an ArrayList of ParameterValue items
        def buildParams = build.getActions(hudson.model.ParametersAction)?.parameters?.find()
        def prevBuildRevisionId = buildParams?.find { it.name == 'ABORT_ON_REVISION_ID' }?.value

        if (prevBuildRevisionId && prevBuildRevisionId == revisionId) {
          script.println "Aborting previous build #${build.number}"
          // Use the special plugin-defined CauseOfInterruption, which skips the notification step.
          def causeOfInterruption = new PhabricatorCauseOfInterruption(script.currentBuild.absoluteUrl)
          build.executor.interrupt(Result.ABORTED, causeOfInterruption)
        }
      }
    }
  }
}

clintharrison avatar Jul 09 '19 22:07 clintharrison

I should stress that communicating with Phabricator from pipeline (Jenkinsfile) itself might be a bad idea if you want to report build status in Differential (and you probably do). Reasons:

  • you might want to call harbormaster.createartifact to provide initial link to Jenkins build as soon as build starts. This plugin currently has no means to do this in Pipeline, AFAIK (we currently resort to calling arc call-conduit manually from shell, @timbrown5's comment in #330 provides means to do this from Groovy itself)
  • pipeline may fail because of various reasons, so you need to use constructions like
try {
 ... // my whole pipeline
} catch (exc) {
  currentBuild.result = 'ERROR' // plugin won't detect that the build failed without it
} finally {
  step([$class: 'PhabricatorNotifier', commentOnSuccess: false, commentWithConsoleLinkOnFailure: false])
}
  • pipeline may still fail after the PhabricatorNotifier is called, leading to a green indicator in Phabricator and red one in Jenkins
  • pipeline may fail because of syntax error in Groovy, in which case pipeline doesn't even have a chance to call harbormaster.createartifact or harbormaster.sendmessage.

With all these bumps I've encountered while trying to integrate Phabricator with Pipeline jobs, I believe the right way should be in style of Freestyle jobs: there should be a checkbox "notify Phabricator" somewhere in Build environment, that should provide a BUILD_URL to .createartifact as soon as the build starts and send build status to .sendmessage regardless of what caused the failure: error call, exception thrown, syntax error, etc.

Artalus avatar Oct 18 '19 12:10 Artalus

Hi @Artalus, I agree that the best solution would be for the plugin to natively support pipelines, so we don't have to handle reporting to Phabricator in each of our pipelines. That said I'm not sure how actively this plugin is being maintained, and in the meantime, I think we will have to make do.

I agree with your point about the try/catches - my scripted pipeline is awash with them. That said I think declarative pipelines could simplify working with the Phabricator groovy functions, e.g:

@Library('my-phabricator-lib')
def common = new org.acme.pipeline.CommonFunctions()
pipeline {
    agent none
    stages {
        // Run this stage on any agent to it runs as soon as possible.
        stage ("Report to Phabricator") {
            agent any
            steps {
                script {
                    try {
                        common.report_build_start_to_phabricator(
                            params.DIFF_IDS,
                            params.DIFF_REPOS,
                            params.PHID
                        )
                    } catch (err) {
                        echo "Failed to repo the builds status to Phabricator (is this a rebuild)?" + err.toString()
                    }   
                }
            }
        }
        stage ("Start job") {
            agent any
            steps {
                sh "echo Hello World!"   
            }
        }
    }
    post {
        always {
            node('master') {
                script {
                    common.report_build_end_to_phabricator(
                        params.DIFF_IDS,
                        params.DIFF_REPOS,
                        params.PHID
                    )
                }
            }
        }
    }
}

In the above, I have the report_build_start_to_phabricator and report_build_end_to_phabricator pulled out into a separate Groovy module which gets pulled in by Pipeline Shared Groovy Libraries Plugin. I do wonder if, in lieu of having Pipeline support in the plugin, we should try getting a groovy module together on github with useful Phabricator pipeline functions (like @clintharrison's function above).

timbrown5 avatar Oct 24 '19 09:10 timbrown5

I've read this thread several times but can't work out whether anyone has got Phabricator diffs to build using a Jenkinsfile.

Here's what I've got.

  • a Jenkinsfile with parameters PHID and DIFF_ID which correctly creates a job under a multibranch pipeline with those same parameters.
  • a "post-always" step in my Jenkinsfile with step([$class: 'PhabricatorNotifier', commentOnSuccess: true, commentWithConsoleLinkOnFailure: true]) to notify Phabricator of build status
  • a Harbormaster build plan which calls http://myjenkins/job/MyMultibranchBuild/job/MyBranch/buildWithParameters?job=differential-${repository.callsign}&DIFF_ID=${buildable.diff}&PHID=${target.phid}&ABORT_ON_REVISION_ID=${buildable.revision}
  • a Herald rule which calls the build plan when a differential revision is created
  • my repository set up to use a staging repo for diffs

When I run arc diff on my workstation, the build runs on Jenkins, the diff in Phabricator gets feedback that it's been successful, and the build in Jenkins gets a link to the diff. So far, so good.

The problem is that my build is running the base commit without applying the diff. I'll try again without using the staging area but would appreciate any feedback on:

  • whether this is known to work with the latest available version of the plugin (2.1.2)
  • whether I can run the parameterised build without specifying a branch in the Jenkins API URL. I've tried but get a 404 (this might be a "feature" of multibranch pipelines).

I've seen comments here about using the staging area and I believe I could create a separate Jenkins build that would detect new refs in the staging repository by polling every few minutes but then I don't see how to report back to Phabricator since I wouldn't have any parameters.

carlfischerjba avatar Dec 19 '19 18:12 carlfischerjba

@carlfischerjba trigger the job for a staging area tag from Phabricator

ogonkov avatar Dec 20 '19 07:12 ogonkov

@ogonkov Thanks, so I need a separate job for commit and differential builds since they will be looking at different repositories. I thought the plugin would figure out where to get the code from by querying arcanist but I guess not.

I've set up a job identically to the one in the screenshot above by @danielbprice but I get errors during checkout.

 > git fetch --tags --force --progress https://phabricator/diffusion/MYSTAG/my-staging.git +refs/heads/*:refs/remotes/origin/* --depth=1
ERROR: Error fetching remote repo 'origin'
hudson.plugins.git.GitException: Failed to fetch from https://phabricator/diffusion/MYSTAG/my-staging.git
	at hudson.plugins.git.GitSCM.fetchFrom(GitSCM.java:894)
	at hudson.plugins.git.GitSCM.retrieveChanges(GitSCM.java:1161)
	at hudson.plugins.git.GitSCM.checkout(GitSCM.java:1192)
	at org.jenkinsci.plugins.workflow.steps.scm.SCMStep.checkout(SCMStep.java:120)
	at org.jenkinsci.plugins.workflow.cps.CpsScmFlowDefinition.create(CpsScmFlowDefinition.java:144)
	at org.jenkinsci.plugins.workflow.cps.CpsScmFlowDefinition.create(CpsScmFlowDefinition.java:67)
	at org.jenkinsci.plugins.workflow.job.WorkflowRun.run(WorkflowRun.java:293)
	at hudson.model.ResourceController.execute(ResourceController.java:97)
	at hudson.model.Executor.run(Executor.java:429)
Caused by: hudson.plugins.git.GitException: Command "git fetch --tags --force --progress https://phabricator/diffusion/MYSTAG/my-staging.git +refs/heads/*:refs/remotes/origin/* --depth=1" returned status code 128:
stdout: 
stderr: error: RPC failed; HTTP 500 curl 22 The requested URL returned error: 500
fatal: the remote end hung up unexpectedly

The job is parameterised with the PHID and DIFF_ID but doesn't seem to reach the stage where they're used.

If I uncheck the fetch tags box then I get a different error because it can't find the tag corresponding to the diff. This makes sense but I don't know why fetching tags would be a problem. I've been able to clone the repository and fetch tags from a shell but Jenkins must be doing something different.

 > git fetch --no-tags --force --progress https://phabricator/diffusion/MYSTAG/my-staging.git +refs/heads/*:refs/remotes/origin/*
 > git rev-parse refs/tags/phabricator/diff/10217^{commit} # timeout=10
 > git rev-parse refs/remotes/origin/refs/tags/phabricator/diff/10217^{commit} # timeout=10
 > git rev-parse refs/tags/phabricator/diff/10217^{commit} # timeout=10
ERROR: Couldn't find any revision to build. Verify the repository and branch configuration for this job.

The 500 response is logged in the Apache error logs but no indication of what caused it.

Here's the full build configuration in case it's useful to anyone for their own setup (or pointing out problems in mine).

image

carlfischerjba avatar Dec 20 '19 17:12 carlfischerjba

@carlfischerjba Did you get the problem solved yet? Thanks!

pasikarkkainen avatar May 06 '20 19:05 pasikarkkainen

@pasikarkkainen I'm afraid not quite. One of my colleagues got a build working from a staging repo and didn't encounter the "remote end hung up" error, so that must have been specific to my repository. But his build doesn't report back to Phabricator.

I've proposed we change the trigger URL in Harbormaster to something like http://myjenkins/job/MYBUILD/view/tags/job/${repository.staging.ref}/build?delay=0sec&PHID=${target.phid}&DIFF_ID=${buildable.diff} but haven't tried it out yet.

carlfischerjba avatar May 07 '20 10:05 carlfischerjba

@carlfischerjba For what it's worth, here is a simple example of a declaratve pipeline using the plugin ~~(although I send a URL to Phabricator by adding an artifact using the httpRequest - this can be omitted~~ [EDIT: Sorry I removed this to make the example cleaner but didn't update the comment].

def PHABRICATOR_URL="https://phabricator.acme.com"
//This requires:
// - A credential containing a valid Arcanist token of type 'Secret Text' and ID 'phab_arc_token'
properties([[$class: 'RebuildSettings', autoRebuild: false, rebuildDisabled: false],
    parameters([
        string(defaultValue: '', description: 'Phabricator Diff ID [Dxxxx].', name: 'DIFF_ID', trim: false),
        string(defaultValue: '', description: 'Phabricator Build Target PHID [PHID-HMBT-xxxx...].', name: 'PHID', trim: false)
    ])
])

pipeline {
    agent {label "python3_agent"}
    stages {
        stage ("Run Unit tests") {
            steps {
                dir('src'){
                    git(
                        url: 'https://github.com/pluralsight/intro-to-pytest.git',
                        branch: "master"
                    )
                    sh """
                    python3 -m venv tutorial-env
                    source ./tutorial-env/bin/activate
                    python3 -m pip install -r requirements.txt
                    python3 -m pip install pytest-cov
                    python3 -m pytest --junitxml=junit-python3.xml --cov-branch --cov-report term-missing --cov=./ --cov-report xml:coverage-python3.xml
                    deactivate
                    """
                }
                cobertura autoUpdateHealth: false, autoUpdateStability: false, coberturaReportFile: '**/coverage*.xml', conditionalCoverageTargets: '70, 0, 0', failUnhealthy: false, failUnstable: false, lineCoverageTargets: '80, 0, 0', maxNumberOfBuilds: 0, methodCoverageTargets: '80, 0, 0', onlyStable: false, sourceEncoding: 'ASCII', zoomCoverageChart: false
            }
        }
    }
    post {
        always {
            script {
                step([$class: 'PhabricatorNotifier', commentFile: '.phabricator-comment', commentOnSuccess: false,
                    commentSize: '1000', commentWithConsoleLinkOnFailure: false, coverageCheck: false,
                    coverageReportPattern: '**/coverage*.xml, **/cobertura*.xml, **/jacoco*.xml',
                    coverageThreshold: 0.0, customComment: false, lintFile: '.phabricator-lint', lintFileSize: '100000',
                    minCoverageThreshold: 100.0, preserveFormatting: false, processLint: false, uberallsEnabled: false])
            }
        }
    }
}

It could use some cleaning up, some better error handling and probably isn't the best way to do it but hopefully, it will give you some ideas.I find that this does most of what I want/need. The one issue is it doesn't seem to find the line coverage. I get:

[phabricator:uberalls] Using coverage metrics from Cobertura Jenkins Plugin
[phabricator:process-build-result] No unit results available.
[phabricator:process-build-result] No line coverage available to post to Harbormaster.

For completeness my Harbormaster step which calls this is an HTTP Request http://my.jenkins.server:8080/buildByToken/buildWithParameters?job=phab_simple_pytest&DIFF_ID=${buildable.diff}&PHID=${target.phid}&token=my_secret_token. Note: I use the 'Build Authorization Token Root Plugin' to try and secure my web-hook a little more, but I don't think that is a requirement.

timbrown5 avatar Jun 17 '20 17:06 timbrown5

So I have just managed to get the Coverage being sent to Phabricator. In doing this I found two things:

  • The Plugin seems to detect when a differential repo is used so it can enable certain functionality. This makes sense but wasn't obvious to me before.
  • (This one is a mistake on my part, but might help someone) The parameter passed to the Jenkins job needs to be DIFF_ID=${buildable.diff} - I was passing DIFF_ID=${buildable.revision} which started throwing exceptions.

Adding a new diff, as I think the diff above is could still be a useful starting point (as it uses a freely available Github repo).

properties([[$class: 'RebuildSettings', autoRebuild: false, rebuildDisabled: false],
    parameters([
        string(defaultValue: '', description: 'Phabricator Diff ID [Dxxxx].', name: 'DIFF_ID', trim: false),
        string(defaultValue: '', description: 'Phabricator Build Target PHID [PHID-HMBT-xxxx...].', name: 'PHID', trim: false)
    ])
])

pipeline {
    agent {label "python3_agent"}
    stages {
        stage ("Run Unit tests") {
            steps {
                sh "rm -rf src"
                dir('src'){
                    // use checkout and not git so we can add additional submodule behaviours.
                    checkout([
                        $class: 'GitSCM',
                        branches: [[name: '*/master']],
                        doGenerateSubmoduleConfigurations: false,
                        extensions: [[
                            $class: 'SubmoduleOption',
                            disableSubmodules: false,
                            parentCredentials: true,
                            recursiveSubmodules: true,
                            reference: '',
                            trackingSubmodules: false
                        ]],
                        submoduleCfg: [],
                        userRemoteConfigs: [[
                            credentialsId: 'my_credential',
                            url: 'ssh://[email protected]/diffusion/MYPYTHONREPO/my_python_repo.git'
                        ]]
                    ])
                    sh """
                    arc patch --diff ${DIFF_ID}
                    python3 -m venv tutorial-env
                    source ./tutorial-env/bin/activate
                    python3 -m pip install -r requirements.txt
                    python3 -m pip install -r test-requirements.txt
                    python3 -m pytest --junitxml=junit-python3.xml --cov-branch --cov-report term-missing --cov=./ --cov-report xml:coverage.xml
                    deactivate
                    """
                }
                junit '**/*junit*.xml'
                cobertura coberturaReportFile: '**/coverage.xml'
            }
        }
    }
    post {
        always {
            script {
                step([$class: 'PhabricatorNotifier', commentOnSuccess: false, commentWithConsoleLinkOnFailure: true])
            }
        }
    }
}

timbrown5 avatar Jun 18 '20 16:06 timbrown5