actions / checkout

Action for checking out a repo
https://github.com/features/actions
MIT License
5.75k stars 1.7k forks source link

Detached HEAD State #6

Closed peter-evans closed 4 years ago

peter-evans commented 5 years ago

When using this action it leaves the repository in a "detached HEAD" state. Is there a way to checkout the branch that initiated the workflow in an attached, usable state?

The checkout for Actions v1 using the HCL workflows worked differently and didn't leave the repository in a "detached HEAD" state.

TingluoHuang commented 5 years ago

in Actions v1, i think you only get a tar ball of your git repository, you can't run git operations on it. we checkout commit instead of branch since the branch might get more commits after the workflow get triggered.

vlymar commented 5 years ago

@TingluoHuang, actions v1 definitely checked out the repository to a branch, complete with all git metadata. LaunchDarkly's GH action was built around running git operations on the checked out repo. We are now implementing a workaround for this detached head issue (e.g. reading branch name from GITHUB_REF), but the new actions/checkout was a breaking change for us. I understand the concern about more commits coming after the workflow gets triggered, but it all seemed to work neatly in v1.

@peter-evans, an extremely hacky workaround that could be used short term to get the repo into a non-detached state would be to add this step after the actions/checkout step:

- name: Prepare repository
  run: git checkout "${GITHUB_REF:11}"

I'm not sure what happens if there have been more commits since the workflow was triggered, it depends on how actions/checkout works, but it may very well run against the latest commit instead of the one that triggered the workflow.

TingluoHuang commented 5 years ago

@vlymar can you share some context around how you use the checkout repo in actions v1? are you making a commit and push back to origin?

if we want to make actions v2 has the same behavior as actions v1, I guess we need to checkout the branch and reset HEAD to SHA. The downside i can think of is we will leave a local ref around after each run finished on the runner.

@chrispat to decide which direction to go. :)

vlymar commented 5 years ago

Our action scans the repository for feature flags and posts the results back to launchdarkly. It's triggered by push events so it runs on any branches under development. We want to be able to show information about feature flag usage per branch so we post the branch name the action is running for.

We were aware of GITHUB_REF for v1, but didn't build around it because our scanner is designed to run in multiple contexts: CLI, github actions, docker run, circleci, bitbucket pipelines, etc. We tried to make it as generic as possible, so we got the branch name by running git rev-parse HEAD. We're currently adding a special case for github actions to read the branch name from the GITHUB_REF.

peter-evans commented 5 years ago

To add some context from my use case. I wrote an experimental action that creates a pull request for any changes to the actions workspace. I realise it's not good practice in general to modify a repository during a workflow, but it opens up some interesting possibilities when used carefully.

I managed to work around the changes that were made between v1 and v2 Actions:

vlymar commented 5 years ago

Updated the origin remote URL to add token auth git remote set-url origin https://$TOKEN:x-oauth-basic@github.com/username/repository

This is actually relevant for us too, thanks for posting!

For context, we use ls-remote to prune stale branches from launchdarkly.

chingc commented 5 years ago

I'm also in the same boat and would love to be able to checkout without being put into a detached head state. I currently have to resort to sed, which isn't as terse as the bash substring extraction solution by @vlymar.

- name: Reattach HEAD
  run: git checkout "$(echo ${{ github.ref }} | sed -E 's|refs/[a-zA-Z]+/||')"

A true/false option would be nice and would preserve both behaviors.

TingluoHuang commented 5 years ago

I have a fix that almost ready, will finish testing and release to GitHub Actions.

elstudio commented 5 years ago

Meanwhile, here's an action that works around the current detached head state, using a sh one-liner to parse $GITHUB_REF and checking out the current branch:

https://github.com/elstudio/actions-js-build/tree/v2/commit

It also sets up git to commit with the appropriate username and email address.

chingc commented 5 years ago

Any updates?

timmehhh7 commented 5 years ago

We are having the same issue since moving to new Actions and using checkout. Our use case is some python scripts that get executed and generate files, then push them back into the repo on the same branch/PR. I tried using the fixes above and the GH event data isn't consistent so I can't reliably get the Branch name from it. ie sometimes "github.ref": "refs/pull/575/merge" as an example. Which doesn't work. In those cases head_ref is populated, however if the ref is like above, head_ref is empty.

Either way there is no reliable way to get a branch name it seems. Why can't we just have the checkout action clone the current branch?

peter-evans commented 5 years ago

Learnt a different way to set the git remote that allows the default GITHUB_TOKEN to be used to commit. Updated my comment here https://github.com/actions/checkout/issues/6#issuecomment-520776943

hashim-sohail commented 5 years ago

Is there a workaround?

Running semantic-release in GitHub Actions fails at @semantic-release/git which throws error HEAD:undefined

gr2m commented 4 years ago

@hashim-sohail I tried the workaround mentioned above using

- run: git checkout "${GITHUB_REF:11}"

But semantic-release still does not recognize that it's running on the master branch: https://github.com/gr2m/create-or-update-pull-request-action/runs/240930167#step:7:33. It might be a problem with semantic-release/git though, the checkout seems to have worked:

Switched to a new branch 'master'

https://github.com/gr2m/create-or-update-pull-request-action/runs/240930167#step:4:14

hashim-sohail commented 4 years ago

@hashim-sohail I tried the workaround mentioned above using

- run: git checkout "${GITHUB_REF:11}"

But semantic-release still does not recognize that it's running on the master branch: https://github.com/gr2m/create-or-update-pull-request-action/runs/240930167#step:7:33. It might be a problem with semantic-release/git though, the checkout seems to have worked:

