<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Anthony Bouvier</title>
    <description>The latest articles on DEV Community by Anthony Bouvier (@thebouv).</description>
    <link>https://dev.to/thebouv</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F6682%2Fc9183280-ce51-4ca7-912c-9a2c5b5cb5e1.jpg</url>
      <title>DEV Community: Anthony Bouvier</title>
      <link>https://dev.to/thebouv</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thebouv"/>
    <language>en</language>
    <item>
      <title>Changing GitHub Enterprise users from LDAP to local</title>
      <dc:creator>Anthony Bouvier</dc:creator>
      <pubDate>Thu, 22 Apr 2021 02:20:56 +0000</pubDate>
      <link>https://dev.to/thebouv/changing-github-enterprise-users-from-ldap-to-local-278</link>
      <guid>https://dev.to/thebouv/changing-github-enterprise-users-from-ldap-to-local-278</guid>
      <description>&lt;h2&gt;
  
  
  What?
&lt;/h2&gt;

&lt;p&gt;The company I work for recently split off our entire software engineering team, part of other teams, and backoffice people into a stand alone independent software vendor. For the time being we're sharing a single GitHub Enterprise instance on prem and as part of the transition we've moved the new company staff off to their own Active Directory.&lt;/p&gt;

&lt;p&gt;Unlike other tooling I have in place like Jenkins or Harbor, GitHub Enterprise only supports using a single AD/LDAP server (version 3.0.4 as of the publishing of this post). So the 6 or so digital marketing developers left behind at the parent company have to be converted from LDAP auth to local authentication.&lt;/p&gt;

&lt;p&gt;Thankfully this is possible with GitHub Enterprise via this setting:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu5t4nka8d4666xtd4op6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu5t4nka8d4666xtd4op6.png" alt="screenshot of github admin settings to allow local account creation along side ldap accounts"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  But?
&lt;/h2&gt;

&lt;p&gt;The issue is that accounts that were previously LDAP are flagged as that and this setting only allows for new accounts.&lt;/p&gt;

&lt;p&gt;I asked GitHub for instructions on how to convert those accounts and they sent me some ghe-console commands to run. And here is what they sent me:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If enabled, temporarily disable LDAP sync to prevent it from re-writing the LDAP associations.&lt;/p&gt;

&lt;p&gt;Connect to the server via SSH. Destroy the LDAP mapping for the users you'd like to switch to built-in authentication and set a default password for those users: (replace USERNAME with the user's actual GitHub username, and replace NEW_PASSWORD with a temporary password)&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;  &lt;span class="n"&gt;ghe&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;console&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;
  &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_by_login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"USERNAME"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;ldap_mapping&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;destroy&lt;/span&gt;
  &lt;span class="n"&gt;pass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"NEW_PASSWORD"&lt;/span&gt;
  &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_by_login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"USERNAME"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update_attributes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;password: &lt;/span&gt;&lt;span class="n"&gt;pass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;password_confirmation: &lt;/span&gt;&lt;span class="n"&gt;pass&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;exit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Ensure these users are not in the LDAP directory before they attempt to login again.  &lt;/p&gt;

&lt;p&gt;Re-enable LDAP sync if necessary.&lt;/p&gt;

&lt;p&gt;Instruct users to update passwords after logging in.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No doubt this is from their support team's knowledgebase. The problem is it throws errors on trying to use the code as-is.&lt;/p&gt;

&lt;p&gt;Of course, I only had a few tracebacks to go off of like this one for &lt;code&gt;update_attributes&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Traceback (most recent call last):
        3: from /github/script/console:92:in `&amp;lt;main&amp;gt;'
        2: from (irb):4
        1: from /github/vendor/gems/2.7.1/ruby/2.7.0/gems/activemodel-6.1.0.rc1.8389f99/lib/active_model/attribute_methods.rb:469:in `method_missing'
