Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Checkout@v2 detached HEAD #124

Closed
rachelluli-guetta opened this issue Dec 25, 2019 · 20 comments
Closed

Checkout@v2 detached HEAD #124

rachelluli-guetta opened this issue Dec 25, 2019 · 20 comments

Comments

@rachelluli-guetta
Copy link

Hi,
I have a workflow that runs on pull requests, what it does is:

  1. Checkout
  2. Create a commit based on the pull request label and push

Had to do some workarounds to make it work in checkout@v1 so now I switched to checkout@v2 but I still get:

[detached HEAD xxxxxx] ...
...
fatal: You are not currently on a branch.
To push the history leading to the current (detached HEAD)
state now, use

    git push origin HEAD:<name-of-remote-branch>
@ericsciple
Copy link
Contributor

The pull request refs aren't regular branches so detached head is intentional.

V2 fetches depth 1 by default. It sounds like the lack of history might be the issue? Setting fetch-depth: 0 might fix the issue?

@ericsciple
Copy link
Contributor

if so, related to PR #127 (added note about fetch depth to the summary)

@ericsciple
Copy link
Contributor

If you intend to push changes, you'll need to create a branch.

@ericsciple
Copy link
Contributor

Closing. Reopen if still hitting issues.

@tunetheweb
Copy link

@ericsciple I'm a little confused with this.

So we have a branch with a change on it. What I want to do is complete an action on that branch (let's say I've a repo with some markdown I want to auto generate HTML from when any changes are made to the markdown files).

Now this is very easy to do when completing this action on a push. However that means this Action happens each time the code is pushed to GitHub. This will then require the person working on that branch to pull the changes made by my GitHub /Action on that branch, before they can push another change. This could get tiresome if pushing a lot of commits periodically.

So I thought to only run this action when upon opening a pull request as by that time any changes should hopefully have settled down a bit. But then I ran it this detached head issue, which I'll admit I don't really understand (I'm far from a Git expert!).

So is it not possible to add directly to a branch that is part of a pull request and you must create another branch from that instead?

If that is the case, then what is the recommended workflow for this as would have thought it was a fairly common request.

  • Do we create a separate branch and merge it into this one to add the changes to this PR?
  • Do we create a separate branch and create a separate PR for this auto generated stuff so now have two PRs?
  • Do we only run this on master so it's only actioned after a pull request has been merged, but then we can't see the impact of the changes when reviewing the pull request?

Any advice appreciated as a bit new to this!

@ericsciple
Copy link
Contributor

@bazzadp sorry for the delay, i was out and just catching up on notifications

@ericsciple ericsciple reopened this Feb 10, 2020
@ericsciple
Copy link
Contributor

ericsciple commented Feb 10, 2020

@bazzadp i had a similar problem, but went a different direction.

I added a gendocs command to the package.json. The workflow runs npm run gendocs and then verifies no unstaged changes. Otherwise fails with a message telling user how to fix.

Automatically pushing commits is an alternate approach but tradeoffs I personally didn't want:

  • Requires a PAT
  • If forks are a scenario for you, then secrets not available during fork PR. So would need to run on master instead of PRs. Rules out separate branch/PR approach as well (for forks).
  • I also worry about automated generation accidentally causing a loop :)

@ericsciple
Copy link
Contributor

ericsciple commented Feb 10, 2020

The detached head issue is because checkout during a PR happens against the merge ref, not a branch. Branches are like refs/heads/some-branch. The merge ref is like refs/pull/8/merge. When git checks out anything that is not a branch, it does detached HEAD (effectively checks out the commit, branch not setup pointing to it)

You could checkout the branch instead. The branch is available from the github context (i assume, havent tried). This snippet can be used to dump the context:

on: push
jobs:
  one:
    runs-on: ubuntu-16.04
    steps:
      - name: Dump GitHub context
        env:
          GITHUB_CONTEXT: ${{ toJson(github) }}
        run: echo "$GITHUB_CONTEXT"

It would be similar to this scenario where the branch HEAD commit is checked out. Looking at the event payload docs it looks like it might be ${{ github.event.pull_request.head.ref }}

Again note, this wont work for forks. 1) because the ref from the fork repo wont exist and 2) because you would need to push to the fork repo

@ericsciple
Copy link
Contributor

@bazzadp hope that helps. Let me know if i can help further.

Folks on the community forum might have better suggestions

