actions / checkout

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

Preserve tag annotations #290

Open martinthomson opened 4 years ago

martinthomson commented 4 years ago

The technique this tool uses for checking out tags only preserves the relation between tag and ref, not any annotations created with git tag -a.

git fetch origin +$HASH:refs/tags/$TAG
git checkout -f refs/tag/$TAG

I have a CI action that depends on information from annotated tags. Specifically, the name of the person who applied the tag: git tag --list --points-at HEAD --format '%(taggeremail)' (I can't use ${{ github.actor }} for reasons).

The workaround is to run git fetch -f origin ${{ github.ref }}:${{ github.ref }}. But it would be better not to need this workaround.

morrone commented 4 years ago

Agreed! This breaks the "git describe" command too. We need tags to be in their correct original form.

martinthomson commented 4 years ago

I realize now that this is complicated by a desire to checkout the specific code identified by the hash when the tag has been re-applied on the repository. I would be happy to have an option that would cause the checkout to fail if the hash didn't match.

For example:

git fetch origin refs/tags/$TAG
[ `git rev-parse refs/tags/$TAG` != $HASH ] || fail
git checkout -f refs/tag/$TAG
ericsciple commented 4 years ago

@martinthomson does the input depth: 0 help? It will cause all history for all branches and tags to be fetched?

morrone commented 4 years ago

@martinthomson does the input depth: 0 help? It will cause all history for all branches and tags to be fetched?

I didn't try 0, but I tried "fetch-depth: 2000" at one point. It fetched the other tags in that history correctly, but if the thing that triggered the workflow was itself an annotated tag, that one tag will still be converted from an annotated tag into a lightweight tag.

ericsciple commented 4 years ago

fetch-depth: 0 triggers a different behavior. Curious if that solves the issue?

Stanzilla commented 4 years ago

It does not solve the issue, I ran into this today. Looks like the action is not using the tag itself, just the commit the tag points to.

andreineculau commented 4 years ago

fetch-depth: 0 does solve the issue. I don't see how it wouldn't because it fetch all branches, all tags

Stanzilla commented 4 years ago

@andreineculau sadly does not.

Envek commented 4 years ago

+1 on preserving tag annotations. fetch-depth: 0 alone doesn't help, git fetch --tags --force does help.

name: Create release from annotated tag
on: push
jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0 # Doesn't help
      - name: "Extract data from tag: version, message, body"
        id: tag
        run: |
          git fetch --tags --force # Retrieve annotated tags. THIS TRICK REALLY HELPS
          echo ::set-output name=subject::$(git for-each-ref $GITHUB_REF --format='%(contents:subject)')
          # …
      - name: Create Release
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: ${{ github.ref }}
          release_name: ${{ steps.tag.outputs.subject }}
martinthomson commented 4 years ago

That's the same workaround I originally suggested, just more broadly targets (all tags, not just one). As you say --depth 0 has no effect.

The main problem is that the code fetches using a hash and then re-applies its own tag if the build was initiated as a result of applying a tag. That's also why you need to add --force, because you need to overwrite that bad tag. Hence my suggestion to fetch the tag rather than applying it, along with a check that the tag still points to the fetched content.

bixu commented 4 years ago

Also seeing that fetch_depth: 0 doesn't work for all Actions that handle/search for tags in the repo history.

haizaar commented 3 years ago

I only needed to git describe --always to discover the latest tag since I'm release docker images myself, and indeed in GH Actions it was discovering one-before-the-current tags. In my case it was another to add --tags to git describe to make it consider non-annotated tags well. While it was an easy workaround I believe there is way too much details involved in getting this work properly.

chrislambe commented 3 years ago

This bit me as well. We use annotated tags in our build/release process and this was a little tough to track down. Another confirmation that fetch-depth: 0 does not address this. Adding git fetch --force --tags as an additional build step after checkout seems to be a valid workaround, at least for us.

ericcornelissen commented 3 years ago

Same here, exact same scenario as chrislambe described. I can also confirm that fetch-depth: 0 doesn't help, but adding git fetch --force --tags does.

Stanzilla commented 3 years ago

You can also just revert to checkout@v1 it does not really have any downsides

ericcornelissen commented 3 years ago

You can also just revert to checkout@v1 it does not really have any downsides

Thanks for the suggestion, I can confirm that works fine as well. Though, I would argue that it has the downside of probably receiving support for less amount of time.

On the other hand, I don't see any downsides to using git fetch --force --tags. Am i missing something? I guess the overhead can get a bit high for large projects?

martinthomson commented 3 years ago

The downside is that if the tag has moved then it will no longer be attached to the commit that you have checked out. For that, my personal preference is for the situation to be detected and the build aborted. It shouldn't happen very often.

Stanzilla commented 2 years ago

Any plans to fix this?

HexDecimal commented 2 years ago

I doubt there are any current plans. Everyone is already using workarounds. The simplest workaround being to pin actions/checkout@v1 on any job where the tags need to be correct.

In theory someone experienced in Actions and Git could come in a make pull requests. With tests so that any regressions in tag handing would be detected in the future.

Stanzilla commented 2 years ago

I mean yeah, I am stuck on v1 because of that, hence the question if they will ever address it or not.

bk2204 commented 2 years ago

Hey,

This just bit Git LFS today. It broke our release process by creating all of our release assets with the version number v3.1.0-3-g18b608c9 instead of v3.1.1, requiring extensive manual intervention to fix. Fortunately, we have a manual verification step that prevented this from being more serious.

We switched due to a claim in git-lfs/git-lfs#4789 that there was a security fix that required switching to v2. Is that the case, or can we revert that change and move back to v1 until this is fixed?

Tuxdude commented 2 years ago

Just ran into https://github.com/goreleaser/goreleaser/issues/2919 which was due to this issue and took me a sweet couple of hours to root cause. Had to workaround by doing https://github.com/Tuxdude/go-scratch-gh/commit/f31ca61a7ce73b3c84c91f00db70a15646d78855 It would be great if this behavior was fixed in the action, since there are a lot of use cases for reading the metadata from annotated tags.

Even if the bug is not fixed immediately, at least it might be worth documenting this behavior in the README for this action so that users have the right expectation around this action w.r.t. annotated tags (especially the tag at the tip).

bostjan commented 2 years ago

@Tuxdude - high five on spending a couple of hours to track this down. :/

Love the actions/checkout@v2 in general, but nobody expects their own tags to be rewritten behind their back. Especially when the tags are signed.

hikari-no-yume commented 4 months ago

I got bitten by this yesterday. The solution offered in https://github.com/actions/checkout/pull/1506 looks like a good compromise to me. I hope that'll be merged eventually.