NoMethodError (undefined method `update_attributes' for #&amp;lt;User:0x000000000000&amp;gt;)
Did you mean?  update_attribute
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So then I tried to change it to &lt;code&gt;update_attribute&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Traceback (most recent call last):
        4: from /github/script/console:92:in `&amp;lt;main&amp;gt;'
        3: from (irb):4
        2: from (irb):5:in `rescue in irb_binding'
        1: from /github/vendor/gems/2.7.1/ruby/2.7.0/gems/activerecord-6.1.0.rc1.8389f99/lib/active_record/persistence.rb:612:in `update_attribute'
ArgumentError (wrong number of arguments (given 1, expected 2))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Damn. Well, it sorta &lt;em&gt;looks&lt;/em&gt; like I'm sending two arguments instead of one, so what's going on?&lt;/p&gt;

&lt;p&gt;Since I now know we're dealing with Ruby in the &lt;em&gt;ghe-console&lt;/em&gt; I start looking up some docs and find out that &lt;strong&gt;update_attribute&lt;/strong&gt; only does one attribute at a time and whatever format I'm sending it doesn't like.&lt;/p&gt;

&lt;p&gt;I also look up &lt;strong&gt;update_attributes&lt;/strong&gt; and find out it was deprecated. You only need &lt;strong&gt;update&lt;/strong&gt; in this case. So I try &lt;strong&gt;update&lt;/strong&gt; with the same params and it worked:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;password: &lt;/span&gt;&lt;span class="n"&gt;pass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;password_confirmation: &lt;/span&gt;&lt;span class="n"&gt;pass&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or what I originally tried works too using a different syntax for sending the attributes that I saw in the &lt;strong&gt;update&lt;/strong&gt; documentation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:password&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;pass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:password_confirmation&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;pass&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Gut?
&lt;/h2&gt;

&lt;p&gt;Mostly just chose that subtitle to rhyme with the others, but actually using your gut to do such debugging is something I recommend. The longer you're in this business, the more experience you have running up against just weird scenarios like the above. My vendor gave me syntax that was actually out of date, but I used the info given to me for a language I have zero experience with to debug what to do next.&lt;/p&gt;

&lt;p&gt;And I wrote them back to let them know to update their knowledgebase.&lt;/p&gt;

&lt;p&gt;So follow your gut! Know how to look up docs even for things you don't know about or langauges you're unfamiliar with. &lt;/p&gt;

&lt;p&gt;Deduce. Experiment. Test. Repeat. It becomes second nature.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>github</category>
      <category>enterprise</category>
    </item>
    <item>
      <title>Apple AirTag announced</title>
      <dc:creator>Anthony Bouvier</dc:creator>
      <pubDate>Tue, 20 Apr 2021 17:54:24 +0000</pubDate>
      <link>https://dev.to/thebouv/apple-airtag-announced-3a04</link>
      <guid>https://dev.to/thebouv/apple-airtag-announced-3a04</guid>
      <description>&lt;p&gt;The AirTag has been &lt;a href="https://www.apple.com/newsroom/2021/04/apple-introduces-airtag/"&gt;announced&lt;/a&gt; by Apple.&lt;/p&gt;

&lt;p&gt;"Apple today introduced AirTag, a small and elegantly designed accessory that helps keep track of and find the items that matter most with Apple’s Find My app. Whether attached to a handbag, keys, backpack, or other items, AirTag taps into the vast, global Find My network1 and can help locate a lost item, all while keeping location data private and anonymous with end-to-end encryption. AirTag can be purchased in one and four packs for just $29 and $99, respectively, and will be available beginning Friday, April 30. "&lt;/p&gt;

&lt;p&gt;And I think the real key element here is the use of Find My App / Find My Network.&lt;/p&gt;

&lt;p&gt;Apparently this leverages the vast, mostly unknown, network that Apple has where every device from them with Bluetooth on contributes to the Find My network. Meaning, even if you don't own a AirTag, but you happen to have Bluetooth on and are near an AirTag, your phone will send and receive data to share the location with the network.&lt;/p&gt;

&lt;p&gt;No opt-in. No opt-out besides leaving Bluetooth off.&lt;/p&gt;

&lt;p&gt;Though I've definitely been one to lose my keys or backpack and wish I had something like an AirTag or its predecessor called &lt;a href="https://www.thetileapp.com/"&gt;Tile&lt;/a&gt; I am wholly uncomfortable that they are using my device to communicate with other people's devices creating a large mesh network with no knowledge of my participation.&lt;/p&gt;

&lt;p&gt;This is being discussed on Hacker News right now and other sites too. The benefit seems cool and huge, but much like Amazon's announcement several months ago about its &lt;a href="https://www.forbes.com/sites/paullamkin/2020/11/27/what-is-amazon-sidewalk-and-why-is-it-on-your-echo-smart-speaker/?sh=34f46e19acfd"&gt;Sidewalk&lt;/a&gt; feature, I feel like there will be a &lt;a href="https://www.businessinsider.com/amazon-sidewalk-privacy-neighborhood-wifi-networks-us-2020-11?op=1"&gt;backlash&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I'd love to hear what others think because my initial reaction is revulsion. And I'm seeing mixed thoughts on articles concerning it. To me it is without my consent and if it weren't for a single device in my home I use Bluetooth for from my iPhone I would definitely have it turned off all the time.&lt;/p&gt;

&lt;p&gt;Why isn't there active, positive consent to participate in this?&lt;/p&gt;

&lt;p&gt;Why isn't this theft of resources, although minimal, to participate in this?&lt;/p&gt;

&lt;p&gt;Do we really want to participate more in the already egregious tracking done by just participating in having a smart phone?&lt;/p&gt;

</description>
      <category>apple</category>
      <category>iot</category>
      <category>privacy</category>
      <category>ios</category>
    </item>
    <item>
      <title>Temperature and Humidity Sensors (part one)</title>
      <dc:creator>Anthony Bouvier</dc:creator>
      <pubDate>Sun, 18 Apr 2021 21:25:02 +0000</pubDate>
      <link>https://dev.to/thebouv/temperature-and-humidity-sensors-part-one-32le</link>
      <guid>https://dev.to/thebouv/temperature-and-humidity-sensors-part-one-32le</guid>
      <description>&lt;p&gt;This article originally was &lt;a href="https://thebouv.com/temperature-and-humidity-sensors-part-one.html"&gt;published&lt;/a&gt; on the &lt;a href="https://thebouv.com"&gt;my site&lt;/a&gt; where I discuss my homelab, DevOps, and other tech related topics. &lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up
&lt;/h2&gt;

&lt;p&gt;I have a home from 1914 which has a lot of charm and a lot of issues. One of which is the need to constantly pay attention to the humidity levels and temperature in all floors, finished and unfinished, in the house. This project of my homelab will cover the hardware and custom software I write for it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hardware
&lt;/h3&gt;

&lt;p&gt;4x Raspberry Pi Zero WH (just like the W, but with pre-soldered headers on the GPIO)&lt;br&gt;&lt;br&gt;
4x Raspberry Pi official zero w cases&lt;br&gt;&lt;br&gt;
4x Raspberry Pi official power supplies&lt;br&gt;&lt;br&gt;
4x Gigastone 16gb MicroSDHC  &lt;/p&gt;
&lt;h3&gt;
  
  
  Operating System
&lt;/h3&gt;

&lt;p&gt;Though I wish I could use Ubuntu LTS on the Pi Zero W, it doesn't seem to be supported or I at least haven't been able to find out how to boot it. Like my pihole project for the lab, I'm using the most recent official Raspberry Pi OS Lite (because I don't want a desktop environment on this headless computer). And of course I use the Raspberry Pi Imager -- it's just really convenient.&lt;/p&gt;

