peter-evans/create-pull-request

PRs created don't trigger other actions

abatilo opened this issue ยท 31 comments

It seems that any PRs that get created by this action will not trigger any actions waiting on a pull request event, which means that you can have any required status checks.

Any ideas for how to get around this?

This is a deliberate limitation imposed by GitHub Actions that an action cannot trigger other workflows. From the documentation:

An action in a workflow run can't trigger a new workflow run. For example, if an action pushes code using the repository's GITHUB_TOKEN, a new workflow will not run even when the repository contains a workflow configured to run when push events occur.

https://help.github.com/en/articles/events-that-trigger-workflows#example-using-more-than-one-event

I'm not sure if there are any work arounds. I guess you would need another event to trigger the additional workflow.

I've found a work around. It looks like GitHub are determining that API calls are coming from actions by checking the authentication token. If you use a repo scoped token instead of the default GITHUB_TOKEN then the on: pull_request workflow will run checks against the created pull request.

Create a repo scoped token at https://github.com/settings/tokens and then add it as a secret to the repository your workflow runs in. It will be under https://github.com/[username]/[repo]/settings/secrets

Use that secret in your workflow and assign it to the environment variable GITHUB_TOKEN.

    - name: Create Pull Request
      uses: peter-evans/create-pull-request@v1.3.1
      env:
        GITHUB_TOKEN: ${{ secrets.REPO_SCOPED_TOKEN }}

There is a downside to this method. The PR is no longer created by the github-actions bot user and instead appears to be created by the user associated with the token.

image

I contacted GitHub about this issue and their response confirms that using a personal token as I outlined above is the correct approach.

From GitHub Support:

This is a deliberate decision by the Actions team in order to prevent accidental "infinite loop" situations, and as an anti-abuse measure.
You will be able to work around this using a Personal Access Token in place of the provided token. As this needs to be explicitly provided it will remove any potential for possible abuse, so we recommend using this method when needing to create a pull request.

Ah what a pain. Resorting to a token that applies to every repository of the user without being able to scope specifically to the desired repository is quite the security concern.

(My complaints are to GitHub, not this repo BUT SOMEONE MUST HEAR ME AS I SHOUT POWERLESS INTO THE VOID!! ๐Ÿ˜…)

Hey all, check it out... another possible workaround is to use an on.schedule.cron trigger as discussed here:

pascalgn/automerge-action#37 (comment)

Here's my (sample/testing ๐Ÿ˜) configuration:

https://github.com/ExtendedXmlSerializer/NextRelease/blob/959614d9e72c08f80d7e71a0e52265a42ed91c75/.github/workflows/automerge.yml#L25-L30

Not as elegant as a direct trigger, but certainly better than having to resort to a Personal Access Token.

Thought I'd share. ๐Ÿ‘

There is a massive drawback to using this token, if a repository owner uses a personal token they will not be able to request changes nor approve a PR. This is due to the fact that the PR will be created by the owner.

Thanks to @proudust for bringing it to my attention, an alternative to using a PAT is SSH Deploy keys that can be set per repository. See the documentation here for how to use Deploy keys with create-pull-request action. Note that this method will only trigger push workflows, not pull_request, so checks must be in an on: push workflow.

Using deploy keys is now even easier because actions/checkout now supports checkout with SSH keys. See the updated documentation here.

Sorry if this has been explained - do I understand correctly that if the repository needs to have workflows triggered on pull_request and has a branch rule requiring that status checks pass, a PAT is the only option? Otherwise, the generated PR will be stuck in "Waiting for status to be reported" and won't be able to be merged?

@brockfanning There are actually a number of different workarounds now with various pros and cons. I've summarised them and updated the documentation here.

https://github.com/peter-evans/create-pull-request/blob/main/docs/concepts-guidelines.md#triggering-further-workflow-runs

Resorting to a token that applies to every repository of the user without being able to scope specifically to the desired repository is quite the security concern

Another approach is to create a GitHub App, install that app on your repo, and then generate a token using that App / installation, e.g. using tibdex/github-app-token.

There's an example of this here. In this example, a workflow in one repo is setting up branch protections in a separate repo, using Terraform (because the default GitHub token is scoped only to the repo where the running workflow lives) but you could also use this same approach to open a PR. This PR would then trigger other workflows in the repo.

@swinton Thank you for that great tip! I've tested it out and updated the documentation to explain how to set it up.

https://github.com/peter-evans/create-pull-request/blob/master/docs/concepts-guidelines.md#authenticating-with-github-app-generated-tokens

I know that for many users the wide scope of PATs is a security concern when wanting pull requests to trigger further workflow runs. A workaround for this is to use a PAT associated with a machine user. The machine user only has write access to a fork of the repository, not the main repository itself. This workaround was possible with v2, but it required a bit of awkward setup in the workflow. I've made it significantly simpler to configure in the newly released v3 version of this action. Just set push-to-fork to the repository fork owned by the machine user. See push pull request branches to a fork for details.

      - uses: actions/checkout@v2

      # Make changes to pull request here

      - uses: peter-evans/create-pull-request@v3
        with:
          token: ${{ secrets.MACHINE_USER_PAT }}
          push-to-fork: machine-user/fork-of-repository