@tunetheweb
Copy link

Thanks for getting back to me.

Again note, this wont work for forks. 1) because the ref from the fork repo wont exist and 2) because you would need to push to the fork repo

Yeah this is where I really want it to work to be honest. We want to be able to accept typo pull requests from people not familiar with the site build process, and then not have the next person to build the site suddenly see changes they did not do included in their PR.

The Calibre Image optimisation app does this very well. When you open a PR with images, it optimised the images and updates the PR with the optimised images. See this comment as an example:

image

Looking at their source code it appears they use the GitHub API and create a new tree and then replace the PR with that tree, so doesn't look simple. But does work very well, so would be really useful to be able to do with this Checkout action. However if that's not possible, or overly complex so something you don't want to add, then I can understand this and feel free to close this issue.

@ericsciple
Copy link
Contributor

@bazzadp cool i didnt realize the built-in token has push permission.

It looks like Calibre is pushing to the user's branch. I would expect their solution to have the drawback you mentioned: "require the person working on that branch to pull the changes".

Additionally, the Calibre solution will not work for forks. The built-in token does not have permission to push to the fork repo where the user's branch is located.

Therefore I would suggest a workflow that runs only against master. Something like this:

on:
  push:
    branches:
      - master
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - run: |
          if [ ! -e gen.txt ]; then
            echo hello > gen.txt
            git config user.email "github-actions-bot@github.com"
            git config user.name "github-actions"
            git add gen.txt
            git commit -m "generated"
            git push
          fi

@tunetheweb
Copy link

It looks like Calibre is pushing to the user's branch. I would expect their solution to have the drawback you mentioned: "require the person working on that branch to pull the changes".

Yes it does. However, by only doing this when opening a pull request, the annoyance factor is much less than doing it on every push.

Additionally, the Calibre solution will not work for forks. The built-in token does not have permission to push to the fork repo where the user's branch is located.

It does work for forks!

In this case I think the action is initiated by the fork updating it's own repo, not the upstream repo trying to update the forked repo. Of course this only works once the action is cloned down to the fork, but with actions only requiring a simple file in the .github/workflows, and using the built in GITHUB_TOKEN that is set up automatically for you, this basically happens by default with no effort from the forker to setup (other than cloning after we add this action to upstream, or rebasing to pick it up if cloned before this was added).

And it also works for fine non-forked branches as well.

Therefore I would suggest a workflow that runs only against master.

Yup that's what I've ended up doing for now. It works, but it does make some people nervous that we are committing changes directly to master without reviewing them as part of a PR. If the generate script messes up then master could get in a bad way. Hence why I was looking for a better solution to add to PR instead.

@elyalvarado
Copy link

elyalvarado commented Feb 16, 2020

@bazzadp I got it working with @ericsciple suggestion (passing the ref to the actual PR branch head). This allowed me to do push after my action automatically generates the changes I needed:

    steps:
    - uses: actions/checkout@v2
      with:
        ref: ${{ github.event.pull_request.head.ref }}

Just letting this here for anybody that hits the same issue. However, please note that I didn't test this on forks, however if the action runs on the fork as @bazzadp mentions it might work.

danrivett added a commit to elevai-consulting/commitlint-github that referenced this issue Feb 23, 2020
…e commit messages because the PR branch was checked out as a detached head.

The error we received is below:

  error running commitlint
  fatal: ambiguous argument '46bb5821095a7e8e1ffd48f4697eec3c593c9b24^1..46bb582': unknown revision or path not in the working tree.

This was solved using a solution reported here: actions/checkout#124 (comment)
danrivett added a commit to elevai-consulting/commitlint-github that referenced this issue Feb 23, 2020
…ssages because the PR branch was checked out as a detached head.

The error we received is below:

  error running commitlint
  fatal: ambiguous argument '46bb5821095a7e8e1ffd48f4697eec3c593c9b24^1..46bb582': unknown revision or path not in the working tree.

This was solved using a solution reported here: actions/checkout#124 (comment)
@chingc
Copy link

chingc commented Mar 30, 2020

I just experienced this issue myself. Thank to the suggestions in this thread I was able to fix the issue. FYI, my workflow triggers on pull_request and on push, so here's what my config looks like in case someone does something similar.

steps:
- uses: actions/checkout@v2
  if: github.event_name == 'pull_request'
  with:
    fetch-depth: 0
    ref: ${{ github.event.pull_request.head.ref }}