&lt;p&gt;After I image the SD card I make a couple changes to the config.txt file on the card itself from the host machine I did the imaging from.  This is so I can set the gpu mem split and disable bluetooth.&lt;/p&gt;

&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: when the Raspberry Pi imager is done it unmounts the SD card, so you'll need to plug it back in to your host machine to edit the config.txt file.  On my Mac, it mounts as &lt;em&gt;boot&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;

&lt;p&gt;I add these two lines config.txt. There are a couple of lines that already set dtoverlay that are commented out, so I just put both of these in that area:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gpu_mem=16
dtoverlay=disable-bt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Wi-Fi
&lt;/h3&gt;

&lt;p&gt;I also want to go ahead and set up the wifi on the pi zero so that when I turn it on it automatically connects.&lt;/p&gt;

&lt;p&gt;Following this &lt;a href="https://learn.adafruit.com/raspberry-pi-zero-creation/text-file-editing"&gt;tutorial&lt;/a&gt; I create the &lt;em&gt;wpa_supplicant.conf&lt;/em&gt; file on the root level of the boot drive while the SD is still connected.&lt;/p&gt;

&lt;h3&gt;
  
  
  SSH
&lt;/h3&gt;

&lt;p&gt;SSH is disabled by default so since I want to log in soon after booting it and stay headless, I merely need to add a blank file named &lt;em&gt;ssh&lt;/em&gt; to the root level of the ssd that I still have mounted.&lt;/p&gt;

