10

我正在使用 Python 2.7 和 Jenkins。

我正在用 Python 编写一些代码,这些代码将执行签入并等待/轮询以完成 Jenkins 作业。我想对我是如何实现它的一些想法。

  1. 在 Perforce 中创建签入的 Python 函数-> 这可以很容易地完成,因为 P4 有 CLI
  2. 用于检测何时触发构建的 Python 代码 -> 我有更改列表和作业编号。如何轮询构建日志的 Jenkins API 以检查它是否具有适当的更改列表?此步骤的输出是执行作业的构建 url
  3. 我如何等到詹金斯的工作完成?

我可以使用来自 Jenkins Rest API 或 Python Jenkins 模块的片段吗?

4

8 回答 8

7

如果您需要知道作业是否完成,则 buildNumber 和 buildTimestamp 是不够的。

这是我如何确定工作是否完成的要点,我在 ruby​​ 中有它,但在 python 中没有,所以也许有人可以将它更新为真正的代码。

lastBuild = get jenkins/job/myJob/lastBuild/buildNumber
get jenkins/job/myJob/lastBuild/build?token=gogogo

currentBuild = get jenkins/job/myJob/lastBuild/buildNumber
while currentBuild  == lastBuild 
  sleep 1 

thisBuild = get jenkins/job/myJob/lastBuild/buildNumber
buildInfo = get jenkins/job/myJob/[thisBuild]/api/xml?depth=0

while buildInfo["freeStyleBuild/building"] == true
  buildInfo = get jenkins/job/myJob/[thisBuild]/api/xml?depth=0
  sleep 1

IE。我发现我需要 A)等到构建开始(新版本号)和 B)等到构建完成(构建是错误的)。

于 2013-08-27T00:12:29.390 回答
4

您可以查询上次构建时间戳以确定构建是否完成。将其与触发构建之前的状态进行比较,并查看它何时发生变化。要获取时间戳,请添加/lastBuild/buildTimestamp到您的工作 URL

事实上,在你的 Jenkins 中,添加/lastBuild/api/到任何 Job 中,你都会看到很多 API 信息。它甚至有 Python API,但我不熟悉,所以不能进一步帮助你

但是,如果您使用的是 XML,则可以在 XML 中添加lastBuild/api/xml?depth=0和查看<changeSet>触发构建的修订/提交消息列表的对象

于 2013-03-11T13:59:57.573 回答
3

使用invokeblock_until_complete方法的简单解决方案(使用 Python 3.7 测试)

import jenkinsapi
from jenkinsapi.jenkins import Jenkins

...

server = Jenkins(jenkinsUrl, username=jenkinsUser,
                 password=jenkinsToken, ssl_verify=sslVerifyFlag)

job = server.create_job(jobName, None)
queue = job.invoke()
queue.block_until_complete()

受到 pycontribs 中的一种测试方法的启发

于 2019-02-26T10:04:14.003 回答
2

此代码段开始构建作业并等待作业完成。

开始工作很容易,但我们需要某种逻辑来知道工作何时完成。首先,我们需要等待作业 ID 被应用,然后我们可以查询作业以获取详细信息:

from jenkinsapi import jenkins

server = jenkins.Jenkins(jenkinsurl, username=username, password='******')
job = server.get_job(j_name)
prev_id = job.get_last_buildnumber()
server.build_job(j_name)
while True:
    print('Waiting for build to start...')
    if prev_id != job.get_last_buildnumber():
        break
    time.sleep(3)
print('Running...')
last_build = job.get_last_build()
while last_build.is_running():
    time.sleep(1)
print(str(last_build.get_status()))
于 2017-10-31T11:46:13.263 回答
2

不知道在提问时这是否可用,但 jenkinsapi 模块的 Job.invoke() 和/或 Jenkins.build_job() 返回一个 QueueItem 对象,该对象可以是 block_until_building() 或 block_until_complete()