Switched to a new branch 'master'

https://github.com/gr2m/create-or-update-pull-request-action/runs/240930167#step:4:14

Yes checkout is working fine, it was an issue with the conflicting version of @semantic-release/git. npx semantic-release@beta requires @semantic-release/git version 7.1.0-beta.x

miguelyoobic95 commented 4 years ago

Are there any news on this ? I am trying the workarounds above and I am observing the detached head behavior when running actions on PR. We run as service called chromatic which relies on the branch name to display which builds corresponds to which PR and HEAD is the current output everywhere.

stefanzweifel commented 4 years ago

@miguelyoobic95

I could solve the problem adding a branch-argument to my Action. On a PR, I can use ${{ github.head_ref }} in the Workflow and then git checkout $INPUT_BRANCH to switch to the branch I want.

Example: https://github.com/stefanzweifel/git-auto-commit-action/blob/12d8aff89d8347b9a102320849a3838746bc85f9/entrypoint.sh#L30-L37

miguelyoobic95 commented 4 years ago

Hey @stefanzweifel, thanks for the reply. I am new to this so not super familiar with the way you define actions. I currently only have a yaml file with the configuration for my workflow and no sh files attached to it. Is this something I should create ? Or can I just run a git checkout on ${{github.head_ref}} after the checkout step is done ?

gr2m commented 4 years ago

@hashim-sohail for semantic-release, it was a problem with the ci-env dependency, it has been resolved now, make sure it's updated to the latest version: https://github.com/pvdlg/env-ci/pull/101

chingc commented 4 years ago

Aug 26 I have a fix that almost ready, will finish testing and release to GitHub Actions.

@TingluoHuang What's the status on this?

TingluoHuang commented 4 years ago

@chingc my change get on hold until we change this action to a javascript action which might take some time.

JustinGrote commented 4 years ago

I was unable to use Gitversion until I backrevved to checkout v1, so this affected me too.

timmehhh7 commented 4 years ago

This is what we did for a workaround:

    steps:
    - uses: actions/checkout@master
    - name: reattach HEAD to Head Ref
      run: git checkout "$(echo ${{ github.head_ref }} | sed -E 's|refs/[a-zA-Z]+/||')"
      if: github.head_ref != ''
    - name: reattach HEAD to Ref
      run: git checkout "$(echo ${{ github.ref }} | sed -E 's|refs/[a-zA-Z]+/||')"
      if: github.head_ref == ''

This way we can put ourselves back to the right place after the initial clone action. We've been running this for about a month now with no issues.

jpvalery commented 4 years ago
- name: Prepare repository
  run: git checkout "${GITHUB_REF:11}"

did the trick for us and got https://github.com/narative/gatsby-theme-novela/issues/185 fixed

JustinGrote commented 4 years ago

@jpvalery Thanks, whats the :11 part for though?

jpvalery commented 4 years ago

@jpvalery Thanks, whats the :11 part for though?

No freaking clue - just used the suggestion in https://github.com/actions/checkout/issues/6#issuecomment-520636057 and it worked 😄

stefan-kolb commented 4 years ago

@JustinGrote @jpvalery Should be a substring syntax which means starting at position 11 of the string to the end. So refs/heads/feature-branch-1 gets feature-branch-1.

JustinGrote commented 4 years ago

@stefan-kolb oh, that makes sense. Is this documented anywhere? :)

peter-evans commented 4 years ago

@JustinGrote That syntax is bash substring extraction. See here for reference: https://www.tldp.org/LDP/abs/html/string-manipulation.html

JustinGrote commented 4 years ago

Oh I didn't notice it was only one pair of curly brackets, I thought it was a GitHub expression. That makes sense, thanks.

On Tue, Oct 22, 2019, 9:37 PM Peter Evans notifications@github.com wrote:

@JustinGrote https://github.com/JustinGrote That syntax is bash substring extraction. See here for reference: https://www.tldp.org/LDP/abs/html/string-manipulation.html

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/actions/checkout/issues/6?email_source=notifications&email_token=ADUNKUTSMWVSQGKFPKBCPV3QP7IKDA5CNFSM4IK7NRH2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOECAAWQA#issuecomment-545262400, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADUNKUQZL2SKBIZP4F6RHDTQP7IKDANCNFSM4IK7NRHQ .

ericsciple commented 4 years ago

actions/checkout@v2 will fix this, here is the PR

i'm expecting v2 to be available sometime early next week

ghost commented 4 years ago

Just wanted to feedback that v2-beta checks out the branch and works fine for me. Thanks!

stewartshea commented 4 years ago

Interesting, I've just tried v2-beta and still see this in my action output:

Note: switching to 'fc6bf2154859fc2f1b532f4b77ddd7f319749b93'.

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

anyone else?

ghost commented 4 years ago

Could you show a git status? I did not really try it, was just happy that coveralls seems to receive the correct branch name.

ericsciple commented 4 years ago

note, prs and tags will still be detached head (they arent branches)

mariusGundersen commented 3 years ago

The work around for this problem is to do the following:


    steps:
    - uses: actions/checkout@v2

    - run: git switch -c "pull-request"

This creates a new branch called pull-request which you can work on.

This assumes that you are not going to push! You can commit and tag and stuff, but you should not push, since the branch name is silly and there is no matching upstream

hkdobrev commented 3 years ago

What do you think of actually setting advice.detachedHead to false in this action? It seems pretty sensible to configure to not warn about it as it's expected.