&lt;p&gt;Once I've done that I eject the SD card and install it into the pi zero.&lt;/p&gt;

&lt;h2&gt;
  
  
  First Boot
&lt;/h2&gt;

&lt;p&gt;After I first boot, I want to make sure to make some changes to each device. There's probably a way to get fancy and make this super repeatable, but I'm not installing 100 sensors; I'm installing 4.&lt;/p&gt;

&lt;h3&gt;
  
  
  Wrap Up Setup
&lt;/h3&gt;

&lt;p&gt;I find the device on my network by looking at my Unifi OS that shows the whole network as a map and I just found the device and ip there, but I could also scan the network from the command line and look for Raspberry Pi MAC addresses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;arp -a | grep -i "b8:27:eb\|dc:a6:32"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or if you're on a Mac or a Windows machine that has Bonjour set up you might be able to talk to it at its default hostname on .local via &lt;em&gt;raspberrypi.local&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh pi@ip.address.you.found
# or 
ssh pi@raspberrypi.local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;WARNING: If you use ssh &lt;a href="mailto:pi@raspberrypi.local"&gt;pi@raspberrypi.local&lt;/a&gt; more than once because you're setting up multiple sensors, keep in mind ssh is going to complain that raspberrypi.local doesn't match the fingerprint from the last time you did it. Cause each device you set up is unique, but ssh doesn't know that. So I suggest using the IP because it is more likely to be different. And below we're giving each their own hostname anyway.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;/blockquote&gt;
&lt;br&gt;
&lt;/blockquote&gt;

&lt;p&gt;Change the default password (always a smart thing to do):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;passwd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update apt and upgrade the OS packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt upgrade -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update the hostname. I'm going with a naming scheme of 'temphum1', 'temphum2', etc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo vi /etc/hostname
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now let's shut it down for now because we're going to be installing the sensor and doing some soldering next before we turn this device back on.&lt;/p&gt;

&lt;p&gt;The part two of this post will be abour the physical aspects of the project like testing out on a breadboard and soldering the real thing together.&lt;/p&gt;

</description>
      <category>homelab</category>
      <category>raspberrypi</category>
      <category>linux</category>
    </item>
    <item>
      <title>Building my static site with Pelican (part two)</title>
      <dc:creator>Anthony Bouvier</dc:creator>
      <pubDate>Sat, 17 Apr 2021 18:59:07 +0000</pubDate>
      <link>https://dev.to/thebouv/building-my-static-site-with-pelican-part-two-135f</link>
      <guid>https://dev.to/thebouv/building-my-static-site-with-pelican-part-two-135f</guid>
      <description>&lt;p&gt;This article originally was &lt;a href="https://thebouv.com/how-i-made-this-site-part-two.html"&gt;published&lt;/a&gt; on the &lt;a href="https://thebouv.com"&gt;site&lt;/a&gt; I'm writing about. &lt;/p&gt;




&lt;p&gt;Last I left off in &lt;a href="https://dev.to/thebouv/building-my-static-site-with-pelican-part-one-330i"&gt;part one&lt;/a&gt; I generated the content with &lt;code&gt;invoke build&lt;/code&gt;. I want to go over the remaining steps on how to preview the content, how I'm publishing it to GitHub pages with the submodule created previously, and also how I plan to use &lt;strong&gt;invoke&lt;/strong&gt; to automate some of this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Markdown Tweaks
&lt;/h2&gt;