Good news everyone! Looks like we have another option!

Another frequently-requested feature for Actions is a way to trigger one workflow based on the completion of another workflow. For example, you may want to take the results of a CI workflow and run some further analysis.

The new workflow_run event enables you to trigger a new workflow when one or more workflows are requested or completed. Runs triggered by the workflow_run event always use the default branch for the repository, and have access to a read/write token as well as secrets. As an example, as a maintainer you could set up a workflow that takes the artifacts generated by the pull request workflow, do some analysis, and post comments back to the pull request.  This event is also available as a web hook.

https://github.blog/2020-08-03-github-actions-improvements-for-fork-and-pull-request-workflows/

@abatilo Pull request status checks are added/updated via the push and pull_request events, so I don't think this new workflow_run event will help for triggering checks to run when using GITHUB_TOKEN to create a pull request.

There are some good updates for pull requests from forks, but that is a slightly different issue from the topic here.

On v3 is it needed to have both the GITHUB_TOKEN in the env as well as the token set in the with block?

@zlesnr You don't need to use env. For v3, please pass all inputs via with. However, if you are using the default GITHUB_TOKEN it's not necessary to pass the token input at all because that is the action default. You only need to set the token input if you are using a PAT.

@peter-evans i got a forked version working with a bot account that's successfully setting up PRs - is there a workaround to injecting an environment variable / secret into a workflow that was triggered? i realize the fork doesn't have access to the original accounts secret, but wondering if there's a way to get that working

@colbyfayock That's a slightly different topic from this issue. Please see this section of the readme. I don't know any way to get around the restrictions. In general, the way I've solved most of my problems with these restrictions is to use slash-commands to execute workflows.

This problem was infuriating to no end!! Your solution completely fixed it. Thanks!
It's just sad that it now posts under my account rather than the cool "bot" account. Sigh

Why is this issue still open though, seeing as it was solved? (I would prefer it is mentioned on the main page though, it stumped me for awhile why this wasn't working)

@cherryleafroad There is a full section in this action's documentation about this here, and a note in the main readme here.

I think this can be closed now, though. You are right about that. There are a number of workarounds that I've documented above and there is nothing further to do in terms of changes to this action.

Closing this issue but leaving it pinned for people to find easier.

Fine-grained personal access tokens are now in beta. You can now scope a PAT to one or more specific repositories. Use permissions contents: write and pull-requests: write.

https://github.blog/2022-10-18-introducing-fine-grained-personal-access-tokens-for-github/

Please give your support to this feature request to allow the permissions of the default GITHUB_TOKEN to be elevated so that it can trigger further workflow runs.

https://github.com/orgs/community/discussions/35047

@peter-evans For the PAT approach - It's now possible to create fine-grained PATs scoped to the desired repository. https://github.blog/changelog/2022-10-18-introducing-fine-grained-personal-access-tokens/

Thanks @anderssonjohan. I already commented about that here, but it's probably buried in the hidden comments because there are so many references to this issue. (It would be nice to be able to pin a comment so it didn't get hidden.)

Oh, I totally missed that comment! :) I read your docs you linked to in another comment and didn't find any mentions about fine-grained (scoped) PATs.

https://github.com/peter-evans/create-pull-request/blob/main/docs/concepts-guidelines.md#workarounds-to-trigger-further-workflow-runs

However, the PAT cannot be scoped to a specific repository so the token becomes a very sensitive secret.

Really good docs btw! ๐Ÿคฉ

I chose the workaround to create the pull requests as drafts and trigger the workflow on ready_for_review.

@swinton Thank you for that great tip! I've tested it out and updated the documentation to explain how to set it up.

https://github.com/peter-evans/create-pull-request/blob/master/docs/concepts-guidelines.md#authenticating-with-github-app-generated-tokens

I just set this up and it works like a charm! Opening pull requests with a GitHub App bot account now triggers on: [pull_request] workflows! Thank you!!!

I was able to trigger actions, using Fine-grained personal access token (BETA) , with those permissions:

Actions R/W
Contents R/W
Pull requests R/W
Workflows R/W

Didn't test if this is minimal set of permissions, probably can be limited even more:

Peter, thanks for writing up an explanation of this issue and the workarounds, even though it's not really your responsibility.

Fwiw, this is my situation. I maintain a website template where I try to automate as much as possible for the (often low-technical-knowledge) user. As such, I can't ask the user to create personal access tokens and things like that. So asking them to close/reopen by clicking a big red/green button is the best and most elegant workaround.

I'm also making use of the body field to help the user with this. I'd recommend anyone else using this working around to do the same.

uses: peter-evans/create-pull-request@v6
with:
  body: To run workflows on this PR, close (don't merge) and reopen it.

@vincerubinetti I can understand how that might be the best option for non-technical users. There's a similar approach that @bmacher commented here, that also might work for you.

I chose the workaround to create the pull requests as drafts and trigger the workflow on ready_for_review.