anchor.diff:  - An obvious disadvantage here  is the duplication between the three jobs.
   - Another problem is the lack of extensibility of this approach. It is usual practice to run a set of "smoke" tests before running the full set of functional tests - so that any obvious issues in core functionality are found earlier rather than later. It is also possible that functional tests might need to be run in parallel. So, having a job for each OS's functional tests ends up being limiting. The only way to extend within the job would be to add more tasks which run one after the other.
   
  -To get around this, we can use GoCD's powerful [pipeline chaining mechanism]("https://docs.gocd.io/current/introduction/concepts_in_go.html#pipeline_dependency"), where a stage of a pipeline can be setup as a dependency for another pipeline. We can create one pipeline per operating system's functional test. Let's see how that looks:
  +To get around this, we can use GoCD's powerful [pipeline chaining mechanism](https://docs.gocd.io/current/introduction/concepts_in_go.html#pipeline_dependency), where a stage of a pipeline can be setup as a dependency for another pipeline. We can create one pipeline per operating system's functional test. Let's see how that looks:
   
   <%= image_tag 'blog/beginnings-real-pipeline/pipeline-06.jpg', :alt => 'Pipeline', :title => 'Pipeline' %>
   
  
positive.code: 
  Consider a small, cross-platform desktop application, with unit, integration and functional tests. Let's assume that the goal of the process is to create an installer which can be downloaded.
  
  A typical approach to automate this process would be to have a build script (using Rake, Make, Ant, etc. or even a batch file or a shell script) which has all the individual steps of the process automated so that they can be run locally (<%= link_to 'Principle 5', '/posts/2017-03-01-importance-and-principles-of-cd-pipelines.html#principle-run-locally' %>). Having this, you can now create a GoCD [*pipeline*]("https://docs.gocd.io/current/introduction/concepts_in_go.html#pipeline") with a single [*stage*]("https://docs.gocd.io/current/introduction/concepts_in_go.html#stage") which has a single [*job*]("https://docs.gocd.io/current/introduction/concepts_in_go.html#job") which has a single [*task*]("https://docs.gocd.io/current/introduction/concepts_in_go.html#task") which calls "make all" (for instance). It'll look like this:
  
  <%= image_tag 'blog/beginnings-real-pipeline/pipeline-01.jpg', :alt => 'Pipeline', :title => 'Simple Pipeline' %>
  
  
negative.code: 
  It is not atypical (though it is changing slowly) to deploy a build which has gone through all of these tests onto a set of deployment environments such as a UAT, pre-production and production environment. We'll look at how you can model these in your deployment pipelines in our next post.
  
  
  <div class='row'>
    <%= partial "partials/downloadbanner" %>
  </div>
  