&lt;p&gt;First before previewing the content, I had to make some adjustments to how the Markdown is processed, especially for code blocks. By default pygments, which pelican uses for code highlighting, didn't mesh well with my theme. I made sure to make my pre/code blocks have a dark background for one. I also wanted it to stop guessing the language (it was giving weird results trying to guess at the command line code blocks since they're not really a 'language' per se), and for it to recognize GitHub style fenced blocks (using backticks to surround code blocks instead of relying on indentation).&lt;/p&gt;

&lt;p&gt;I added this to my &lt;em&gt;pelicanconf.py&lt;/em&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;MARKDOWN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;'extension_configs'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;'markdown.extensions.codehilite'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'css_class'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'highlight'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'guess_lang'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s"&gt;'markdown.extensions.fenced_code'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s"&gt;'output_format'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'html5'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Preview
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;invoke build&lt;/code&gt; command looks at my &lt;em&gt;pelicanconf.py&lt;/em&gt; file for settings. Some of these settings are theme specific, but they also cover things like what is the site url, how many pages to show before paginating, and so forth. Below I will also be using &lt;em&gt;publishconf.py&lt;/em&gt; for prod settings like my Google Analytics tag and FQDN for the site url.&lt;/p&gt;

&lt;p&gt;Now that the &lt;em&gt;output&lt;/em&gt; directory has my generated content, I want to preview it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;invoke serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a simple local webserver to show you my content on &lt;a href="http://localhost:8000"&gt;http://localhost:8000&lt;/a&gt; so I open Firefox and make sure everything seems to be working as expected. I click around, look for formatting weirdness, agonize internally over whether I chose the right theme or not, and then ultimately decide all is well.&lt;/p&gt;

&lt;p&gt;That's pretty cool, buuuuuuttttt:&lt;/p&gt;

&lt;h3&gt;
  
  
  Invoke
&lt;/h3&gt;

&lt;p&gt;Let's dive a bit more into the &lt;strong&gt;invoke&lt;/strong&gt; command and the default &lt;em&gt;tasks.py&lt;/em&gt; file that is created.&lt;/p&gt;

&lt;p&gt;There are lot of built in invoke tasks in this file already like &lt;strong&gt;build&lt;/strong&gt;, &lt;strong&gt;serve&lt;/strong&gt;, and &lt;strong&gt;publish&lt;/strong&gt;. Below are my tweaks.&lt;/p&gt;

