'unable to push git tags in gitlab ci pipeline

In my gitlab ci pipeline, I want to push a tag wherever pipeline run for the master branch. But the issue is that I am unable to push the tag on the repository.

I am trying to push the git tag using the GITLAB_TOKEN

image:
  name: X
  entrypoint: [""]


stages:
  - deploy
deploy:
  stage: deploy

  script:
    #  Generating new tag version using stk utility
    - git config --global user.email $USER_MAIL
    - git config --global user.name $USER_NAME
    - git config --global http.postBuffer 52428800
    - git remote set-url origin https://$USER_NAME:$GITLAB_TOKEN@${CI_PROJECT_URL:8}

    - export NEW_TAG_VERSION=<generating new git tag>
    - echo $NEW_TAG_VERSION

    - if [ $CI_COMMIT_REF_NAME == "master" ]; then \
    -       git tag -a v$NEW_TAG_VERSION -m "[skip ci] new tag"; \
    -       git tag --list; \
    -       git push origin --tags; \
    # I have also tried the command given below
    # -       git push origin HEAD:$CI_COMMIT_REF_NAME v$NEW_TAG_VERSION; \

    - else \
    -       echo "non-master"; \
    - fi

But the problem is that when i try to push the tag i get this error

error: RPC failed; result=22, HTTP code = 404
fatal: The remote end hung up unexpectedly
fatal: The remote end hung up unexpectedly


Solution 1:[1]

We had the same problem, but using after_script or SSH did not satisfy our requirements.

Here is our solution outline:

  • Use OAuth2 and Personal Access Token in origin to enable write access from CI job
  • Use ci.skip git option to skip retriggering pipeline after pushing a tag

Details:

image: alpine

stages:
  - build
  - test
  - package

make:
  stage: build
  script:
    - env
    - echo "complete" > complete.txt
  artifacts:
    paths:
      - complete.txt

  # All dependent jobs must include conditions of the parent job to
  # avoid pipeline entry with gitlab-ci.yml error upon code commit.
  #
  only:
    - schedules

test1:
  stage: test
  script:
    - echo "test1"
  needs:
    - job: make
      artifacts: true
  only:
    - schedules

# Other tests follow test1 structure

build_rpms:
  stage: package
  script:
    - echo "Build RPMs. Add tag v1.9d"
    - apk add git
    - git config --list

    # --force is needed for both tag and push to allow job replay
    - git tag v1.9d --force

    # Enable pushing from CI pipeline:
    #
    # At that point git origin points to CI_REPOSITORY_URL=
    # https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/acme/my-project.git
    # This setup does not allow modifications (i.e git push will be rejected).
    #
    # Setting SSH environment is what many developers do to execute git commands here,
    # but it is complex and requires submitting SSH private keys to Gitlab (cringe).
    #
    # Private Gitlab tokens are deprecated.
    #
    # We use Gitlab Personal Access Token with 'write' access. This token shall
    # be generated via Gitlab user settings and then it shall be added as a masked
    # environment variable for this project CI settings.
    #
    # Use "oauth2" as user. For example for CI_PROJECT_URL=https://gitlab.com/acme/my-project
    #   set origin to https://oauth2:[email protected]/acme/my-project.git
    #
    - git remote set-url origin ${CI_PROJECT_URL/gitlab.com/oauth2:${PERSONAL_ACCESS_TOKEN}@gitlab.com}.git
    - git remote -v

    # Don't trigger pipeline again:
    # -o ci.skip is not well known Gitlab Git option which allows skipping new CI.
    # Without ci.skip option CI would be triggered recursively by tag push.
    #
    - git push origin v1.9d --force -o ci.skip
  when:
    manual

Our objective was to push a tag as part of build-rpm job, which should be initiated manually as part of multi-stage CI pipeline.

The pipeline can be started on schedule or manually.

It must be possible to generate unique tag from git commit timestamp.

Update Jun 2020:

A new due date for a GitLab feature to address pushing tags in pipeline is 22-Jul-2020:

https://gitlab.com/gitlab-org/gitlab/-/issues/16290#note_357065731

Solution 2:[2]

the above issue was due to the repo url on which i was trying to push the git tag.

The issue was fixed by adding .git extension in the repo url, the example is given below:

git remote set-url origin https://$USER_NAME:$GITLAB_TOKEN@${CI_PROJECT_URL:8}.git

Solution 3:[3]

In my related work, we used slightly different approach.

create-git-tag:
  image: alpine/git
  stage: tagging
  script:
    - git config user.email "${GITLAB_USER_EMAIL}"
    - git config user.name "${GITLAB_USER_NAME}"
    - git remote add tag-origin https://oauth2:${GITLAB_ACCESS_TOKEN}@gitlab.com/${CI_PROJECT_PATH}
    - git tag -a "dev-1.0.1" -m "Dev Tag Created Automatically"
    - git push tag-origin "dev-1.0.1"
    - echo "Git Tag created successfully"
  rules:
    - if: '$CI_COMMIT_TAG == null'

Above job runs automatically as part of tagging stage. It won't run when a GIT Tag is raised, otherwise it will go in infinite loop as the job itself is creating the Git Tag. This is just an example to show the git tagging using the oauth url of GitLab.

GITLAB_ACCESS_TOKEN is variable defined in Settings -> CI/CD -> Variables and value is the GitLab Toke (Created separately from Profile -> Access Token) You can also use Project Access Token (better approach than using personal token. https://docs.gitlab.com/ee/user/project/settings/project_access_tokens.html#bot-users-for-projects

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Irtiza
Solution 3 Sanjay Bharwani