jobq = server.build_job(job_name, job_params)
jobq.block_until_building()
print("Job %s (%s) is building." % (jobq.get_job_name(), jobq.get_build_number()))
jobq.block_until_complete(5) # check every 5s instead of the default 15
print("Job complete, %s" % jobq.get_build().get_status())
于 2018-08-27T20:01:34.387 回答
0

正在经历同样的问题,这对我有用,使用python3and python-jenkins.

while "".join([d['color'] for d in j.get_jobs() if d['name'] == "job_name"]) == 'blue_anime':
        print('Job is Running')
        time.sleep(1)

print('Job Over!!')

工作 Github 脚本:链接

于 2015-07-27T11:46:48.303 回答
0

这对我有用

#!/usr/bin/env python

import jenkins
import time

server = jenkins.Jenkins('https://jenkinsurl/', username='xxxxx', password='xxxxxx')

j_name = 'test'
server.build_job(j_name, {'testparam1': 'test', 'testparam2': 'test'})
while True:
    print('Running....')
    if server.get_job_info(j_name)['lastCompletedBuild']['number'] == server.get_job_info(j_name)['lastBuild']['number']:
        print "Last ID %s, Current ID %s"  % (server.get_job_info(j_name)['lastCompletedBuild']['number'], server.get_job_info(j_name)['lastBuild']['number'])
        break
time.sleep(3)
print('Stop....')

console_output = server.get_build_console_output(j_name, server.get_job_info(j_name)['lastBuild']['number'])
print console_output
于 2018-07-17T21:26:13.487 回答
0

build_job 不返回作业编号的问题主要问题,返回队列项目的编号(仅持续 5 分钟)。所以诀窍是

  1. build_job
  2. 获取队列号,
  3. 使用队列号获取 job_number
  4. 现在我们知道了工作的名称和工作编号
  5. get_job_info 并循环这些工作,直到我们找到一个带有我们工作编号的工作
  6. 检查状态

所以我用time_out为它做了一个函数

import time
from datetime import datetime, timedelta
import jenkins

def launch_job(jenkins_connection, job_name, parameters={}, wait=False, interval=30,  time_out=7200):
    """
    Create a jenkins job and waits for the job to finish
    :param jenkins_connection: jenkins server jenkins object
    :param job_name: the name of job we want to create and see if finish string
    :param parameters: the parameters of the job to build directory
    :param wait: if we want to wait for the job to finish or not bool
    :param interval: how often we want to monitor seconds int
    :param time_out: break the loop after certain X seconds int
    :return: build job number int
    """
    # we lunch the job and returns a queue_id
    job_id = jenkins_connection.build_job(job_name, parameters)
    # from the queue_id we get the job number that was created
    queue_job = jenkins_connection.get_queue_item(job_id, depth=0)
    build_number = queue_job["executable"]["number"]
    print(f"job_name: {job_name} build_number: {build_number}")
    if wait is True:
        now = datetime.now()
        later = now + timedelta(seconds=time_out)

        while True:
            # we check current time vs the timeout(later)
            if datetime.now() > later:
                raise ValueError(f"Job: {job_name}:{build_number} is running for more than {time_out} we"
                                 f"stop monitoring the job,  you can check it in Jenkins")
            b = jenkins_connection.get_job_info(job_name, depth=1, fetch_all_builds=False)
            for i in b["builds"]:
                loop_id = i["id"]
                if int(loop_id) == build_number:
                    result = (i["result"])
                    print(f"result: {result}")  # in the json looks like null
                    if result is not None:
                        return i
                        # break
            time.sleep(interval)
        # return result

    return build_number

在我们要求詹金斯构建作业>获取队列#>获取作业#>循环信息并获取状态直到从无变为其他内容之后。if works 将返回包含该作业信息的目录。(希望詹金斯库可以实现这样的东西。)

于 2022-01-26T17:59:29.227 回答