Jenkins并行管道:参数块中的所有子程序调用都传递来自最后一个块的参数

时间:2016-10-10 12:36:10

标签: jenkins groovy parallel-processing closures jenkins-pipeline

我正在寻求帮助,了解Groovy闭包的内容以及"对"做某事的方法是。我有一个Jenkins管道,我在5个并行分支中调用子程序;它需要一个参数,其实际值是一个字符串常量 - 来自并行分支的每次调用中的一个不同的参数。我所看到的是,所有5个执行都接收到最后一个并行分支中命名的字符串常量:

段:

import {Injectable, Inject} from "@angular/core";
import { Http, Response, Headers, RequestOptions } from "@angular/http";
import { StorageServiceClass } from "../storage.service";
import "rxjs/add/operator/map";
import * as Cookies from "js-cookie";

import { Observable }   from "rxjs/Rx";
import {  Router } from "@angular/router";


@Injectable()
export class HttpClient {

    public storage: StorageServiceClass;

    private http: Http;
    private router: Router;

    constructor(private _http: Http, _router: Router, private _storage: StorageServiceClass) {
        this.http = _http;
        this.router = _router;
        this.storage = _storage;
    }

    public setToken() {
        let token = Cookies.get("authToken");
        if (token !== "undefined" && token !== undefined) {
            this.storage.setAuthToken(token);
        }
    }

    public removeStorageAndCookies() {
        Cookies.remove("authToken");
        this.storage.removeAuthToken();
    }

    public createAuthorizationHeader(headers: Headers) {
        let token = this.storage.getAuthToken();
        headers.append("Accept", "application/json");
        headers.append("Content-Type", "application/json");

        if (token !== null && token !== undefined) {
            headers.append("Authorization", "JWT " + token);
        }
    }

    public post(url: string, data: any, options?: RequestOptions) {
        let headers = new Headers();
        if (options !== undefined) {
            headers = options.headers;
        }
        this.createAuthorizationHeader(headers);
        let dataResp = this.intercept(this.http.post(url, data, { headers: headers, withCredentials: true }));
        this.setToken();
        return dataResp;
    }


    public put(url: string, data: any, options?: RequestOptions) {
        let headers = new Headers();
        if (options !== undefined) {
            headers = options.headers;
        }
        this.createAuthorizationHeader(headers);
        let dataResp = this.intercept(this.http.put(url, data, { headers: headers, withCredentials: true }));
        this.setToken();
        return dataResp;
    }

    public delete(url: string, options?: RequestOptions) {
        let headers = new Headers();
        if (options !== undefined) {
            headers = options.headers;
        }
        this.createAuthorizationHeader(headers);
        let dataResp = this.intercept(this.http.delete(url, { headers: headers, withCredentials: true }));
        this.setToken();
        return dataResp;
    }


    public get(url: string, data?: any, options?: RequestOptions) {
        let headers = new Headers();
        if (options !== undefined) {
            headers = options.headers;
        }
        this.createAuthorizationHeader(headers);

        let urlParams = "";
        if (data) {
            urlParams = jQuery.param(data);
        }

        let dataResp = this.intercept(this.http.get(url, {
            headers: headers, search: urlParams, withCredentials: true
        }));
        this.setToken();
        return dataResp;
    }

    public intercept(observable: Observable<Response>): Observable<Response> {
        return observable.catch((err, source) => {
            if (err.status === 401) {
                this.removeStorageAndCookies();
                this.router.navigate(["login"]);
                return Observable.empty();
            } else {
                return Observable.throw(err);
            }
        });
    }

}

输出:

def build_if_needed = { project ->
  println "build_if_needed: $project"
  // ultimately this will kick off a build job...
}

parallel (
  aaa : { build_if_needed('aaa')},
  bbb : { build_if_needed('bbb')},
  ccc : { build_if_needed('ccc')},
  ddd : { build_if_needed('ddd')},
  eee : { build_if_needed('eee')},
)

我希望[aaa]中转储的参数值为&#39; aaa&#39;而不是&#39; eee&#39;。它是作为参数传递的固定字符串常量。为什么所有5次执行&#39; build_if_needed&#39;从最终的并行调用接收字符串常量?我错过了什么?

有没有办法做我想做的事情?

2 个答案:

答案 0 :(得分:0)

在我的情况下(Jenkins 2.7.4)使用方法代替闭包很好:

def build_if_needed(project) {
  println "build_if_needed: $project"
  // ultimately this will kick off a build job...
}

parallel (
  aaa : { build_if_needed('aaa')},
  bbb : { build_if_needed('bbb')},
  ccc : { build_if_needed('ccc')},
  ddd : { build_if_needed('ddd')},
  eee : { build_if_needed('eee')}
)

根据我的经验,您应该尽可能避免在管道脚本中使用闭包。 Jenkins似乎在处理像https://issues.jenkins-ci.org/browse/JENKINS-26481这样的闭包时遇到了问题。

答案 1 :(得分:0)

这被认为是一个基本上是duplicate question的错误。它已被修复为Groovy Pipeline 2.35。