Oscar P
Oscar P

Reputation: 407

Obtain job id from a workflow run using contexts

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?

Upvotes: 23

Views: 18223

Answers (8)

daleyjem
daleyjem

Reputation: 2674

I gave the Tiryoh/gha-jobid-action action a try, but it requires the runner to have jq and curl installed. I prefer something a bit more independent, without the need to do any additional apt-get commands for containers without either of those.

So I made my own, borrowing much of the technique, and mimicking the same inputs/outputs.

daleyjem/gh-job-id@v1

Implementation would look something like this:

name: Verifications
on:
  push:
    branches:
      - main

jobs:
  manual-check:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Get job info
        id: my_action
        uses: daleyjem/gh-job-id@v1
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          job_name: "manual-check"

      # access job_id from action output
      - name: Output our action
        run: echo ${{ steps.my_action.outputs.job_id }} - ${{ steps.my_action.outputs.html_url }}

Upvotes: 1

rzlvmp
rzlvmp

Reputation: 9422

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

Upvotes: 2

qoomon
qoomon

Reputation: 5306

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 }}"

Upvotes: 0

Rishav
Rishav

Reputation: 125

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.

Upvotes: 1

marescab
marescab

Reputation: 245

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"

Upvotes: 1

Lucio Veloso
Lucio Veloso

Reputation: 1000

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 }}

Upvotes: 10

t2d
t2d

Reputation: 476

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 }}

Upvotes: 8

Grzegorz Krukowski
Grzegorz Krukowski

Reputation: 19862

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

Upvotes: 17

Related Questions