mockersf / jenkins-api.rs

Rust client for Jenkins API
MIT License
26 stars 17 forks source link

Support for Multibranch Pipeline project type #36

Open zrokloons opened 5 years ago

zrokloons commented 5 years ago

Hi there,

I was wondering if there is any plans to add support for this project type.

I have projects of this type on one Jenkins instance and it prevents building the Home struct via get_home method.

Thanks Mathias

mockersf commented 5 years ago

Hello,

Do you have a publicly available Jenkins, or a setup I can easily reproduce in a container ? It's not a project type I'm using and it would greatly help.

Thank you

kunicmarko20 commented 4 years ago

I am also having an issue with multibranch pipeline:

let job = jenkins.get_job("projects/job/project/job/master")

this ends up throwing:

https://ci.project.co.uk/job/projects%2Fjob%2Fproject%2Fjob%2Fmaster/api/json?depth=1: Client Error: 404 Not Found

job name is always converted into path name: https://github.com/mockersf/jenkins-api.rs/blob/cc9cf628f54c75bfa7f7672f5d76a9b25b610a48/src/job/mod.rs#L40

which is always url encoded: https://github.com/mockersf/jenkins-api.rs/blob/cc9cf628f54c75bfa7f7672f5d76a9b25b610a48/src/client_internals/path.rs#L18

Not sure if I am doing something wrong but I don't see another way to get a job which supports this?

mockersf commented 4 years ago

I (maybe) added multi branch pipelines in branch multibranch-pipeline

As I can't test it myself, I would love to get feedback.

How it should work:

let multibranch = jenkins.get_job("multibranch pipeline project name")
    .unwrap()
    .as_variant::<jenkins_api::job::WorkflowMultiBranchProject>();
let pipelines = multibranch.jobs;
krooq commented 4 years ago

Hey man, I gave this a go but I get a json parse error Error(Json(Error("missing field `buildable`", line: 1, column: 279412)))

When I check the query manually http://hostname:port/api/json?tree=jobs[buildable]&pretty=true

{
  "_class" : "hudson.model.Hudson",
  "jobs" : [
    {
      "_class" : "org.jenkinsci.plugins.workflow.job.WorkflowJob",
      "buildable" : true
    },
    {
      "_class" : "org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject"
    }
  ]
}

You can see multibranch pipelines only have the class but buildable is an expected boolean as seen in in the macro rules for job_build_with_common_fields_and_impl!.

I ran the following to see what should be in the schema http://hostname:port/api/json?tree=jobs[*] this is what I got:

{
    "_class" : "org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject",
    "actions" : [{},],
    "description" : "",
    "displayName" : "myjobname",
    "displayNameOrNull" : null,
    "fullDisplayName" : "myjobname",
    "fullName" : "myjobname",
    "name" : "myjobname",
    "url" : "http://hostname:port/job/myjobname/",
    "healthReport" : [{}],
    "jobs" : [ { "_class" : "org.jenkinsci.plugins.workflow.job.WorkflowJob" }],
    "primaryView" : { "_class" : "jenkins.branch.MultiBranchProjectViewHolder$ViewImpl" },
    "views" : [ {"_class" : "jenkins.branch.MultiBranchProjectViewHolder$ViewImpl" } ],
    "sources" : [{}]
},

So maybe some tweaking of that macro is required, sorry I can't help with that, I'm only a few months into Rust so macros still scare me. I can test it for you though (unfortunately I have no public jenkins server but maybe there is a apache one or something we can access).

If this is fixed in the API do you think jencli will just work(tm)?

krooq commented 4 years ago

In the meantime if you don't care about most of the stuff in that request you can always do a custom tree query. Really its like only the name, url, description and the jobs that anyone would care about. Once you have the Jobs you can get their names and do a regular jenkins.get_job(name). So its only a minor bit of manual code.

Thanks @mockersf for the awesome api!!!!

krooq commented 4 years ago

I tried to use get_build on a multi pipeline branch but it still doesnt work. I tried using a custom path but it seems URL encoding is applied to job_name when building the path which breaks the request. i.e. this is my hack

let mut job_name = result.pipeline_name.clone();
job_name.push_str("/job/");
job_name.push_str(&result.job_name);
let build = jenkins
    .get_build(
        JobName::from(&job_name),
        BuildNumber::Number(result.build_number),
    )
    .expect("Artifact data from jenkins");

that doesnt work, but should work reqwest::Error { kind: Status(404), url: "http://localhost:8080/job/jenky%2Fjob%2Fmaster/26/api/json?depth=1" }

NOTE: the following does work http://localhost:8080/job/jenky/job/master/26/api/json?depth=1

Maybe its better to add another variant to JobName enum that takes 2 "job" names (pipeline name and job name) and creates the path for them. Should also remove the URL encoding here, I don't think its needed.