Deploy to server after merge to master branch

5,702

Solution 1

One could use conditional builds https://docs.travis-ci.com/user/conditional-builds-stages-jobs/

If code is merged into master one could decide to deploy code to production, but I personally prefer a human intervention by a Product Owner.

jobs:
  include:
      if: branch = master

or

stages:
  - name: deploy
    # require the branch name to be master
    if: branch = master

At other projects I preferred to deploy only tags to enforce the git flow (tags should be created otherwise no deployment to production).

stages:
  - name: deploy
    # require the tag name to match a regular expression
    if: tag =~ ^v1

One could also try (I did not try it yet) whether the if works in combination with script sections:

https://github.com/030/ansible-firefox/blob/master/.travis.yml

Last remark: I would avoid creating such scripts (the ones you included in the question) as most CI tools contain condition checks.

Solution 2

The updated deploy script in the question supports the following workflow (and requires this server setup):

  1. Create a feature branch and push commits to it
  2. Each push deploys the code to the staging server
  3. Review the code with merge request (feature branch --> master)
  4. After merging to master, create a new merge request (master --> production)

Due to Github merge request errata, I rebase when merging to master but normal merges when merging to production. The reason behind this is that Github creates new commits (different SHA1) when rebasing.

The rebase and merge behavior on GitHub deviates slightly from git rebase. Rebase and merge on GitHub will always update the committer information and create new commit SHAs, whereas git rebase outside of GitHub does not change the committer information when the rebase happens on top of an ancestor commit.

The main difference with this workflow to 030's answer is that a production branch is used instead of tags.

For bonus points use staging SSL certificates from Let's Encrypt on your staging server. To enable it while using a reverse proxy in Docker, set LETSENCRYPT_TEST=true

Share:
5,702

Related videos on Youtube

Moritz
Author by

Moritz

Let's digitize and visualize that!

Updated on September 18, 2022

Comments

  • Moritz
    Moritz over 1 year

    I currently have continuous deployment set up with a Travis CI job. All pushes are sent to the staging server and merges to the master to the production server. The problem is that the deployment to the production server is done before the merge is accepted. The continuous integration tests have to all pass, but the deployment occurs before manual code review is done.

    The question is, what is a lightweight method to ensure that a deployment to the production server only takes place after the merge request has been accepted?

    As a reference, the following code is used for deployment:

    #!/bin/bash
    
    # exit with nonzero exit code if anything fails
    set -e
    
    # Add the SSH login key
    chmod 600 veleda-deploy-key
    mv veleda-deploy-key ~/.ssh/id_rsa
    
    # Register the Veleda staging and production server SSH keys
    echo '|1|BqdQKtUnA/AtCT/p2M7wgMq3wlY=|lH39cRtAE64wd6EG3ry2J9ewXic= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBH3antqwy3D4NVVfHQX3SQc/g4wl/SAVC9w9QEry7hhQmB0SJIprwNAq8Hy2DzVCS7kTj/q7fCiiL7oAznrax+0=' >> $HOME/.ssh/known_hosts
    echo '|1|+Z7oOsZ+zdL6u8o8VSWp+bRzd2g=|XMw2HyJIHoekOYlJYw1n75plL2E= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCJ/fa/mr577/qCuRXqUNccfmhpUtmi46LSyE7nDbOgxv8kZFs7yQ/sh6TM5npR+ZIbe9I0qmdvA+cE1QfvN21E=' >> $HOME/.ssh/known_hosts
    
    # Select the remote to push to depending on the branch
    if [ $TRAVIS_BRANCH != 'production' ] ; then
        echo "Pushing to staging"
        export REMOTE=staging.veleda.io
    else
        echo "Pushing to production"
        export REMOTE=veleda.io
    fi
    
    # Push to the remote server
    git remote add deploy "deploy@$REMOTE:/home/deploy/repo/"
    git push -f deploy $TRAVIS_BRANCH
    
    # Unpack and update the Docker services
    ssh -t deploy@"$REMOTE" "\
        mkdir -p veleda &&
        git --work-tree=./veleda --git-dir=./repo checkout -f $TRAVIS_BRANCH &&
        cd veleda &&
        ./start.sh"
    
    • Admin
      Admin about 6 years
      IMHO the code review (and all other steps requiring human intervention) should be plugged into the pipeline somewhere before the commit to master stage to reduce head-of-the-line blocking for the rest of the team.
    • Admin
      Admin about 6 years
      Do you mean like feature branches? The review process happens during the pull request
    • Admin
      Admin about 6 years
      I don't favour feature branches myself, but yes, at pull request - which I suppose shouldn't proceed with the commit until the review is approved, right?
    • Admin
      Admin about 6 years
      Let me verify that again
    • Admin
      Admin about 6 years
      Moritz how about making your comment (on the answer) into a self-answer? For posterity?
  • Moritz
    Moritz about 6 years
    In my case I decided to add another long-lived branch, production, and only after creating a merge request to that branch is it deployed to the production server. This means that changes can be reviewed on the feature branches without pushing to production. This was the case when the master branch was equivalent to the version on the production server.
  • Ryan Crichton
    Ryan Crichton almost 6 years
    If you use this method you need to use add a type clause to the condition if you don't want random pull requests to master to cause a deploy. E.g. if: branch = master AND type = push