Answers: <p>The updated deploy script in the question supports the following workflow (and requires this <a href="https://github.com/mayaculpa/veleda/blob/master/server_setup.md" rel="nofollow noreferrer">server setup</a>):</p>
  
  <ol>
  <li>Create a feature branch and push commits to it</li>
  <li>Each push deploys the code to the staging server</li>
  <li>Review the code with merge request (feature branch --> master)</li>
  <li>After merging to master, create a new merge request (master --> production)</li>
  </ol>
  
  <p>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 <a href="https://help.github.com/articles/about-pull-request-merges/" rel="nofollow noreferrer">creates new commits</a> (different SHA1) when rebasing.</p>
  
  <blockquote>
    <p>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.</p>
  </blockquote>
  
  <p>The main difference with this workflow to 030's answer is that a <em>production</em> branch is used instead of tags.</p>
  
  <p>For bonus points use <em>staging</em> <a href="https://letsencrypt.org/docs/staging-environment/" rel="nofollow noreferrer">SSL certificates</a> from Let's Encrypt on your staging server. To enable it while using a <a href="https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion" rel="nofollow noreferrer">reverse proxy</a> in Docker, set <code>LETSENCRYPT_TEST=true</code></p>
  
Answers: CC BY-SA 3.0
Answers: 2018-03-24T08:39:52.703Z
Answers: 2018-03-24T08:39:52.703Z
Answers: Moritz
Answers: <p>One could use conditional builds <a href="https://docs.travis-ci.com/user/conditional-builds-stages-jobs/" rel="nofollow noreferrer">https://docs.travis-ci.com/user/conditional-builds-stages-jobs/</a></p>
  
  <p>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.</p>
  
  <blockquote>
  <pre><code>jobs:
    include:
        if: branch = master
  </code></pre>
  </blockquote>
  
  <p>or</p>
  
  <blockquote>
  <pre><code>stages:
    - name: deploy
      # require the branch name to be master
      if: branch = master
  </code></pre>
  </blockquote>
  
  <p>At other projects I preferred to deploy only tags to enforce the git flow (tags should be created otherwise no deployment to production).</p>
  
  <blockquote>
  <pre><code>stages:
    - name: deploy
      # require the tag name to match a regular expression
      if: tag =~ ^v1
  </code></pre>
  </blockquote>
  
  <p>One could also try (I did not try it yet) whether the <code>if</code> works in combination with script sections:</p>
  
  <p><a href="https://github.com/030/ansible-firefox/blob/master/.travis.yml" rel="nofollow noreferrer">https://github.com/030/ansible-firefox/blob/master/.travis.yml</a></p>
  
  <p>Last remark: I would avoid creating such scripts (the ones you included in the question) as most CI tools contain condition checks.</p>
  
Answers: CC BY-SA 3.0
Answers: 2018-03-18T14:30:01.107Z
Answers: 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.
Answers: Moritz
Answers: CC BY-SA 4.0
Answers: 2018-07-17T11:58:32.183Z
Answers: 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`
Answers: Ryan Crichton
Answers: CC BY-SA 3.0
Answers: 2018-03-16T17:38:06.857Z
Answers: 2018-03-16T17:38:06.857Z
Answers: 030
Body: <p>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.</p>
  
  <p>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?</p>
  
  <p>As a reference, the following code is used for deployment:</p>
  
  <pre><code>#!/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=' &gt;&gt; $HOME/.ssh/known_hosts
  echo '|1|+Z7oOsZ+zdL6u8o8VSWp+bRzd2g=|XMw2HyJIHoekOYlJYw1n75plL2E= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCJ/fa/mr577/qCuRXqUNccfmhpUtmi46LSyE7nDbOgxv8kZFs7yQ/sh6TM5npR+ZIbe9I0qmdvA+cE1QfvN21E=' &gt;&gt; $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 &amp;&amp;
      git --work-tree=./veleda --git-dir=./repo checkout -f $TRAVIS_BRANCH &amp;&amp;
      cd veleda &amp;&amp;
      ./start.sh"
  </code></pre>
  
Comments: CC BY-SA 3.0
Comments: 2018-03-15T22:43:40.557Z
Comments: 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.
Comments: Dan Cornilescu
Comments: CC BY-SA 3.0
Comments: 2018-03-15T22:52:30.000Z
Comments: Do you mean like feature branches? The review process happens during the pull request
Comments: Moritz
Comments: CC BY-SA 3.0
Comments: 2018-03-15T22:57:40.127Z
Comments: 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?
Comments: Dan Cornilescu
Comments: CC BY-SA 3.0
Comments: 2018-03-15T23:05:06.393Z
Comments: Let me verify that again
Comments: Moritz
Comments: CC BY-SA 3.0
Comments: 2018-03-19T11:34:32.687Z
Comments: Moritz how about making your comment (on the answer) into a self-answer? For posterity?
Comments: Bookeater
Tags: <continuous-deployment><github><travis-ci>
Title: Deploy to server after merge to master branch
UserDisplayName: Moritz
ThreadText: # Deploy to server after merge to master branch
  
  (Asked by: username_0 on 2018-03-15)
  
  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"
  
  ```
  
  **Tags:** continuous-deployment, github, travis-ci
  
  > **Comments:**
  > **username_1**: 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.  
  > **username_0**: Do you mean like feature branches? The review process happens during the pull request  
  > **username_1**: 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?  
  > **username_0**: Let me verify that again  
  > **username_2**: username_0 how about making your comment (on the answer) into a self-answer? For posterity?  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_3 on 2018-03-16. Score: 4 | Accepted answer
  
  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.
  
  > **Comments:**
  > **username_0**: 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.  
  > **username_4**: 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`  
  
  ---
  
  ### Answer by username_0 on 2018-03-24. Score: 2
  
  The updated deploy script in the question supports the following workflow (and requires this [server setup](https://github.com/mayaculpa/veleda/blob/master/server_setup.md)):
  
  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](https://help.github.com/articles/about-pull-request-merges/) (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](https://letsencrypt.org/docs/staging-environment/) from Let's Encrypt on your staging server. To enable it while using a [reverse proxy](https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion) in Docker, set `LETSENCRYPT_TEST=true`
  
  
  ---
  
  