Obtain job id from a workflow run using contexts
Asked Answered
A

7

20

I have a problem, when I want to get the job id using the GitHub context in yaml file, it responds with a String:

  - name: Test
    run: |
      sendEmail ${{github.job]}

I obtain this response:

sendEmail Job_Test

In the GitHub documentation for the API, it says the following, which is an Integer field: enter image description here

But, in the documentation of the contexts it says that it is String: enter image description here

My question is, what is it or how could I obtain the context to obtain the job id, the integer value?

Alidia answered 23/2, 2022 at 16:5 Comment(0)
N
16

There is no straight way to do that - those are not the same values.

The only solution I know is to:

  1. read github.job getting the key
  2. get list of jobs for a workflow using API: /repos/{owner}/{repo}/actions/runs/{run_id}/jobs
  3. find the job by the name and get id as int value
Notorious answered 23/2, 2022 at 17:48 Comment(1)
Unfortunately if the job contains matrix strategy it becomes impossible to find the right id. For example job1 is started for ubuntu-latest and ubuntu-20.04. In both cases github.job is job1, but two separate jobs are created for them :/Parashah
U
8

There's a GitHub action to solve this problem: https://github.com/marketplace/actions/github-actions-job_id-parser

 - name: Get Current Job Log URL
    uses: Tiryoh/gha-jobid-action@v0
    id: jobs
    with:
      github_token: ${{ secrets.GITHUB_TOKEN }}
      job_name: ${{ github.job }}

- name: Output Current Job Log URL
  run: echo ${{ steps.jobs.outputs.html_url }}
Unfailing answered 16/8, 2022 at 15:12 Comment(1)
This only works for very simple cases. If you've got a matrix or the workflow is called from another workflow it's not straight forward to get the job_name and the action will fail.Lie
A
8

This information is not available in the github context level, however you can just filter out it, using a unique job information, like the runner.name. In this way you can get job id for any case, including matrix.

  - name: Get Job ID from GH API
    id: get-job-id
    env:
      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    run: |
      jobs=$(gh api repos/${{ github.repository }}/actions/runs/${{ github.run_id}}/attempts/${{ github.run_attempt }}/jobs)
      job_id=$(echo $jobs | jq -r '.jobs[] | select(.runner_name=="${{ runner.name }}") | .id')
      echo "job_id=$job_id" >> $GITHUB_OUTPUT

  - name: Display Job ID
    run: |
      echo Job ID: ${{ steps.get-job-id.outputs.job_id }}
      echo My full job URL is ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/job/${{ steps.get-job-id.outputs.job_id }}
Automaton answered 3/8, 2023 at 15:0 Comment(4)
The runner.name trick did the job great even when using a matrix strategy. Indeed github.job cannot work because on matrix strategy, the job name is actually appended with some element of the matrix strategy so you don't get the right now.Defeatist
Unfortunately, as much as I wish this was a working solution, runner.name is not a "a unique job information" as stated in this answer. See the GitHub Actions docs: "runner.name - The name of the runner executing the job. This name may not be unique in a workflow run (...)". So it seems the only reliable way remains to find the job by its name - github.com/Tiryoh/gha-jobid-action can do this for you, you just need to provide correct job_name (works for matrix jobs too, see README).Lyricist
I verified the non-uniqueness of runner IDs/names in practice by querying the GitHub REST API for a workflow run with 41 jobs - although all jobs had some runner_name, there were only 20 unique runner names in total, which matches the maximum number of concurrent jobs in the GitHub Free plan (this makes sense - more than 20 jobs are not allowed run concurrently, so it seems that when a runner finishes one job, it gets another one from the queue - hence the repeating runner IDs).Lyricist
Solid foundation here, which I used as a basis for my proposed solution using native github-script's context and applicable for matrices of any size/order.Tampere
H
2

Job ID may be obtained with curl command (piped to jq):

curl -L \
  -H "Accept: application/vnd.github+json" \
  -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"\
  -H "X-GitHub-Api-Version: 2022-11-28" \
  https://api.github.com/repos/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}/attempts/${GITHUB_RUN_ATTEMPT}/jobs | jq .jobs[].id

where all ENVs GITHUB_* should be accessible inside workflow by default

