create-pull-request: PR creation failing due to fetch failing

Subject of the issue

My attempt to create a PR is failing with the error message. My use case is when the generated Swagger doc changes for my project, a PR is opened to merge the changes.

Create or update the pull request
  Attempting creation of pull request
  Error: fetch failed

This was working, but has recently stopped. The branch is created and pushed successfully. It’s just the PR step that is failing.

Steps to reproduce

jobs:
  documentation:
    name: Documentation
    runs-on: [self-hosted]
    permissions:
      contents: write
      pull-requests: write
    env:
      swaggerFile: ./swagger.json
    steps:
      - name: Checkout repo
        uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 18

      - name: Install project dependencies
        run: |
          npm ci

      - name: Update Swagger doc
        run: |
          npm run swagger-autogen

      - name: Check for changes
        id: changes
        run: |
          git diff --exit-code || echo "::set-output name=changed::true"

      - name: Create Pull Request
        id: cpr
        uses: peter-evans/create-pull-request@v6
        if: steps.changes.outputs.changed == 'true'
        with:
          base: main
          commit-message: 'Updated swagger doc'
          branch: docobot/githib_actions/swagger-doc
          committer: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
          author: ${{ github.actor }} <${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com>
          delete-branch: true
          title: 'Update Swagger Doc'
          body: |
            Update Swagger doc due to changes in ${{ github.sha }}
          labels: |
            documentation

About this issue

  • Original URL
  • State: closed
  • Created 5 months ago
  • Reactions: 3
  • Comments: 43 (19 by maintainers)

Most upvoted comments

Thank you for testing!

The fix is released as v6.0.5 / v6.

Octokit changed the behaviour of proxies as detailed in https://github.com/octokit/rest.js/issues/43. Switching to undici should work:

(src/octokit-client.ts)

import {ProxyAgent, fetch as undiciFetch} from 'undici'

const proxyFetch = (proxyUrl: string): typeof undiciFetch =>
  (url, opts) => {
    return undiciFetch(url, {
      ...opts,
      dispatcher: new ProxyAgent({
        uri: proxyUrl,
        keepAliveTimeout: 10,
        keepAliveMaxTimeout: 10,
      })
    })
  }

export const getOctokit = (options: OctokitOptions & {baseUrl: string}) => {
  const baseUrl = options.baseUrl
  const proxyUrl = getProxyForUrl(baseUrl)
  const OctokitWithPlugins = Core.plugin(paginateRest, restEndpointMethods)

  const allOptions: OctokitOptions = {
    ...options,
    baseUrl,
    request: proxyUrl ? {fetch: proxyFetch(proxyUrl)} : undefined
  }

  return new OctokitWithPlugins(allOptions)
}

I tried creating a proxy setup with mitmproxy using which I could test this out properly but failed at that

I’ve just tested my own self-hosted runner here: https://github.com/peter-evans/create-pull-request-tests-self-hosted

It works fine with v6. See run: https://github.com/peter-evans/create-pull-request-tests-self-hosted/actions/runs/8360055456

So this issue is not affecting all self-hosted setups, just some specific configurations it seems. Please share further details so we can narrow this down.

@peter-evans Can confirm the fix works for me too. Thanks for your efforts here. 👍

That’s pretty neat, thank you for your great effort here ❤️

@0xbe7a Please can you show me how you are reproducing the issue. I would like to correct my regression tests so that I can catch similar issues in future.

I have not attempted to reproduce this with a GitHub hosted runner. Our self-hosted runner only has access to our http_proxy and all other outgoing permissions are blocked.

Looking at the test-setup i am not sure if the iptables rules is sufficient here. First from what i understand is that iptables resolves the domain name once at rule-creation time. From the manpage:

Hostnames will be resolved once only, before the rule is submitted to the kernel. Please note that specifying any name to be resolved with a remote query such as DNS is a really bad idea.

As github.com and api.github.com already resolve to different IPs, this is most likely not going to catch all connections.

The proxy-fix version resolves the issue for our behind-a-proxy runner 🎉

@sdolender @JannikWibkerQC Thank you for pointing out this change in octokit. This is most likely the cause of the problem.

I’ve made a feature branch to test this. It seems to pass the tests I have for proxy support. https://github.com/peter-evans/create-pull-request/compare/main...proxy-fix

Please test this version of the action and let me know if it solves the issue:

uses: peter-evans/create-pull-request@proxy-fix

also noticed same issue on self-hosted runners ( behind proxy).

Maybe this case apply here: Yes, in v8 of @octokit/request we switched to the Fetch API instead of node-fetch.

All usages of NodeJS based http(s).Agent will not work as they are incompatible with the fetch API.

https://github.com/octokit/rest.js/issues/43

I also have this problem in one of my runner environments. I have bisected the fault back to https://github.com/peter-evans/create-pull-request/commit/21d8ea09d56b55e7381af60c0427786e5b3948df. My other working environment runs within a Kubernetes cluster, but interacts with the same GitHub Enterprise server. In the working environment it is not required to use a proxy and my GHES URL is included in noProxy, whereas in my malfunctioning environment a proxy must be used to reach GHES. http_proxy, https_proxy, HTTP_PROXY, HTTPS_PROXY, no_proxy and NO_PROXY are correctly set. Using the node16 based action works, while running the commit introducing the node20 runtime triggers the failure.

Edit 1: I have captured all outgoing network traffic and for the final “create pull request” api call the action appears to not be respecting my proxy configuration but instead attempts to directly connect to my GHES which is not possible in this environment. All other interactions with my GHES before the failing api request are done using my HTTP proxy.

Thanks @peter-evans for your efforts here. I’ll try to share what I can, but I think most people who use self-hosted runners are corporates so it’s hard to share material. Chicken meet egg.

@SatwaniGovind yes or rollback to v5

Perhaps it’s worth trying to get more information from the error in the console to continue to aid the debugging efforts.

Yes I think we need to try and narrow this down and make a minimal example that reproduces the problem. This must a rare edge case, because no other users have reported this (so far). This action is used a lot, so I would expect most issues to effect many users.

I’ll have a think about how we can narrow this down.

Not sure if this will fix it, but it’s worth a shot. Please try this version of the action.

uses: peter-evans/create-pull-request@bump-proxy-agent

@peter-evans I tried setting the https_proxy. Unless I’m doiong something wrong, the proxy isn’t the issue.

Run peter-evans/create-pull-request@v6
  with:
    base: main
    ...
 env:
    httpProxy: http://172.17.0.1:3128
    https_proxy: http://172.17.0.1:3128
    
Create or update the pull request
  Attempting creation of pull request
  Error: fetch failed
> Run echo $GITHUB_API_URL
https://api.github.com/

Correct. The repo URL is https://github.com/$ORG/$REPO, and the organisation is using self hosted runners.

I think it’s unlikely that the “infer-urls” feature caused the issue then. 🤔 Just to confirm, it would be great if you could execute this on your self-hosted runner and let me know what the output is.

- run: echo $GITHUB_API_URL