&lt;p&gt;First I remove the &lt;strong&gt;clean&lt;/strong&gt;, and &lt;strong&gt;rebuild&lt;/strong&gt; commands by commenting them out (maybe I'll redo them in the future). This is becaues they're destructive and will remove the &lt;em&gt;output&lt;/em&gt; folder entirely, but remember that I'm using it as a submodule so it is its own git repo. Deleting the whole folder would be too destructive.  I also comment out the &lt;strong&gt;preview&lt;/strong&gt; task as I only need to do a prod build when I'm publishing.&lt;/p&gt;

&lt;p&gt;Next I need to change how the &lt;strong&gt;publish&lt;/strong&gt; task works because I'm not using rsync to publish this, I'm pushing the content of output to my &lt;strong&gt;thebouv.github.io&lt;/strong&gt; repo so that it serves automatically with GitHub Pages.&lt;/p&gt;

&lt;p&gt;Because I'm running two back to back commands in order to commit the output and the raw content of the main repo, I had to split it into two tasks and have one run before the other. I tried combining this into a single command but it wasn't working. Only one git command would occur and I think that is because the context is lost after git takes control and starts to spit out messages. I'll have to revisit that some day just for curiosity's sake.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;publish_output&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;pelican_run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'-s {settings_publish}'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;CONFIG&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="c1"&gt;# Commit the written content to GitHub from this repo
&lt;/span&gt;    &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CONFIG&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'deploy_path'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;'In Directory: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getcwd&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'git add .'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'git commit -m "auto-commit output from Invoke"'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'git push origin master'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;publish_output&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Commit the static html pages to thebouv.github.io repo
&lt;/span&gt;    &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'..'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# my output folder
&lt;/span&gt;    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;'In Directory: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getcwd&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'git add .'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'git commit -m "auto-commit content from Invoke"'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'git push origin master'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I only need to run &lt;code&gt;invoke publish&lt;/code&gt; and the &lt;em&gt;output&lt;/em&gt; directory is refreshed with my new generated site with prod settings from &lt;em&gt;publishconf.py&lt;/em&gt;. Then the &lt;strong&gt;thebouv.github.io&lt;/strong&gt; repo gets an auto-commit and push. Followed by &lt;strong&gt;thebouv-pelican&lt;/strong&gt; receiving an auto-commit as well (since the submodule has updated, this step commits updating the submodule to point to the new commit SHA of &lt;strong&gt;thebouv.github.io&lt;/strong&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  But wait, there's more
&lt;/h2&gt;

&lt;p&gt;I noticed in the default &lt;em&gt;task.py&lt;/em&gt; file that there is a livereload option. I had to try it out by installing the &lt;strong&gt;livereload&lt;/strong&gt; module and then invoking the task.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install livereload
pip freeze &amp;gt; requirements.txt
invoke livereload
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the browser nicely refreshes for me automatically as I edit and save. That's pretty damn handy.&lt;/p&gt;

</description>
      <category>python</category>
      <category>pelican</category>
      <category>static</category>
      <category>blog</category>
    </item>
    <item>
      <title>DevOps teams are an anti-pattern, but ...</title>
      <dc:creator>Anthony Bouvier</dc:creator>
      <pubDate>Fri, 16 Apr 2021 15:03:37 +0000</pubDate>
      <link>https://dev.to/thebouv/devops-teams-are-an-anti-pattern-but-269b</link>
      <guid>https://dev.to/thebouv/devops-teams-are-an-anti-pattern-but-269b</guid>
      <description>&lt;p&gt;People put too much pressure on themselves to do DevOps the "right" way or that they're not doing it like they read about at Netflix or Amazon or any other examples. At small to medium sized companies introducing these new concepts, someone(s) need to own getting it started and to be the evangelists.&lt;/p&gt;

&lt;p&gt;Yes, long-term having only a single team as your "DevOps" team is an anti-pattern, but you gotta start somewhere. &lt;/p&gt;

&lt;p&gt;What follows is my response to post online about how someone was feeling like they're doing DevOps wrong at their company. And asking why is a DevOps team frowned upon.&lt;/p&gt;




&lt;p&gt;I look at it like this as I currently have a DevOps title but didn’t really want one.&lt;/p&gt;

&lt;p&gt;DevOps should be your entire company’s culture. Shift responsibility left. Let the devs run what they build.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;But&lt;/em&gt; you have to start somewhere. You need people to be the catalyst. They need to learn Jenkins first to help others. Much like you describe. A central team is a DevOps anti-pattern long term but I feel like they’re necessary at first. To be the evangelists. To be the first to install the tooling, get it working in your SDLC, to create the pipelines and grease the cogs to get the culture moving.&lt;/p&gt;

&lt;p&gt;They likely own the tooling too. Or a tooling team splits off at some point. Someone needs to manage the tooling and host it and upgrade it and juggle licensing.&lt;/p&gt;

&lt;p&gt;But be open to others learning. Cross train devs and ops people. Make sure not to bottleneck people needing resources. Find ways they can fire up their own vms, containers, app services, storage accounts, etc. Eventually that is.&lt;/p&gt;

&lt;p&gt;Gotta start somewhere. Not everyone is or can be a FAANG company. Not everyone needs every aspect of DevOps people try to shove your way. Not everyone needs to throw k8s at every problem. And so on.&lt;/p&gt;

&lt;p&gt;Improve tooling.&lt;br&gt;&lt;br&gt;
Improve dev empowerment.&lt;br&gt;&lt;br&gt;
Improve SDLC.&lt;br&gt;&lt;br&gt;
Improve testing.&lt;br&gt;&lt;br&gt;
Improve blameless culture.&lt;br&gt;&lt;br&gt;
Improve observability.&lt;br&gt;&lt;br&gt;
Improve continuously.  &lt;/p&gt;

&lt;p&gt;Do those and your company/team will become DevOps too. Your team will evolve too. You’ll continue to expand what you offer and what you can institutionalize.&lt;/p&gt;

&lt;p&gt;Or maybe they resist every damn change you propose and never want to improve. At that point you flip the proverbial table and find a place where you CAN do those things. :)&lt;/p&gt;




&lt;p&gt;This article originally was &lt;a href="https://thebouv.com/devops-teams-are-an-anti-pattern-but.html"&gt;published&lt;/a&gt; on &lt;a href="https://thebouv.com"&gt;thebouv.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
    </item>
    <item>
      <title>Building my static site with Pelican (part one)</title>
      <dc:creator>Anthony Bouvier</dc:creator>
      <pubDate>Thu, 15 Apr 2021 14:24:49 +0000</pubDate>
      <link>https://dev.to/thebouv/building-my-static-site-with-pelican-part-one-330i</link>
      <guid>https://dev.to/thebouv/building-my-static-site-with-pelican-part-one-330i</guid>
      <description>&lt;p&gt;I chose to use &lt;a href="https://getpelican.org/"&gt;pelican&lt;/a&gt; for a few reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This site is hosted for free on GitHub and that means it needs to be statically generated. &lt;/li&gt;
&lt;li&gt;Pelican is written in python and I'm a python fanboy.&lt;/li&gt;
&lt;li&gt;Pelican is still in active development based on the merges, issues, and discussion on its repo in GitHub.&lt;/li&gt;
&lt;li&gt;Pelican has all the features I need plus I can supplement with other things like &lt;a href="http://www.pyinvoke.org/"&gt;invoke&lt;/a&gt; (which I just learned about and am excited to try).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the final structure, I will have one repo for the pelican install (&lt;em&gt;thebouv-pelican.git&lt;/em&gt;) which will have settings, pelican files, raw assets like a post's markdown files and images. And one for the static site files (&lt;em&gt;thebouv.github.io.git&lt;/em&gt;) because GitHub only serves from root or /docs. I feel this way is cleaner and allows the I will be automating publishing with &lt;strong&gt;invoke&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I am basing this process off of &lt;a href="https://randlow.github.io/posts/python/create-pelican-blog/"&gt;this tutorial&lt;/a&gt; but with some of my own ideas and organizational changes. Definitely fewer dependencies as I have no need for Jupyter Notebooks on this site, nor for now do I think I need typogrify or beautifulsoup as per that tutorial. I'll also be looking at the &lt;a href="https://docs.getpelican.com/en/latest/install.html"&gt;pelican quickstart&lt;/a&gt; and other pelican docs to make decisions as I go.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up
&lt;/h2&gt;

&lt;p&gt;First I cleared all previous content out of my previous static site and leave only the README.md and CNAME files. The README will get updated during the project and CNAME is a text file required by GitHub to have thebouv.com as a custom domain.  I could have set up a totally new repo or trashed this one and restarted, but with git I don't need to and I can always roll back one day or refer to the old site if I need.&lt;/p&gt;

&lt;h3&gt;
  
  
  Some git stuff
&lt;/h3&gt;

&lt;p&gt;I create my empty repo for &lt;em&gt;thebouv-pelican&lt;/em&gt; and set it up in GitHub as a remote:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir thebouv-pelican
cd thebouv-pelican
git init
gh repo create
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the &lt;em&gt;gh&lt;/em&gt; command. If you don't use the GitHub command line tool &lt;em&gt;gh&lt;/em&gt; yet I do recommend it. It is pretty handy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pelican!
&lt;/h3&gt;

&lt;p&gt;Now to set up my python environment and start getting Pelican set up.  I'm doing this all with python 3.9.1 because it is stable and the most recent 3.9 release that pyenv has.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python -m venv .venv
source .venv/bin/activate
pip install "pelican[markdown]" invoke
pip freeze &amp;gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now for the remainder of this post I'm going to no longer talk about being in a venv, activating, deactivating, etc. If I'm in a python project, I've got the venv activated. I assume the reader is managing this aspect.&lt;/p&gt;

