Skip to content

Instantly share code, notes, and snippets.

@lukebigum
Created April 28, 2020 15:18
Show Gist options
  • Save lukebigum/cb020336d5c8081faebc1eb4144ee1d4 to your computer and use it in GitHub Desktop.
Save lukebigum/cb020336d5c8081faebc1eb4144ee1d4 to your computer and use it in GitHub Desktop.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title> PuppetContinuousIntegration &lt; Technology &lt; LMAX</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<link rel="icon" href="/pub/System/ProjectLogos/favicon.ico" type="image/x-icon" />
<link rel="shortcut icon" href="/pub/System/ProjectLogos/favicon.ico" type="image/x-icon" />
<meta name="TEXT_NUM_TOPICS" content="Number of topics:" />
<meta name="TEXT_MODIFY_SEARCH" content="Modify search" />
<meta name="robots" content="noindex" />
<link rel="alternate" type="application/rss+xml" title="RSS Feed" href="/Technology/WebRss" />
<!--[if IE]></base><![endif]-->
<style media="all">
@import url('/pub/System/SkinTemplates/base.css');
</style>
<style media="all">
@import url('/pub/System/PatternSkinTheme/layout.css');
@import url('/pub/System/PatternSkinTheme/style.css');
@import url('/pub/System/PatternSkinTheme/colors.css');
</style>
<style media="all">
@import url('/pub/System/PatternSkinTheme/column_left.css');
@import url('/pub/System/PatternSkinTheme/variant_foswiki_noframe.css');
</style>
<style media="all">
@import url('/pub/Main/SitePreferences/custom.css');
</style>
<style media="all">
/* Styles that are set using variables */
.patternBookView .foswikiTopRow,
.patternWebIndicator a img,
.patternWebIndicator a:hover img {
background-color: #6600CC;
}
#patternTopBarContents {
background-image: url(/pub/System/PatternSkin/header5.gif);
background-repeat: repeat-x;
}
#patternTopBarContents {
background-color: #ffffff;
}
.patternBookView {
border-color: #6600CC;
}
.patternPreviewPage #patternMain {
/* uncomment to set the preview image */
/*background-image:url("/pub/System/PreviewBackground/preview2bg.gif");*/
}
</style>
<style media="all">
@import url("/pub/System/PatternSkin/print.css");
</style>
<!--[if IE]><style media="screen">
pre {
height:1%;
overflow-x:auto;
}
.foswikiAttachments,
.foswikiForm,
.foswikiHelp,
.foswikiPreviewArea,
.patternPreviewPage .foswikiForm,
.patternSigLine,
.patternToolBar,
.patternTop,
.patternTopicAction,
#patternSideBarContents .patternLeftBarPersonal,
#patternSideBarContents h2,
#patternSideBarContents li,
#patternTopBarButtons ul {
height:1%;
}
#patternSideBarContents .patternLeftBarPersonal {
width:100%;
}
.foswikiFormStep {
height:100%;
}
#foswikiLogin,
.patternShadow {
border:10px solid #fff;
margin-top:10px;
margin-bottom:10px;
border:2px solid #ccc;
}
</style><![endif]-->
<!--[if gt IE 8 ]><style media="screen">
#foswikiLogin,
.patternShadow {
border:10px solid #fff;
margin-top:10px;
margin-bottom:10px;
box-shadow: 0 0 10px #ccc;
}
</style><![endif]-->
<style media="all">
.externalLink a:link,
.externalLink a:visited,
.externalLink a:hover {
background-image: url(/pub/System/ExternalLinkPlugin/external.gif);
background-repeat: no-repeat;
background-position: right;
padding-right: 18px;
}
</style>
<link rel="stylesheet" href="/pub/System/JQueryPlugin/themes/foswiki/jquery-ui.css" media="all" />
<style media="all">
.foswikiTable {
border-width: 1px
}
.foswikiTable .tableSortIcon img {
padding-left: .3em;
vertical-align: text-bottom
}
.foswikiTable td {
border-style: solid none;
vertical-align: top
}
.foswikiTable th {
border-style: none solid;
vertical-align: top;
background-color: #d6d3cf;
color: #000000
}
.foswikiTable th a:link {
color: #000000
}
.foswikiTable th a:visited {
color: #000000
}
.foswikiTable th a:hover {
color: #000000;
background-color: #d6d3cf
}
.foswikiTable th.foswikiSortedCol {
background-color: #c4c1ba
}
.foswikiTable tr.foswikiTableRowdataBg0 td {
background-color: #ffffff
}
.foswikiTable tr.foswikiTableRowdataBg0 td.foswikiSortedCol {
background-color: #f7f7f6
}
.foswikiTable tr.foswikiTableRowdataBg1 td {
background-color: #f7f7f6
}
.foswikiTable tr.foswikiTableRowdataBg1 td.foswikiSortedCol {
background-color: #f0f0ee
}
</style>
</head>
<body class="foswikiNoJs patternViewPage patternPrintPage">
<a name="PageTop"></a>
<div class="foswikiPage">
<div id="patternScreen">
<div id="patternPageShadow">
<div id="patternPage">
<div id="patternOuter">
<div id="patternFloatWrap">
<div id="patternMain">
<div id="patternMainContents">
<div class="patternContent">
<div class="foswikiTopic">
<h1><a name="PuppetContinuousIntegration"></a> PuppetContinuousIntegration </h1>
<p></p>
<a name="foswikiTOC"></a>
<div class="foswikiToc">
<ul>
<li> <a href="?cover=print#Tech_Stack"> Tech Stack </a>
</li>
<li> <a href="?cover=print#What_is_this_all_about"> What is this all about </a>
</li>
<li> <a href="?cover=print#Rbenv"> Rbenv </a>
<ul>
<li> <a href="?cover=print#How_It_Works"> How It Works </a>
</li>
<li> <a href="?cover=print#Installation_of_rbenv"> Installation of rbenv </a>
</li>
<li> <a href="?cover=print#rbenv_Usage"> rbenv Usage </a>
</li>
</ul>
</li>
<li> <a href="?cover=print#pdksync"> pdksync </a>
</li>
<li> <a href="?cover=print#Try_the_tests"> Try the tests </a>
</li>
<li> <a href="?cover=print#Dependencies"> Dependencies </a>
</li>
<li> <a href="?cover=print#Speeding_up_Merge_Requests"> Speeding up Merge Requests </a>
</li>
<li> <a href="?cover=print#Deploying_a_puppet_module_to_production"> Deploying a puppet module to production </a>
</li>
</ul>
</div>
<p class='p'>The following page is designed to be a "getting started" page for someone who's never done any Puppet testing before.</p>
<h2><a name="Tech_Stack"></a> Tech Stack </h2>
<p class='p'>There's a lot of moving parts involved. Good news is almost all of them are bundled into PDK now. You can manage things individually though, if you like, but for the most part you don't need to. There are two places you will need RBEnv though: pdksync and Hiera GPG.</p>
<p class='p'>An overview of what does what:</p>
<table class="foswikiTable" rules="none" border="1">
<tbody>
<tr class="foswikiTableOdd foswikiTableRowdataBgSorted0 foswikiTableRowdataBg0">
<td class="foswikiTableCol0 foswikiFirstCol"> Component </td>
<td class="foswikiTableCol1 foswikiLastCol"> Description </td>
</tr>
<tr class="foswikiTableEven foswikiTableRowdataBgSorted1 foswikiTableRowdataBg1">
<td class="foswikiTableCol0 foswikiFirstCol"> PDK </td>
<td class="foswikiTableCol1 foswikiLastCol"> Puppet Development Kit. The community standard way to test and develop Puppet modules. Bundles all of the below components into one package. </td>
</tr>
<tr class="foswikiTableOdd foswikiTableRowdataBgSorted0 foswikiTableRowdataBg0">
<td class="foswikiTableCol0 foswikiFirstCol"> pdksync </td>
<td class="foswikiTableCol1 foswikiLastCol"> A tool to do mass runs of PDK across multiple modules. </td>
</tr>
<tr class="foswikiTableEven foswikiTableRowdataBgSorted1 foswikiTableRowdataBg1">
<td class="foswikiTableCol0 foswikiFirstCol"> Rbenv </td>
<td class="foswikiTableCol1 foswikiLastCol"> Handles compiling and swapping between different versions of Ruby in hour home directory, without polluting the system Ruby or RPMs, similar to <a class="foswikiNewLink" href="/edit/Technology/PyEnv?topicparent=Technology.PuppetContinuousIntegration" rel="nofollow" title="Create this topic">PyEnv</a>. </td>
</tr>
<tr class="foswikiTableOdd foswikiTableRowdataBgSorted0 foswikiTableRowdataBg0">
<td class="foswikiTableCol0 foswikiFirstCol"> Bundler </td>
<td class="foswikiTableCol1 foswikiLastCol"> A Ruby Gem dependency management system, can run Ruby programs with specific versions of Gems. </td>
</tr>
<tr class="foswikiTableEven foswikiTableRowdataBgSorted1 foswikiTableRowdataBg1">
<td class="foswikiTableCol0 foswikiFirstCol"> Rake </td>
<td class="foswikiTableCol1 foswikiLastCol"> The Ruby equivalent of what Make is to C/C++. Several Gems provide Rake tasks related to Puppet unit testing. </td>
</tr>
<tr class="foswikiTableOdd foswikiTableRowdataBgSorted0 foswikiTableRowdataBg0">
<td class="foswikiTableCol0 foswikiFirstCol"> rspec </td>
<td class="foswikiTableCol1 foswikiLastCol"> A testing framework for the Ruby language. </td>
</tr>
<tr class="foswikiTableEven foswikiTableRowdataBgSorted1 foswikiTableRowdataBg1">
<td class="foswikiTableCol0 foswikiFirstCol foswikiLast"> rspec-puppet </td>
<td class="foswikiTableCol1 foswikiLastCol foswikiLast"> Builds on top of rspec to provide a testing framework for Puppet manifests. </td>
</tr>
</tbody>
</table>
<p></p>
<h2><a name="What_is_this_all_about"></a> What is this all about </h2>
<p class='p'>Continuous Integration (CI) is a development practice that requires developers to integrate code into a shared repository several times a day. Each check-in is then verified by an automated build, allowing teams to detect problems early.</p>
<p class='p'>The steps we are going to work through here are:</p>
<ul>
<li> Create a puppet module and git push it to <span class='externalLink'><a href="https://git" target="_top">https://git</a></span>.
</li>
<li> Add module to continuous integration server <a href="https://git/" target="_top">https://git/</a>
</li>
<li> Add a <strong>*.fixtures.yml*</strong> to enable our test tool to find all the required module dependencies
</li>
</ul>
<p class='p'>Create an empty Puppet module, but uuse PDK to create it:</p>
<pre>
cd ~/git/
pdk new module
</pre>
<p class='p'>You'll be asked a series of questions. Almost always you want these responses:</p>
<ul>
<li> Forge username == lmax
</li>
<li> Author == YOUR NAME
</li>
<li> License == Apache-2.0
</li>
<li> Operating systems == Redhat based Linux (only, so turn off Debian and Windows)
</li>
</ul>
<p></p>
Create a repo in <a class="foswikiNewLink" href="/edit/Technology/GitLab?topicparent=Technology.PuppetContinuousIntegration" rel="nofollow" title="Create this topic">GitLab</a> called the same as the you picked for your module in the <strong>techops-puppet</strong> namespace.
<p></p>
<ul>
<li> <span class='externalLink'><a href="https://git/projects/new" target="_top">https://git/projects/new</a></span>
</li>
</ul>
<p class='p'>You might want to rename the directory just created to include the author name, lmax, so "lmax-woof" in this example. Initialise the module directory as a Git repo, and push it to said Git Lab repo:</p>
<pre>
mv woof lmax-woof
cd lmax-woof
git init .
git remote add origin https://git/techops-puppet/lmax-woof.git
git add .
git commit -a -m &#34;initial commit&#34;
git push -u origin master
</pre>
<p></p>
<h2><a name="Rbenv"></a> Rbenv </h2>
<p class='p'>While PDK comes with it's own Ruby and most dependencies, other Ruby projects do not. We use pdksync to keep all our module repositories configured the same. For this you will need RBenv installed.</p>
<h1><a name="Rbenv_AN1"></a> Rbenv </h1>
<p></p>
<p class='p'></p>
<p class='p'></p>
<ul>
<li> <span class='externalLink'><span class='externalLink'><a href="http://rbenv.org/" target="_top">http://rbenv.org/</a></span></span>
</li>
</ul>
<p></p>
Since Puppet bundles it's own version of Ruby we need to be able to make sure our code works with this version. <span class='externalLink'><span class='externalLink'><a href="http://rbenv.org/" target="_top">rbenv</a></span></span> is a tool which allows you to easily switch between different versions of ruby and installs into your home directory so that you don't pollute the system packages managed by deb/rpm.
<p class='p'></p>
<p class='p'></p>
<h3><a name="How_It_Works"></a> How It Works </h3>
<p class='p'>At a high level, rbenv intercepts Ruby commands using shim executables injected into your PATH, determines which Ruby version has been specified by your application, and passes your commands along to the correct Ruby installation.</p>
<h3><a name="Installation_of_rbenv"></a> Installation of rbenv </h3>
<p></p>
Clone the latest version of <span class='externalLink'><span class='externalLink'><a href="http://rbenv.org/" target="_top">rbenv</a></span></span> into your home directory:
<p></p>
<pre>
git clone https://github.com/sstephenson/rbenv.git $HOME/.rbenv
git clone https://github.com/sstephenson/ruby-build.git \
$HOME/.rbenv/plugins/ruby-build
</pre>
<p></p>
Configure your bash environment so that it knows about <span class='externalLink'><span class='externalLink'><a href="http://rbenv.org/" target="_top">rbenv</a></span></span>. If you use another shell then check out the docs on the rbenv site.
<p></p>
<pre class='syntaxHighlightingPlugin'><I><FONT COLOR="#B22222">########################
</FONT></I><I><FONT COLOR="#B22222"># Ruby configuration
</FONT></I><I><FONT COLOR="#B22222">########################
</FONT></I><I><FONT COLOR="#B22222"># rbenv
</FONT></I><I><FONT COLOR="#B22222"># https://github.com/sstephenson/rbenv
</FONT></I>
<I><FONT COLOR="#B22222">## Install rbenv
</FONT></I><B><FONT COLOR="#A020F0">if</FONT></B> [ ! -d <B><FONT COLOR="#BC8F8F">&quot;$HOME/.rbenv&quot;</FONT></B> ]
<B><FONT COLOR="#A020F0">then</FONT></B>
git clone https://github.com/sstephenson/rbenv.git $<FONT COLOR="#B8860B">HOME</FONT>/.rbenv
<B><FONT COLOR="#A020F0">fi</FONT></B>
<B><FONT COLOR="#A020F0">if</FONT></B> [ -d <B><FONT COLOR="#BC8F8F">&quot;$HOME/.rbenv&quot;</FONT></B> ] &amp;&amp; [ ! -d <B><FONT COLOR="#BC8F8F">&quot;$HOME/.rbenv/plugins/ruby-build&quot;</FONT></B> ]
<B><FONT COLOR="#A020F0">then</FONT></B>
git clone https://github.com/sstephenson/ruby-build.git \
$<FONT COLOR="#B8860B">HOME</FONT>/.rbenv/plugins/ruby-build
<B><FONT COLOR="#A020F0">fi</FONT></B>
<I><FONT COLOR="#B22222">## initialize rbenv
</FONT></I><B><FONT COLOR="#A020F0">if</FONT></B> [ -d $<FONT COLOR="#B8860B">HOME</FONT>/.rbenv ]
<B><FONT COLOR="#A020F0">then</FONT></B>
<B><FONT COLOR="#DA70D6">export</FONT></B> RBENV_ROOT=<B><FONT COLOR="#BC8F8F">&quot;$HOME/.rbenv&quot;</FONT></B>
<B><FONT COLOR="#DA70D6">export</FONT></B> <FONT COLOR="#B8860B">PATH</FONT>=<B><FONT COLOR="#BC8F8F">&quot;$RBENV_ROOT/bin:$PATH&quot;</FONT></B>
<B><FONT COLOR="#A020F0">if</FONT></B> <B><FONT COLOR="#DA70D6">type</FONT></B> <B><FONT COLOR="#BC8F8F">&quot;rbenv&quot;</FONT></B> &amp;&gt; /dev/null; <B><FONT COLOR="#A020F0">then</FONT></B>
<B><FONT COLOR="#DA70D6">eval</FONT></B> <B><FONT COLOR="#BC8F8F">&quot;$(rbenv init -)&quot;</FONT></B>
<I><FONT COLOR="#B22222"># Add the version to my prompt
</FONT></I> __rbversion (){
<B><FONT COLOR="#A020F0">if</FONT></B> <B><FONT COLOR="#DA70D6">type</FONT></B> <B><FONT COLOR="#BC8F8F">&quot;ruby&quot;</FONT></B> &amp;&gt; /dev/null; <B><FONT COLOR="#A020F0">then</FONT></B>
rbenv_ruby_version=$(rbenv version | sed -e 's/ .*//')
printf $rbenv_ruby_version
<B><FONT COLOR="#A020F0">fi</FONT></B>
}
<B><FONT COLOR="#DA70D6">export</FONT></B> <FONT COLOR="#B8860B">PS1</FONT>=<B><FONT COLOR="#BC8F8F">&quot;rb:\$(__rbversion)|$PS1&quot;</FONT></B>
<B><FONT COLOR="#A020F0">fi</FONT></B>
<B><FONT COLOR="#A020F0">fi</FONT></B></pre>
<p class='p'>Make sure you source you `.bashrc` file to initialise rbenv:</p>
<pre>
source ~/.bashrc
</pre>
<p class='p'>Install the required packages for compiling rubies:</p>
<pre>
dnf install binutils gcc gcc-c++ make openssl-devel readline-devel \
zlib-devel libffi-devel libyaml-devel ncurses-devel gdbm-devel \
patch libxslt-devel libxml2-devel
</pre>
<p></p>
When installing rubygems, the default is to install all the documentation as well. This makes installing gems take a lot longer. For your own sanity create a file named <code><b>~/.gemrc</b></code> with the following content.
<pre>
install: --no-ri --no-rdoc
update: --no-ri --no-rdoc
</pre>
<p></p>
<h3><a name="rbenv_Usage"></a> rbenv Usage </h3>
<p></p>
Before you install rbenv you should remove any <code><b>~/.gem*</b></code> folder from your home directory because things in there can conflict with <strong>rbenv</strong>
<p class='p'>Now we can install some Rubies. Our puppet server is using 2.5.7:</p>
<pre>
rbenv install 2.5.7
</pre>
<p></p>
You can see what versions of ruby are installed:
<pre>
rbenv versions
</pre>
<p></p>
Which version of ruby are you currently using:
<pre>
ruby --version
</pre>
<p></p>
There are several ways of setting the version of ruby. To set for a directory (`.ruby-version`):
<pre>
rbenv local 2.5.7
</pre>
<p></p>
To set for your shell just for this session:
<pre>
rbenv shell 2.5.7
</pre>
<p></p>
To set for your user account:
<pre>
rbenv global 2.5.7
</pre>
<p></p>
Set it using an environment variable:
<pre>
export RBENV&#95;VERSION&#61;2.5.7
</pre>
<p class='p'></p>
-- <a href="/Main/LukeBigum">LukeBigum</a> - 02 Nov 2019
<p></p>
<h2><a name="pdksync"></a> pdksync </h2>
<p></p>
<img src="/pub/System/DocumentGraphics/tip.png" alt="IDEA!" title="IDEA!" width="16" height="16" /> Now would be a good time to create a <a class="foswikiNewLink" href="/edit/Technology/GitLab?topicparent=Technology.PuppetContinuousIntegration" rel="nofollow" title="Create this topic">GitLab</a> API token for yourself, save it in <em>~/.gitlab.token</em>.
<p class='p'>pdksync is used to synchronize common files between module repositories.</p>
<ul>
<li> <a href="https://github.com/puppetlabs/pdksync" target="_top">https://github.com/puppetlabs/pdksync</a> website
</li>
</ul>
<p></p>
We have our own customised configuration for pdksync available at: <a href="https://git/techops-puppet/pdksync" target="_top">https://git/techops-puppet/pdksync</a>
<p class='p'>Clone the above repository:</p>
<pre>
cd ~/git/
git clone https://git/techops-puppet/pdksync.git
cd pdksync
</pre>
<p></p>
The PDK defaults are good, but they need some slight tweaks to work with our environment (eg: the name of our <a class="foswikiNewLink" href="/edit/Technology/GitLab?topicparent=Technology.PuppetContinuousIntegration" rel="nofollow" title="Create this topic">GitLab</a> server, and our test pipelines). For most purposes all you will need to do is add the module name to <strong>managed_modules.yml</strong>:
<p></p>
<pre>
echo &#39;- lmax-woof&#39; &#62;&#62; managed&#95;modules.yml
git commit -a -m &#34;adding lmax-woof&#34;
git push
</pre>
<p></p>
We could use pdksync right now, but it would act on everything in <em>managed_modules.yml</em>. Since we don't want to sync everything, temporarily edit the managed_modules.yml file to just contain the module you want:
<p></p>
<pre>
echo &#39;- lmax-woof&#39; &#62; managed&#95;modules.yml
</pre>
<p class='p'>We'll undo this later.</p>
There's one very special file that needs to get into our new Puppet module: <em>.sync.yml</em>. This file changes the PDK templates slightly to fit our environment. You need to commit it to Git manually, pdksync does not put it there unfortunately. However you can do it using pdksync itself. The following pdksync commands clone down all managed modules (of which at the moment there's only one), copies in _.sync.yml, commits it, and creates a Merge Request in Git Lab:
<p></p>
<pre>
bundle install
bundle exec rake git:clone&#95;managed&#95;modules
bundle exec rake pdksync:run&#95;a&#95;command&#91;&#39;cp ../../module&#95;sync.yml ./.sync.yml&#39;]
bundle exec rake git:create&#95;commit&#91;&#39;pdksync&#39;,&#39;pdksync&#39;]
bundle exec rake git:create&#95;pr&#91;&#39;pdksync&#39;,]
</pre>
<p class='p'>That's going to look like overkill - you could have just committed that file by hand and pushed it, right? Correct, however learning how to do it with pdksync will help you if you need do to the same thing again across our other 100 modules.</p>
Go into Git Lab for that module, you should see a Merge Request waiting: <a href="https://git/techops-puppet/lmax-woof/merge_requests/" target="_top">https://git/techops-puppet/lmax-woof/merge_requests/</a>
<p></p>
You can review the changes in this interface, and check the test pipeline - the tests should pass. When you're happy, merge this MR into the master branch. While we're here, we should also prevent pushes to the master branch, forcing the use of Merge Requests (and thus forcing tests to pass before merging). Go to <a href="https://git/techops-puppet/lmax-woof/settings/repository" target="_top">https://git/techops-puppet/lmax-woof/settings/repository</a> and expand out "Protected Branches". There should already be an entry for the "master" branch. Change it so "Allowed to push" is set to "No one" (that's it, there's no save button).
<p></p>
We're done inside pdksync, so undo our local edit of <em>managed_modules.yml</em>:
<p></p>
<pre>
git checkout managed&#95;modules.yml
</pre>
<p></p>
<h2><a name="Try_the_tests"></a> Try the tests </h2>
<p class='p'>The pdksync should have updated a number of important files. Pull these down locally and try a test run:</p>
<pre>
cd ~/git/lmax-woof
git pull --rebase
pdk test unit
</pre>
<p class='p'>It will test nothing (because there are no tests) but it should run without failure.</p>
<h2><a name="Dependencies"></a> Dependencies </h2>
<p></p>
If your module depends (or will depend) on other modules you need to tell the testing framework to fetch them. The <strong>.fixtures.yml</strong> file describes the modules necessary for tests to pass. A good starting point is the Puppetlabs Stdlib and LMAX Stdlib, which contain various helpful functions. Only use the <em>symlink</em> option for the module you testing, everything else should be pulled down fresh. PDK will have created a sample fixtures file that would fetch Puppelabs Stdlib from the Puppet Forge:
<p></p>
<pre>
$ cat .fixtures.yml
# This file can be used to install module dependencies for unit testing
# See https://github.com/puppetlabs/puppetlabs&#95;spec&#95;helper#using-fixtures for details
---
fixtures:
forge&#95;modules:
# stdlib: &#34;puppetlabs/stdlib&#34;
</pre>
<p class='p'>Our preference is to always use our internal Git repo as a mirror though. It's faster, and tests still run if we can't reach the Forge for whatever reason.</p>
<p class='p'>Overwrite the fixtures file like so:</p>
<pre>
cd ~/git/lmax-woof
cat &#62; .fixtures.yml &#60;&#60;EOF
fixtures:
repositories:
stdlib: &#34;https://git/techops-puppet-3rd-party/puppetlabs-stdlib.git&#34;
lmax&#95;stdlib: &#34;https://git/techops-puppet/lmax-lmax&#95;stdlib.git&#34;
symlinks:
testmodule: &#34;#{source&#95;dir}&#34;
EOF
</pre>
<p class='p'>Commit and push that:</p>
<pre>
git commit -a -m &#34;fixtures update&#34;
git push
</pre>
<p class='p'>That will have failed, because the 'master' branch is protected now:</p>
<pre>
! &#91;remote rejected] master -&#62; master (pre-receive hook declined)
error: failed to push some refs to &#39;https://git/techops-puppet/lmax-woof.git&#39;
</pre>
<p></p>
You need to push your changes to a different branch, then create a Merge Request in Gitlab, wait for the tests to pass, <em>then</em> you can merge it.
<p class='p'>If you do this 50 times a day with a mouse and web browser it's going to get tedious - you can do it all from the command line.</p>
<h2><a name="Speeding_up_Merge_Requests"></a> Speeding up Merge Requests </h2>
<p></p>
<img src="/pub/System/DocumentGraphics/tip.png" alt="IDEA!" title="IDEA!" width="16" height="16" /> This workflow optimisation only makes sense if doing small, non-breaking changes. If we were doing something large, or something we knew would break things, then obviously we would <strong>NOT</strong> merge our changes immediately into the master branch.
<p></p>
If you're using a reasonably recent version of Git, there are extra options you can add that Git Lab understands and will create Merge Requests for you. I have this as a Git Alias. In my <em>~/.gitconfig</em> file:
<p></p>
<pre>
...
&#91;credential]
helper &#61; /usr/libexec/git-core/git-credential-libsecret
&#91;alias]
bpm &#61; push -o merge&#95;request.create -o merge&#95;request.remove&#95;source&#95;branch -o merge&#95;request.merge&#95;when&#95;pipeline&#95;succeeds
</pre>
<p class='p'>Add that alias, and add the credentials helper at the same time if it's not there (unless you like typing your password 200 times a day).</p>
You can now switch to a new branch in the local Git repo, and <strong>git bpm</strong> to push with those extra options. I've streamlined mine a little more to handle the switching into a specific branch first. Here is my <strong>bpm</strong> script (Branch Push Merge):
<p></p>
<pre>
cat ~/bin/bpm
#!/bin/bash
BPM&#95;BRANCH&#61;&#34;biguml&#95;bpm&#34;
BRANCH&#61;$(git branch --no-color --show-current)
if &#91;&#91; $BRANCH !&#61; $BPM&#95;BRANCH ]]; then
git branch --no-color &#124; grep -q $BPM&#95;BRANCH
RET&#61;$?
if &#91;&#91; $RET &#61;&#61; 0 ]]; then
git branch -D $BPM&#95;BRANCH
fi
git checkout -b $BPM&#95;BRANCH
fi
git push --set-upstream origin biguml&#95;bpm -o merge&#95;request.create -o merge&#95;request.remove&#95;source&#95;branch -o merge&#95;request.merge&#95;when&#95;pipeline&#95;succeeds -o merge&#95;request.title&#61;&#34;BPM: $(git log -1 --pretty&#61;&#37;B &#124; head -n1)&#34;
if &#91;&#91; $BRANCH !&#61; $BPM&#95;BRANCH ]]; then
git checkout $BRANCH
fi
</pre>
<p></p>
<h2><a name="Deploying_a_puppet_module_to_production"></a> Deploying a puppet module to production </h2>
<p></p>
To deploy a puppet module to the puppet master look at the instructions on the <a href="/Technology/R10k">R10k</a> page.
<p></p>
<p class='p'></p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment