触发 github 工作流调度事件后获取 运行 id
Get run id after triggering a github workflow dispatch event
我正在通过 github 的其余部分 api 触发工作流 运行。但是 github 不会在响应正文 (204) 中发送任何数据。
我如何获得触发请求的 运行 id?
我知道 getRunsList
api,它将 return 运行s 作为工作流 ID,然后我可以获得最新的 运行,但这可能会导致问题当几乎同时提交两个请求时。
目前无法在调度响应本身中获取与调度 API 调用关联的 run_id,但是如果您可以编辑您的 worflow 文件,则有一种方法可以找到它有一点。
您需要像这样 input
分派工作流:
curl "https://api.github.com/repos/$OWNER/$REPO/actions/workflows/$WORKFLOW/dispatches" -s \
-H "Authorization: Token $TOKEN" \
-d '{
"ref":"master",
"inputs":{
"id":"12345678"
}
}'
同时使用可选 input
(此处命名为 id
)编辑您的工作流 yaml 文件。此外,将它作为第一个作业,一个具有与输入 id
值相同名称的单个步骤的作业(这就是我们使用 API 取回 id 的方式!):
name: ID Example
on:
workflow_dispatch:
inputs:
id:
description: 'run identifier'
required: false
jobs:
id:
name: Workflow ID Provider
runs-on: ubuntu-latest
steps:
- name: ${{github.event.inputs.id}}
run: echo run identifier ${{ inputs.id }}
这里的技巧是使用name: ${{github.event.inputs.id}}
https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#inputs
那么流程如下:
运行 dispatch API 调用以及名为 id
的 input
在这种情况下具有随机值
POST https://api.github.com/repos/$OWNER/$REPO/actions/workflows/$WORKFLOW/dispatches
在循环中获取自现在减去 5 分钟后创建的 运行s(增量是为了避免任何时间问题):
GET https://api.github.com/repos/$OWNER/$REPO/actions/runs?created=>$run_date_filter
在 运行 API 响应中,您将得到一个 jobs_url
,您将调用:
GET https://api.github.com/repos/$OWNER/$REPO/actions/runs/[RUN_ID]/jobs
作业 API 在上面调用 returns 作业列表,因为您已将 id
作业声明为第一个作业,它将位于第一个位置.它还为您提供 steps
和 name
的步骤。像这样:
{
"id": 3840520726,
"run_id": 1321007088,
"run_url": "https://api.github.com/repos/$OWNER/$REPO/actions/runs/1321007088",
"run_attempt": 1,
"node_id": "CR_kwDOEi1ZxM7k6bIW",
"head_sha": "4687a9bb5090b0aadddb69cc335b7d9e80a1601d",
"url": "https://api.github.com/repos/$OWNER/$REPO/actions/jobs/3840520726",
"html_url": "https://github.com/$OWNER/$REPO/runs/3840520726",
"status": "completed",
"conclusion": "success",
"started_at": "2021-10-08T15:54:40Z",
"completed_at": "2021-10-08T15:54:43Z",
"name": "Hello world",
"steps": [
{
"name": "Set up job",
"status": "completed",
"conclusion": "success",
"number": 1,
"started_at": "2021-10-08T17:54:40.000+02:00",
"completed_at": "2021-10-08T17:54:42.000+02:00"
},
{
"name": "12345678", <=============== HERE
"status": "completed",
"conclusion": "success",
"number": 2,
"started_at": "2021-10-08T17:54:42.000+02:00",
"completed_at": "2021-10-08T17:54:43.000+02:00"
},
{
"name": "Complete job",
"status": "completed",
"conclusion": "success",
"number": 3,
"started_at": "2021-10-08T17:54:43.000+02:00",
"completed_at": "2021-10-08T17:54:43.000+02:00"
}
],
"check_run_url": "https://api.github.com/repos/$OWNER/$REPO/check-runs/3840520726",
"labels": [
"ubuntu-latest"
],
"runner_id": 1,
"runner_name": "Hosted Agent",
"runner_group_id": 2,
"runner_group_name": "GitHub Actions"
}
id
步骤的 name
正在 returning 您的输入值,因此您可以放心地确认是由您的 dispatch 触发的 运行打电话
这是 python 中此流程的一个实现,它将 return 工作流 运行 id:
import random
import string
import datetime
import requests
import time
# edit the following variables
owner = "YOUR_ORG"
repo = "YOUR_REPO"
workflow = "dispatch.yaml"
token = "YOUR_TOKEN"
authHeader = { "Authorization": f"Token {token}" }
# generate a random id
run_identifier = ''.join(random.choices(string.ascii_uppercase + string.digits, k=15))
# filter runs that were created after this date minus 5 minutes
delta_time = datetime.timedelta(minutes=5)
run_date_filter = (datetime.datetime.utcnow()-delta_time).strftime("%Y-%m-%dT%H:%M")
r = requests.post(f"https://api.github.com/repos/{owner}/{repo}/actions/workflows/{workflow}/dispatches",
headers= authHeader,
json= {
"ref":"master",
"inputs":{
"id": run_identifier
}
})
print(f"dispatch workflow status: {r.status_code} | workflow identifier: {run_identifier}")
workflow_id = ""
while workflow_id == "":
r = requests.get(f"https://api.github.com/repos/{owner}/{repo}/actions/runs?created=%3E{run_date_filter}",
headers = authHeader)
runs = r.json()["workflow_runs"]
if len(runs) > 0:
for workflow in runs:
jobs_url = workflow["jobs_url"]
print(f"get jobs_url {jobs_url}")
r = requests.get(jobs_url, headers= authHeader)
jobs = r.json()["jobs"]
if len(jobs) > 0:
# we only take the first job, edit this if you need multiple jobs
job = jobs[0]
steps = job["steps"]
if len(steps) >= 2:
second_step = steps[1] # if you have position the run_identifier step at 1st position
if second_step["name"] == run_identifier:
workflow_id = job["run_id"]
else:
print("waiting for steps to be executed...")
time.sleep(3)
else:
print("waiting for jobs to popup...")
time.sleep(3)
else:
print("waiting for workflows to popup...")
time.sleep(3)
print(f"workflow_id: {workflow_id}")
示例输出
$ python3 github_action_dispatch_runid.py
dispatch workflow status: 204 | workflow identifier: Z7YPF6DD1YP2PTM
get jobs_url https://api.github.com/repos/OWNER/REPO/actions/runs/1321463229/jobs
get jobs_url https://api.github.com/repos/OWNER/REPO/actions/runs/1321463229/jobs
get jobs_url https://api.github.com/repos/OWNER/REPO/actions/runs/1321463229/jobs
get jobs_url https://api.github.com/repos/OWNER/REPO/actions/runs/1321475221/jobs
waiting for steps to be executed...
get jobs_url https://api.github.com/repos/OWNER/REPO/actions/runs/1321463229/jobs
get jobs_url https://api.github.com/repos/OWNER/REPO/actions/runs/1321475221/jobs
waiting for steps to be executed...
get jobs_url https://api.github.com/repos/OWNER/REPO/actions/runs/1321463229/jobs
get jobs_url https://api.github.com/repos/OWNER/REPO/actions/runs/1321475221/jobs
waiting for steps to be executed...
get jobs_url https://api.github.com/repos/OWNER/REPO/actions/runs/1321463229/jobs
get jobs_url https://api.github.com/repos/OWNER/REPO/actions/runs/1321475221/jobs
get jobs_url https://api.github.com/repos/OWNER/REPO/actions/runs/1321463229/jobs
workflow_id: 1321475221
如果有一种方法可以通过 API 检索工作流输入,那会更容易,但目前无法做到这一点
请注意,在 worflow 文件中,我使用 ${{github.event.inputs.id}}
,因为 ${{inputs.id}}
不起作用。当我们使用它作为步骤名称时,似乎 inputs
没有被评估
获取 WORKFLOWID
gh workflow list --repo <repo-name>
workflow_dispatch
类型的触发器工作流
gh workflow run $WORKFLOWID --repo <repo-name>
不return需要run-id得到执行状态
获取最新的run-idWORKFLOW_RUNID
gh run list -w $WORKFLOWID --repo <repo> -L 1 --json databaseId | jq '.[]| .databaseId'
获取工作流程运行详细信息
gh run view --repo <repo> $WORKFLOW_RUNID
这是我们所做的解决方法。它并不完美,但应该可以。
整个想法是知道哪个 运行 被调度,当 id 被建议在调度时使用时,这个 id 应该在对这个 url 的 GET 调用的响应中找到“actions/runs”所以现在用户能够识别正确的 运行 监视器。注入的 ID 不是响应的一部分,因此提取另一个 url 来查找您的 ID 没有帮助,因为这是识别 运行 以进行监控
所需的点
我正在通过 github 的其余部分 api 触发工作流 运行。但是 github 不会在响应正文 (204) 中发送任何数据。
我如何获得触发请求的 运行 id?
我知道 getRunsList
api,它将 return 运行s 作为工作流 ID,然后我可以获得最新的 运行,但这可能会导致问题当几乎同时提交两个请求时。
目前无法在调度响应本身中获取与调度 API 调用关联的 run_id,但是如果您可以编辑您的 worflow 文件,则有一种方法可以找到它有一点。
您需要像这样 input
分派工作流:
curl "https://api.github.com/repos/$OWNER/$REPO/actions/workflows/$WORKFLOW/dispatches" -s \
-H "Authorization: Token $TOKEN" \
-d '{
"ref":"master",
"inputs":{
"id":"12345678"
}
}'
同时使用可选 input
(此处命名为 id
)编辑您的工作流 yaml 文件。此外,将它作为第一个作业,一个具有与输入 id
值相同名称的单个步骤的作业(这就是我们使用 API 取回 id 的方式!):
name: ID Example
on:
workflow_dispatch:
inputs:
id:
description: 'run identifier'
required: false
jobs:
id:
name: Workflow ID Provider
runs-on: ubuntu-latest
steps:
- name: ${{github.event.inputs.id}}
run: echo run identifier ${{ inputs.id }}
这里的技巧是使用name: ${{github.event.inputs.id}}
https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#inputs
那么流程如下:
运行 dispatch API 调用以及名为
id
的input
在这种情况下具有随机值POST https://api.github.com/repos/$OWNER/$REPO/actions/workflows/$WORKFLOW/dispatches
在循环中获取自现在减去 5 分钟后创建的 运行s(增量是为了避免任何时间问题):
GET https://api.github.com/repos/$OWNER/$REPO/actions/runs?created=>$run_date_filter
在 运行 API 响应中,您将得到一个
jobs_url
,您将调用:GET https://api.github.com/repos/$OWNER/$REPO/actions/runs/[RUN_ID]/jobs
作业 API 在上面调用 returns 作业列表,因为您已将
id
作业声明为第一个作业,它将位于第一个位置.它还为您提供steps
和name
的步骤。像这样:
{
"id": 3840520726,
"run_id": 1321007088,
"run_url": "https://api.github.com/repos/$OWNER/$REPO/actions/runs/1321007088",
"run_attempt": 1,
"node_id": "CR_kwDOEi1ZxM7k6bIW",
"head_sha": "4687a9bb5090b0aadddb69cc335b7d9e80a1601d",
"url": "https://api.github.com/repos/$OWNER/$REPO/actions/jobs/3840520726",
"html_url": "https://github.com/$OWNER/$REPO/runs/3840520726",
"status": "completed",
"conclusion": "success",
"started_at": "2021-10-08T15:54:40Z",
"completed_at": "2021-10-08T15:54:43Z",
"name": "Hello world",
"steps": [
{
"name": "Set up job",
"status": "completed",
"conclusion": "success",
"number": 1,
"started_at": "2021-10-08T17:54:40.000+02:00",
"completed_at": "2021-10-08T17:54:42.000+02:00"
},
{
"name": "12345678", <=============== HERE
"status": "completed",
"conclusion": "success",
"number": 2,
"started_at": "2021-10-08T17:54:42.000+02:00",
"completed_at": "2021-10-08T17:54:43.000+02:00"
},
{
"name": "Complete job",
"status": "completed",
"conclusion": "success",
"number": 3,
"started_at": "2021-10-08T17:54:43.000+02:00",
"completed_at": "2021-10-08T17:54:43.000+02:00"
}
],
"check_run_url": "https://api.github.com/repos/$OWNER/$REPO/check-runs/3840520726",
"labels": [
"ubuntu-latest"
],
"runner_id": 1,
"runner_name": "Hosted Agent",
"runner_group_id": 2,
"runner_group_name": "GitHub Actions"
}
id
步骤的 name
正在 returning 您的输入值,因此您可以放心地确认是由您的 dispatch 触发的 运行打电话
这是 python 中此流程的一个实现,它将 return 工作流 运行 id:
import random
import string
import datetime
import requests
import time
# edit the following variables
owner = "YOUR_ORG"
repo = "YOUR_REPO"
workflow = "dispatch.yaml"
token = "YOUR_TOKEN"
authHeader = { "Authorization": f"Token {token}" }
# generate a random id
run_identifier = ''.join(random.choices(string.ascii_uppercase + string.digits, k=15))
# filter runs that were created after this date minus 5 minutes
delta_time = datetime.timedelta(minutes=5)
run_date_filter = (datetime.datetime.utcnow()-delta_time).strftime("%Y-%m-%dT%H:%M")
r = requests.post(f"https://api.github.com/repos/{owner}/{repo}/actions/workflows/{workflow}/dispatches",
headers= authHeader,
json= {
"ref":"master",
"inputs":{
"id": run_identifier
}
})
print(f"dispatch workflow status: {r.status_code} | workflow identifier: {run_identifier}")
workflow_id = ""
while workflow_id == "":
r = requests.get(f"https://api.github.com/repos/{owner}/{repo}/actions/runs?created=%3E{run_date_filter}",
headers = authHeader)
runs = r.json()["workflow_runs"]
if len(runs) > 0:
for workflow in runs:
jobs_url = workflow["jobs_url"]
print(f"get jobs_url {jobs_url}")
r = requests.get(jobs_url, headers= authHeader)
jobs = r.json()["jobs"]
if len(jobs) > 0:
# we only take the first job, edit this if you need multiple jobs
job = jobs[0]
steps = job["steps"]
if len(steps) >= 2:
second_step = steps[1] # if you have position the run_identifier step at 1st position
if second_step["name"] == run_identifier:
workflow_id = job["run_id"]
else:
print("waiting for steps to be executed...")
time.sleep(3)
else:
print("waiting for jobs to popup...")
time.sleep(3)
else:
print("waiting for workflows to popup...")
time.sleep(3)
print(f"workflow_id: {workflow_id}")
示例输出
$ python3 github_action_dispatch_runid.py
dispatch workflow status: 204 | workflow identifier: Z7YPF6DD1YP2PTM
get jobs_url https://api.github.com/repos/OWNER/REPO/actions/runs/1321463229/jobs
get jobs_url https://api.github.com/repos/OWNER/REPO/actions/runs/1321463229/jobs
get jobs_url https://api.github.com/repos/OWNER/REPO/actions/runs/1321463229/jobs
get jobs_url https://api.github.com/repos/OWNER/REPO/actions/runs/1321475221/jobs
waiting for steps to be executed...
get jobs_url https://api.github.com/repos/OWNER/REPO/actions/runs/1321463229/jobs
get jobs_url https://api.github.com/repos/OWNER/REPO/actions/runs/1321475221/jobs
waiting for steps to be executed...
get jobs_url https://api.github.com/repos/OWNER/REPO/actions/runs/1321463229/jobs
get jobs_url https://api.github.com/repos/OWNER/REPO/actions/runs/1321475221/jobs
waiting for steps to be executed...
get jobs_url https://api.github.com/repos/OWNER/REPO/actions/runs/1321463229/jobs
get jobs_url https://api.github.com/repos/OWNER/REPO/actions/runs/1321475221/jobs
get jobs_url https://api.github.com/repos/OWNER/REPO/actions/runs/1321463229/jobs
workflow_id: 1321475221
如果有一种方法可以通过 API 检索工作流输入,那会更容易,但目前无法做到这一点
请注意,在 worflow 文件中,我使用 ${{github.event.inputs.id}}
,因为 ${{inputs.id}}
不起作用。当我们使用它作为步骤名称时,似乎 inputs
没有被评估
获取 WORKFLOWID
gh workflow list --repo <repo-name>
workflow_dispatch
类型的触发器工作流gh workflow run $WORKFLOWID --repo <repo-name>
不return需要run-id得到执行状态
获取最新的run-idWORKFLOW_RUNID
gh run list -w $WORKFLOWID --repo <repo> -L 1 --json databaseId | jq '.[]| .databaseId'
获取工作流程运行详细信息
gh run view --repo <repo> $WORKFLOW_RUNID
这是我们所做的解决方法。它并不完美,但应该可以。
整个想法是知道哪个 运行 被调度,当 id 被建议在调度时使用时,这个 id 应该在对这个 url 的 GET 调用的响应中找到“actions/runs”所以现在用户能够识别正确的 运行 监视器。注入的 ID 不是响应的一部分,因此提取另一个 url 来查找您的 ID 没有帮助,因为这是识别 运行 以进行监控
所需的点