&lt;p&gt;I'm going to run the &lt;em&gt;pelican_quickstart&lt;/em&gt; command line app and answer all the questions it poses. I'm filling out my site's details and pretty much accepting the defaults to things with defaults. Only thing is I'll be deleting the Makefile as I plan to use &lt;strong&gt;invoke&lt;/strong&gt; instead to run the tasks in tasks.py.&lt;/p&gt;

&lt;p&gt;I'm also manually creating a pages folder under the content folder generated by &lt;em&gt;pelican_quickstart&lt;/em&gt; because I will want some stand-alone non-blog pages in the future like a resume.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pelican_quickstart
rm -f Makefile
mkdir content/pages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This leaves me with this structure below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;thebouv-pelican/
├── content
│   └── pages
├── output
├── pelicanconf.py       # Main settings file
├── publishconf.py       # Settings to use when ready to publish
└── requirements.txt     # saved earlier from pip freeze
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that those exist and I want to start adding content, I want to do one thing real quick. I want to make my output directory actually be a git submodule of &lt;em&gt;thebouv.github.io.git&lt;/em&gt; since the generated output will be in that repo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git submodule add -f git@github.com:thebouv/thebouv.github.io.git output
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Later I will automate committing and pushing both this repo and the generated content up to GitHub with &lt;em&gt;invoke&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Theme
&lt;/h3&gt;

&lt;p&gt;For now I plan to use a theme that is inside this repo called &lt;a href="https://github.com/mc-buckets/brutalistpelican"&gt;brutalistpelican&lt;/a&gt; but host just a fork of the theme for my own version. I'm doing this because I don't need the rest of his pelican set up (I have my own which this post is about) and only the theme itself. After I clone their repo I move the theme folder out and set it all up as its own &lt;a href="https://github.com/thebouv/brutalist-theme"&gt;repo&lt;/a&gt;.  Then I can add the submodule like I wanted to do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git submodule add -f git@github.com:thebouv/brutalist-theme.git theme/brutalist-theme
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I've definitely made some changes to the theme that I'm not going to go into detail on. One of the main things I've done is get rid of any external javascript except Google Analytics. I also tweak page width to 60em max (non-brutalist but I wanted a slightly wider content area). I'll be making more changes over time and if they're significant, I'll write about them but likely most will be slight tweaks.&lt;/p&gt;

&lt;p&gt;Any changes I make to the theme will need to be pushed up as well to its own repo but I can do it &lt;em&gt;from&lt;/em&gt; the submodule itself which is handy and something I will be automating with &lt;strong&gt;invoke&lt;/strong&gt; in part two of this post.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd theme/brutal-theme
git add --all
git commit -m "some message about the changes I made"
git push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Let's fire this baby up!
&lt;/h2&gt;

&lt;p&gt;This article, the one I'm writing and you're reading, is the first post in my blog. So the instructions below are so I can test this out locally and see it for the first time in all its simple glory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;invoke build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This statically generates all the content and uses the theme to style it. Then it puts all those static files in output which you'll recall is a submodule. Then I can go into that folder add all the output to git and push it up. And since it is set up to be hosted by GitHub once this output is pushed up, my site will appear here at &lt;a href="https://thebouv.com"&gt;https://thebouv.com&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd output
git add --all
git commit -m "auto-generated output from pelican"
git push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Next time
&lt;/h3&gt;

&lt;p&gt;Okay, realize this is getting long and I have more to do but I've detailed everything that has gotten the site to this point.  Well, besides the fact that I switched themes like 5 times but I didn't need to document that part. ;)&lt;/p&gt;

&lt;p&gt;You can read &lt;a href="https://dev.to/thebouv/building-my-static-site-with-pelican-part-two-135f"&gt;part two&lt;/a&gt; if you want. :)&lt;/p&gt;

</description>
      <category>python</category>
      <category>pelican</category>
      <category>static</category>
      <category>blog</category>
    </item>
  </channel>
</rss>
