How can I attach a manual workflow run to a pull request's status checks?
Asked Answered
A

3

9

I have a workflow which runs a test job under given circumstances automatically, or I can run it manually:

name: Test

on:
  workflow_dispatch:
    inputs:
      used-branch:
        description: Branch the test shall be run on
        default: master
        required: true
  push:
    branches: ['main', 'master']
    tags: ['!**']
  pull_request:
    types: [opened, reopened, ready_for_review]

jobs:
  test:
    steps:
      - name: Checkout selected branch
        uses: actions/checkout@v3
        if: inputs.used-branch != ''
        with:
          ref: ${{ github.event.inputs.used-branch }}
      - name: Checkout current branch
        uses: actions/checkout@v3
        with:
          ref: ${{github.ref}}
        if: inputs.used-branch == ''
      - name: Run test
        ...

I want the test be required before merging. So I check Require status check to pass before merging, Require branches to be up to date before merging and specify test as required job in the repo's branch settings.

The problem is: when I run the workflow manually (and therefore inject the branch via a variable), it's not related to the branch and its success won't be "discovered" by the PR checks.

Is there another way to link the run to a branch, or another way to propagate the result to the branch's pull request?

Aguie answered 20/12, 2022 at 19:3 Comment(5)
I 100% understand your question and once you start to work around GitHub's API design things get complicated. My best guess is you will need to resort to using the API when running manually... see: github.com/orgs/community/discussions/24616 & docs.github.com/en/rest/checks?apiVersion=2022-11-28 & docs.github.com/en/pull-requests/…Boart
@Boart Thanks for your response! So there's no "configurable" way to achieve this right now. Well, if that's the answer, then feel free to provide it and I will accept it! I don't see myself tinkering with API for now, I think. A workaround is closing and reopening the PR, and maybe I find a even less wonky way (pr_comment don't exist either, sadly) for the time being. :)Aguie
pr_comment events are handled via issue_comment because pull requests are just issues with code... docs.github.com/en/actions/using-workflows/…Boart
@Boart Oh, I see. After skimming briefly over this topic I thought it would mean a comment in a referred issue (for my defense, I hadn't the time for a proper read yet). So thanks for your clarification, maybe that's a good compromise to head for!Aguie
I've spent the last six months buried in GHA so I have got all the bruises from learning it :)Boart
B
0

Took me a minute to digest what you were asking, but now I get it. (Updated title to be more precise).

Short answer, it isn't possible out of the box. Once you start to work around GitHub's API design things get complicated.

The only plausible solution I can think of today is via GitHub API.

See:

Boart answered 21/12, 2022 at 19:12 Comment(2)
> The only plausible solution I can think of today is via GitHub API. could you expand on this?Lumpy
@Lumpy I haven't explored the checks api before, but essentially you need to map all non pull_request triggers to a PR and then use the api to set the proper status on the PR.Boart
C
6

There is a way to do this via the api. You can run a step conditionally based on your manual input, and use the github.checks.create action from github-script.

Assuming that you give your step name: Run test and id of tests-step, here is an example:

- name: Report tests check
  if: ${{ github.event.inputs.used-branch && steps.tests-step.outcome }}
  uses: actions/github-script@v3
  with:
    github-token: ${{ secrets.GITHUB_TOKEN }}
    script: |
      github.checks.create({
        name: 'run tests',
        head_sha: '${{ github.event.issue.pull_request.head.sha }}',
        status: 'completed',
        conclusion: '${{ steps.tests-step.outcome }}',
        output: {
          title: 'Run tests',
          summary: 'Results: ${{ steps.tests-step.outcome }}'
        },
        owner: context.repo.owner,
        repo: context.repo.repo
      })

Note that GITHUB_TOKEN is automatically built in to your workflows.

The head_sha parameter is tricky and needs to be there for the commit annotation to work. The issue property of github.event.issue in this case refers to the PR (github sees it as an "issue") that will be annotated.

The trouble here is that if you run your workflow using workflow_dispatch, you will not have access to this value, since there is no PR in the context of a manual run.

One solution would be to have an input requiring the PR number, and a script to get the sha. Here is how you can do that:

- name: get sha from PR number and save output
  id: get-sha
  uses: actions/github-script@v3
  with:
    github-token: ${{ secrets.GITHUB_TOKEN }}
    script: |
      console.log('PR number: ' + ${{ github.event.issue.number }})
      const pr = await github.pulls.get({
        owner: context.repo.owner,
        repo: context.repo.repo,
        pull_number: ${{ github.event.issue.number }}
      })
      console.log('PR Head sha: ' + pr.data.head.sha)
      core.setOutput('sha', pr.data.head.sha)
Canopus answered 11/10, 2023 at 16:32 Comment(2)
what process needs the get-sha value of the output "sha"? I still can't find a correlationPropylaeum
@MarcelloDeSales the sha output is a solution for cases where your workflow was activated manually (not a PR) in which case you need to get a SHA value in order to call the checks api. The solution should be updated to use $GITHUB_OUTPUT but the logic is the sameCanopus
F
3

Not a real solution, as GitHub doesn't support this as you observed, but a workaround is to trigger the workflow from something that happens with the pull request. E.g. it can be triggered when a label is added to the PR (like "run-tests") or the PR is approved (which needs a combination of a trigger and job condition). A special comment would work as well, though that's less intuitive.

While these are not exactly the dispatch trigger you asked about, but I think they cover the "run workflow manually" use-case.

Firooc answered 27/5, 2023 at 10:7 Comment(8)
Hey, not sure all of this would work, though. I tried an approach where a \test comment in the PR triggered the tests, but this didn't update the checks either. For now, I'm switching a PR to Draft and back, which triggere a workflow that get actually recognized, similar to what you've suggested.Aguie
@Aguie these should work. How does your jobs look like? anyway, I know you said it triggered the tests, but tests that are triggered by issue_comment event will only be triggered if the workflow file is in the main branch (source)Lumpy
Yep, we actually use the label approach; first tried the PR approval one what also works but we didn't like it for other reasons.Firooc
@Lumpy You're right, I did some adjustments and it's working. So now a /test comment in the PR triggers a workflow whose result is detected by the PR's status checks.Aguie
Hey @NotX.. do you have a code snippet on how you got it working after that adjustment? I have a comment check (and tried a workflow run) merged into main, but new PRs still don't seem to be working. (it runs on comment, but doesn't update the comment)Bostic
Hey @Bostic Here's a slightly simplified gist of my WF. I'm sure for the core logic you're asking for can be simplified even more, but I don't really have the time atm to do that. Anyway, I hope you'll get the ... well ... gist of it. If not, I'll try to simplify the example the next days. :)Aguie
Thanks! I see the key is to just use myrotvorets/set-commit-status-action@master I was moreso curious if there is a way without a third-party action, but this will doBostic
Well, you could probably check @Bostic I see! You probably have to utililze the Check Runs API as recommended here: #72532026Aguie
B
0

Took me a minute to digest what you were asking, but now I get it. (Updated title to be more precise).

Short answer, it isn't possible out of the box. Once you start to work around GitHub's API design things get complicated.

The only plausible solution I can think of today is via GitHub API.

See:

Boart answered 21/12, 2022 at 19:12 Comment(2)
> The only plausible solution I can think of today is via GitHub API. could you expand on this?Lumpy
@Lumpy I haven't explored the checks api before, but essentially you need to map all non pull_request triggers to a PR and then use the api to set the proper status on the PR.Boart

© 2022 - 2024 — McMap. All rights reserved.