I am using gitlab-ci to automate testing of the project to a staging branch.

My requirement is to always reset the staging branch to master. That is, staging branch is identical to the master branch before merging any feature branch code to the staging.

So, assume: I have feature-one, feature-two, staging and master branches.

I have already merged feature-one to the staging branch and now I want to merge feature-two branch to the staging branch but I want to get rid of feature-one code or any other code that is in the staging branch but not in the master branch.

This way I always have my staging branch = master branch code + new feature branch code.

I have created a sample project to test this, my gitlab-ci.yml:

image: <some-image>

stages:
  - test
  - reset_staging # Reset staging branch
  - staging_one   # Deployment to a staging server
  - live          # Deployment to a live server

unit_test:
  stage: test
  script:
    - echo "unit test command"
  except:
    - master
    - staging-one

reset_staging:
  stage: reset_staging
  script:
    - git fetch origin master
    - git remote show origin
    - git checkout $CI_COMMIT_REF_NAME
    - git reset --hard origin/master
    - git remote set-url origin https://oauth2:[email protected]/proj-public/test-repo.git
    - git push origin $CI_COMMIT_REF_NAME --force
    - echo "reset staging complete"
  only:
    - staging-one

deploy_to_staging_one:
  stage: staging_one
  script:
    - echo "$CI_COMMIT_SHA"
    - echo "$CI_MERGE_REQUEST_SOURCE_BRANCH_SHA"
    - echo "$CI_MERGE_REQUEST_TARGET_BRANCH_SHA"
    - echo "$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME"
    - echo "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME"
    - git reset --hard $CI_COMMIT_SHA
  when: on_success
  only:
    - staging-one

deploy_to_live:
  stage: live
  script:
    - echo "live command one"
    - echo "live command two"
  when: on_success
  only:
    - master

I can get the staging-one branch to reset but the new code is not merged. What am I missing or is there any alternate solution for the above?

I use below Gitlab self-hosted:

  • GitLab 9.5.2
  • GitLab Shell 5.8.0
  • GitLab Workhorse v3.0.0
  • GitLab API v4
  • Git 2.13.5
  • Ruby 2.3.3p222
  • Rails 4.2.8
  • postgresql 9.6.3
1

There are 1 best solutions below

2
kris On

I'd assume $CI_COMMIT_SHA is the commit on feature-1 branch that you want to test. If you want to apply that single commit to the staging branch, you could change your deploy_to_staging_one step to:

- git checkout staging
- git cherry-pick $CI_COMMIT_SHA

This will apply the commit on the tip of feature-1 to the staging branch.

However, it sounds like you want to use all of the commits on feature-1, so you probably want:

- git checkout staging
- git rebase $CI_COMMIT_BRANCH

This applies all of the commits on feature-1 to staging.

But I also suspect your reset_staging step isn't doing what you want it to. git checkout $CI_COMMIT_REF_NAME puts you in a detached head state: you aren't "on a branch", you're balanced on the tip of feature-1. Then you run git reset --hard origin/master, which resets the detached head to the state of origin/master, which is a bit odd. (Kind of like creating a scratch workspace and then clearing it of all useful data.)

I think you want:

- git fetch origin master
- git checkout staging
- git reset --hard origin/master  # <-- now staging matches master