For example

    - name: Get link to this run
      run: |
        # https://stackoverflow.com/a/75734917
        workflow_id=$(curl -L \
          -H "Accept: application/vnd.github+json" \
          -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"\
          -H "X-GitHub-Api-Version: 2022-11-28" \
          https://api.github.com/repos/${GITHUB_REPOSITORY}/actions/runs/${GITHU
B_RUN_ID}/attempts/${GITHUB_RUN_ATTEMPT}/jobs | jq .jobs[].id )
        RUN_URL=https://github.com/${{ github.repository }}/actions/runs/${{ git
hub.run_id }}/job/${workflow_id}
        echo "RUN_URL=${RUN_URL}" >> $GITHUB_ENV
      shell: bash

PS jobs value is list so multiple IDs may be returned

Herbarium answered 14/3, 2023 at 15:5 Comment(0)
M
1

for a matrix strategy, although not pretty this will get the html url to the proper matrix job (in this example, the "name" of each individual matrix job is matrix.region): gh api repos/${{ github.repository }}/actions/runs/${{ github.run_id}}/attempts/${{ github.run_attempt }}/jobs | jq -r '.jobs | map(select(.name | contains("${{ matrix.region }}"))) | .[0].html_url'. example:

 example-job:
    name: ${{ matrix.region }}
    runs-on: ubuntu-latest
    strategy:
      matrix:
        region: ["us-east-1", "us-west-2"]
      - name: example-matrix-step
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          job_id=$(gh api repos/${{ github.repository }}/actions/runs/${{ github.run_id}}/attempts/${{ github.run_attempt }}/jobs | jq -r '.jobs | .[0].id')
          matrix_job_html_url=$(gh api repos/${{ github.repository }}/actions/runs/${{ github.run_id}}/attempts/${{ github.run_attempt }}/jobs | jq -r '.jobs | map(select(.name | contains("${{ matrix.region }}"))) | .[0].html_url')
          matrix_id=$( sed 's/.*\jobs\///' <<<$matrix_job_html_url)
          echo "matrix job html url: $matrix_job_html_url"
          echo "matrix id: $matrix_id" # i doubt this is of any use. in the github response this id is only present as part of the html_url
          echo "job id: $job_id"
Margertmargery answered 8/7, 2023 at 1:55 Comment(0)
T
1

While it'd be ideal to have a separate github.job_id alongside the existing github.job, the main challenges here are:

  1. Obtainable from contexts alone.
  2. Compatible with matrix strategy (without hard-coding).

Most of the answers here fall short of handling matrices, so here's my working solution to this which leverages native actions/github-script's context.

steps:
  - name: Resolve job ID from workflow run, accounting for matrix strategy.
    id: job_id
    uses: actions/github-script@main
    env:
      matrix: ${{ toJson(matrix) }}
    with:
      script: |
        const { data: workflow_run } = await github.rest.actions.listJobsForWorkflowRun({
          owner: context.repo.owner,
          repo: context.repo.repo,
          run_id: context.runId
        });
        const matrix = JSON.parse(process.env.matrix);
        const job_name = `${context.job}${matrix ? ` (${Object.values(matrix).join(", ")})` : ""}`;
        return workflow_run.jobs.find((job) => job.name === job_name).id;

  - name: Print job ID
    run: echo "${{ steps.job_id.outputs.result }}"

Of note:

  • Obtain context from octokit/rest.js's rest.actions.listJobsForWorkflowRun, as documented in REST API endpoints.
  • If matrix context is present, represent it as a comma-separated string of values (e.g., convert { "os": "ubuntu-latest", "node": 20 } to ubuntu-latest, 20).
  • Surround this string in () parentheses then append to context.job using a ternary operator, enabling it to work with or without a matrix of any size/order.
  • Return the associated ID matching the job name for use/reference in later steps.
Tampere answered 16/3, 2024 at 9:14 Comment(0)
M
0

Feel free to use my action to access current job_id (among other context information)

Example Workflow

jobs:
  example:
    runs-on: ubuntu-latest
    environment: playground
    permissions:
      actions:     read  # required for qoomon/actions--context action
      deployments: read  # required for qoomon/actions--context action
      contents: read
    steps:
      - uses: qoomon/actions--context@v1
        id: context

      - run: |
          echo "Current Environment: ${{ steps.context.outputs.environment }}"
          echo "Job ID: ${{ steps.context.outputs.job_id }}"
          echo "Job Logs: ${{ steps.context.outputs.job_log_url }}"
Magallanes answered 2/8, 2024 at 16:11 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.