- uses: actions/checkout@v2
  if: github.event_name == 'push'
  with:
    fetch-depth: 0

@tunetheweb
Copy link

tunetheweb commented May 5, 2020

Additionally, the Calibre solution will not work for forks. The built-in token does not have permission to push to the fork repo where the user's branch is located.

It does work for forks!

Upon further investigation it does not work for forks - it just fails silently so I presumed it was working when it wasn’t 😔

So you can do it on pull requests within the current repo (by passing the ref) but not for pull requests from forks.

Therefore it does look like the best option, to also support forks, is to just use Actions for checks, and then open another pull request for changes upon merge, instead of trying to add to the current pull request. That’s quite easy with this Action: https://github.com/peter-evans/create-pull-request and also has the benefit of allowing you to review any changes. The down side is the extra PR and need to be careful to avoid an infinite loop as that merging PR may kick off this whole workflow again!

hadley added a commit to rstudio/hex-stickers that referenced this issue Jul 30, 2020
yoheikikuta added a commit to yoheikikuta/sql-autoformat-action that referenced this issue Aug 2, 2020
lgatto added a commit to lgatto/GHA_knit_README that referenced this issue Dec 14, 2020
cghobson added a commit to BCDevOps/nrdk that referenced this issue Dec 17, 2020
Maybe actions/checkout#124 will change the behaviour?
cghobson added a commit to BCDevOps/nrdk that referenced this issue Dec 17, 2020
laurencejackson pushed a commit to GSTT-CSC/MLOps that referenced this issue Dec 15, 2021
as described here # required for GitPython checks actions/checkout#124
@jenstroeger
Copy link

I wanted to leave an alternative hint here, as a summary of #773 (comment): using

origin/${{ github.event.pull_request.base.ref }}

worked considering that branches aren‘t checked out locally (see @ericsciple’s comment above). It feels a little hacky, though, and the alternative would be to git checkout whichever branches I’d need in my Action.

@nvictor
Copy link

nvictor commented Feb 17, 2023

Hello team,

Where does this solution stand today? I have a workflow (below) that auto-formats Terraform configuration files. It pushes back to the PR branch.

Is there anything that I should be worried about? Is the fetch-depth: 0 needed?

Thanks

name:  Terraform format
on:
  pull_request:
    branches: [main]

jobs:
  terraform-fmt:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
        with:
          ref: ${{ github.event.pull_request.head.ref }}

      - name: Install Terraform
        uses: hashicorp/setup-terraform@v2

      - name: Format Terraform configuration files
        run: terraform fmt -recursive

      - name: Check for changes
        run: |
          if [[ -n $(git status --porcelain) ]]; then
            echo "Changes detected, committing and pushing..."
          else
            echo "No changes detected, skipping commit and push."
            exit 0
          fi

      - name: Commit formatted code
        run: |
          git config --local user.email "action@github.com"
          git config --local user.name "GitHub Action"
          git add .
          git commit -m "Format Terraform configuration files"
          git push

@julioNico
Copy link

I just experienced this issue myself. Thank to the suggestions in this thread I was able to fix the issue. FYI, my workflow triggers on pull_request and on push, so here's what my config looks like in case someone does something similar.

steps:
- uses: actions/checkout@v2
  if: github.event_name == 'pull_request'
  with:
    fetch-depth: 0
    ref: ${{ github.event.pull_request.head.ref }}

- uses: actions/checkout@v2
  if: github.event_name == 'push'
  with:
    fetch-depth: 0

Thank you, for this solution! Worked for me. And I used actions/checkout@v3

@c0nscience
Copy link

I just experienced this issue myself. Thank to the suggestions in this thread I was able to fix the issue. FYI, my workflow triggers on pull_request and on push, so here's what my config looks like in case someone does something similar.

steps:
- uses: actions/checkout@v2
  if: github.event_name == 'pull_request'
  with:
    fetch-depth: 0
    ref: ${{ github.event.pull_request.head.ref }}

- uses: actions/checkout@v2
  if: github.event_name == 'push'
  with:
    fetch-depth: 0

I just want to leave a comment here that this approach fixed my issue: I needed git branch --show-current to return something for a test. With this approach I get a value since it does not seem to be detached anymore. thank you very much.

@Aki0x137
Copy link

Aki0x137 commented Oct 5, 2024

Seems like the mentioned solution work on checkout@v4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants