This page looks best with JavaScript enabled

It Runs Fine Locally, but GitHub Actions Keeps Failing

 ·  β˜• 4 min read

1. A Confusing Problem

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
name: Go

on: [push, pull_request]

jobs:
  build:
    name: CI
    runs-on: ubuntu-latest
    steps:
      - name: Set up Go 1.13
        uses: actions/setup-go@v1
        with:
          go-version: 1.13
      - name: Check out code into the Go module directory
        uses: actions/checkout@v2
      - name: Check pr is properly formatted
        run: diff -u <(echo -n) <(gofmt -d ./pkg ./cmd ./tools ./test)
      - name: Test & Build
        run: make all

The above is part of a project’s workflow, used mainly to check code style, run unit tests, and compile the code. It is triggered when a Pull Request is submitted.

But GitHub Actions kept failing, with the following message:

1
Error: vet: pkg/kapis/cluster/v1alpha1/handler_test.go:405:87: too few arguments in call to informers.NewInformerFactories

The key point is that running it locally produced no error at all. At first I suspected GitHub Actions simply wasn’t stable enough and might be flaky. So I pushed repeatedly, but the error persisted.

2. Debugging Online

I brought out the big gun: I logged in to Ngrok, got an Authtoken, and configured it in Secrets. Then I added the following snippet before the failing task:

1
2
3
4
5
6
- uses: shaowenchen/debugger-action@v2
  name: debugger
  timeout-minutes: 30
  continue-on-error: true
  with:
    ngrok_token: ${{ secrets.NGROK_TOKEN }}

In the Actions execution log, I found the SSH login link. I ran the command to log in to the Runner remotely and debug:

1
ssh root@@0.tcp.ngrok.io -p 17656

I entered the password root and could debug online. But it still reported the same error, so I had to find another way.

3. A Clue in the Logs

Based on the error, I guessed it was something like a code cache or sync issue. So I went through the full Actions log and finally spotted a clue.

1
2
3
Checking out the ref
/usr/bin/git log -1 --format='%H'
'0f878e746fe9ce55a6c4b793c66f501c14c456f5'

A SHA value in the log caught my attention, because I had run into a problem before in Jenkins where a Git record could not be found. A SHA represents a version record.

Then, locally I ran git checkout -f 0f878e746fe9ce55a6c4b793c66f501c14c456f5 and, surprisingly, it said that record could not be found. I expanded the collapsed Checking out the ref log:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
Checking out the ref
  /usr/bin/git checkout --progress --force refs/remotes/pull/3254/merge
  Note: switching to 'refs/remotes/pull/3254/merge'.

  You are in 'detached HEAD' state. You can look around, make experimental
  changes and commit them, and you can discard any commits you make in this
  state without impacting any branches by switching back to a branch.

  If you want to create a new branch to retain commits you create, you may
  do so (now or later) by using -c with the switch command. Example:

    git switch -c <new-branch-name>

  Or undo this operation with:

    git switch -

  Turn off this advice by setting config variable advice.detachedHead to false

  HEAD is now at 0f878e7 Merge 2ecc7398161e7a0211c59b52061c9e3800d28551 into 38eaa5cde0580ac4d29537065b687e090db557c6

Merge 2ecc7398161e7a0211c59b52061c9e3800d28551 into 38eaa5cde0580ac4d29537065b687e090db557c6 β€” so actions/checkout by default merges the Pull Request branch’s code onto the latest code, producing a new record.

The cause was found: the developer forked the mainline code and then developed a new feature. But during that process, the mainline branch had already merged other people’s code. When the already-merged code conflicts with the code in the Pull Request, this phenomenon occurs.

The way to solve it is: before submitting each Pull Request, pull the upstream code again, then rebase to resolve the conflict, and only then submit. There are two kinds of conflict here β€” one is a file conflict, and the other is a functional conflict.

4. Interpreting the action/checkout Parameters

Next, let us take a look at the other parameters and features of action/checkout.

  • fetch-depth defaults to 1, pulling only the current branch. When set to 0, it pulls the records of all branches and tags.
1
2
3
- uses: actions/checkout@v2
  with:
    fetch-depth: 0
  • Check out multiple repositories’ code into a specified directory
1
2
3
4
5
6
7
8
- name: Checkout
  uses: actions/checkout@v2

- name: Checkout tools repo
  uses: actions/checkout@v2
  with:
    repository: my-org/my-tools
    path: my-tools
  • Check out onto the record that submitted the Pull Request; by default it is the record after the merge
1
2
3
- uses: actions/checkout@v2
  with:
    ref: ${{ github.event.pull_request.head.sha }}

WeChat Official Account
WRITTEN BY
WeChat Official Account