<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>GitHub on Nelson Figueroa</title><link>https://nelson.cloud/categories/github/</link><description>Recent content in GitHub on Nelson Figueroa</description><image><title>Nelson Figueroa</title><url>https://nelson.cloud/apple-touch-icon.png</url><link>https://nelson.cloud/categories/github/</link></image><language>en</language><lastBuildDate>Thu, 26 Mar 2026 19:18:46 -0700</lastBuildDate><atom:link href="https://nelson.cloud/categories/github/index.xml" rel="self" type="application/rss+xml"/><item><title>GitHub Actions for Pulumi with an AWS S3 Backend</title><link>https://nelson.cloud/github-actions-for-pulumi-with-an-aws-s3-backend/?ref=rss</link><pubDate>Thu, 11 Dec 2025 00:00:00 +0000</pubDate><guid>https://nelson.cloud/github-actions-for-pulumi-with-an-aws-s3-backend/?ref=rss</guid><description>How to set up GitHub Actions for Pulumi when the state is stored in an AWS S3 Bucket.</description><content:encoded><![CDATA[<h2 id="introduction">Introduction</h2>
<p>This is a quick guide to set up GitHub Actions for Pulumi with an 

<a href="https://aws.amazon.com/s3/" target="_blank" rel="noopener">AWS S3</a> backend. It builds on a previous guide I wrote: 

<a href="https://nelson.cloud/how-to-use-an-aws-s3-bucket-as-a-pulumi-state-backend/">How to Use an AWS S3 Bucket as a Pulumi State Backend</a>.</p>
<p>This guide assumes you have the following:</p>
<ul>
<li>An AWS S3 Bucket created and ready to be used with Pulumi</li>
<li>An IAM User that has permissions to read/write to the S3 bucket</li>
<li>The Access Key and Secret Access Key for the IAM User to use for authenticating to AWS within GitHub Actions</li>
<li>A passphrase of your choosing that will be used to encrypt secrets in the pulumi stack</li>
<li>A GitHub repository</li>
</ul>
<h2 id="setting-up-repository-secrets">Setting up Repository Secrets</h2>
<p>First, set up secrets on your GitHub repository. These will be filled in by GitHub Actions once we create a workflow YAML. You&rsquo;ll need to create 3 secrets. You can name them whatever you want, but I&rsquo;ll be naming them:</p>
<ul>
<li><code>AWS_ACCESS_KEY_ID</code></li>
<li><code>AWS_SECRET_ACCESS_KEY</code></li>
<li><code>PULUMI_CONFIG_PASSPHRASE</code></li>
</ul>
<p>You can create these by browsing to your GitHub repository &gt; Settings &gt; Secrets and variables &gt; Actions. There are &ldquo;Environment secrets&rdquo; and &ldquo;Repository secrets&rdquo;. In this case go with &ldquo;Repository secrets&rdquo;.</p>
<p>Create the three secrets and fill in their respective values. <code>PULUMI_CONFIG_PASSPHRASE</code> can be whatever you want and doesn&rsquo;t come from AWS.</p>
<blockquote><p><strong>Warning:</strong></p>Make sure you don&rsquo;t change this passphrase after the fact, or your Pulumi state may break.</blockquote>

<p>The end result should look like this:</p>
<img src="/github-actions-with-pulumi-s3/github-secrets.webp" alt="GitHub repository secrets showing AWS credentials and Pulumi passphrase" width="3096" height="1708" style="max-width: 100%; height: auto; aspect-ratio: 774 / 427;" loading="lazy" decoding="async">
<h2 id="defining-the-github-actions-workflow">Defining the GitHub Actions Workflow</h2>
<p>Next, clone the repository locally with <code>git clone</code>. We&rsquo;ll need to create a few files for a minimum viable Pulumi program. Run <code>pulumi new</code> and it&rsquo;ll guide you through the creation of a basic Pulumi program. The language you choose doesn&rsquo;t matter.</p>
<p>Then we can create the YAML file to set up GitHub Actions. Create a YAML file under <code>&lt;your-repository-name&gt;/.github/workflows/</code>. I&rsquo;ll call it <code>preview.yml</code> in my example. Fill it in with the following YAML, changing values as needed.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Pulumi</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">on</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">push</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">branches</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">main</span><span class="w"> </span><span class="c"># change this if you&#39;re using a different branch name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">jobs</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">preview</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Preview</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">runs-on</span><span class="p">:</span><span class="w"> </span><span class="l">ubuntu-latest</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">steps</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/checkout@v4</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Pulumi Preview</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">pulumi/actions@v6.6.1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">with</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">command</span><span class="p">:</span><span class="w"> </span><span class="l">preview</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">stack-name</span><span class="p">:</span><span class="w"> </span><span class="l">dev</span><span class="w"> </span><span class="c"># change this to your stack&#39;s name (or whatever you want it to be if it doesn&#39;t exist)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">cloud-url</span><span class="p">:</span><span class="w"> </span><span class="l">s3://nelson-test-bucket-for-github-actions</span><span class="w"> </span><span class="c"># change this to your bucket name to be used as a pulumi backend</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">upsert</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span><span class="c"># creates a stack if it doesn&#39;t exist (along with Pulumi.&lt;stack&gt;.yaml)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">env</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">AWS_ACCESS_KEY_ID</span><span class="p">:</span><span class="w"> </span><span class="l">${{ secrets.AWS_ACCESS_KEY_ID }}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">AWS_SECRET_ACCESS_KEY</span><span class="p">:</span><span class="w"> </span><span class="l">${{ secrets.AWS_SECRET_ACCESS_KEY }}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">PULUMI_CONFIG_PASSPHRASE</span><span class="p">:</span><span class="w"> </span><span class="l">${{ secrets.PULUMI_CONFIG_PASSPHRASE }}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">AWS_REGION</span><span class="p">:</span><span class="w"> </span><span class="l">us-east-1</span><span class="w"> </span><span class="c"># change the region as needed</span></span></span></code></pre></div><p>This runs a <code>pulumi preview</code> so it&rsquo;ll verify that everything is set up correctly without actually deploying anything.</p>
<h2 id="testing-the-workflow">Testing the Workflow</h2>
<p>Now push your code to GitHub and see if the GitHub Action workflow ran successfully. You should see output from a successful <code>pulumi preview</code>.</p>
<img src="/github-actions-with-pulumi-s3/github-actions-logs.webp" alt="GitHub Actions workflow logs showing successful Pulumi preview" width="2854" height="1632" style="max-width: 100%; height: auto; aspect-ratio: 1427 / 816;" loading="lazy" decoding="async">
<p>If this works, you should be good to go. You can update your Pulumi code and change <code>command: preview</code> to <code>command: up</code> in the GitHub Actions YAML file and run it again to actually deploy some infrastructure.</p>
<h2 id="references">References</h2>
<ul>
<li>

<a href="https://github.com/pulumi/actions" target="_blank" rel="noopener">https://github.com/pulumi/actions</a></li>
</ul>
]]></content:encoded></item><item><title>How to Enable Manual Runs of GitHub Actions Workflows</title><link>https://nelson.cloud/how-to-enable-manual-runs-of-github-actions-workflows/?ref=rss</link><pubDate>Tue, 27 Dec 2022 00:00:00 +0000</pubDate><guid>https://nelson.cloud/how-to-enable-manual-runs-of-github-actions-workflows/?ref=rss</guid><description>Add workflow_dispatch to your GitHub Actions YAML to enable the &amp;lsquo;Run workflow&amp;rsquo; button.</description><content:encoded><![CDATA[<p>By default, GitHub Actions does not allow you to run a workflow manually. In order to enable manual workflow runs, I had to add <code>workflow_dispatch</code> to the YAML file under <code>.github/workflows/</code>.</p>
<p>For example, the beginning of my GitHub Actions YAML file looked like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Deploy</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">on</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">push</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">branches</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">master</span></span></span></code></pre></div><p>This configuration allows for workflows to run on commit pushes to the <code>master</code> branch, but there is no option to run this workflow manually on GitHub:</p>
<img src="/how-to-enable-manual-runs-of-github-actions-workflows/no-manual-run.webp" alt="GitHub Actions doesn't show a manual way of running the workflow." width="720" height="259" style="max-width: 100%; height: auto; aspect-ratio: 1862 / 672;" loading="lazy" decoding="async">
<p>To enable manual runs of workflows, I added the <code>workflow_dispatch</code> key. There was no need to add anything else under it:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Deploy</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">on</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">push</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">branches</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">master</span><span class="w">
</span></span></span><span class="line hl"><span class="cl"><span class="w">  </span><span class="l">workflow_dispatch:</span></span></span></code></pre></div>
<p>After pushing changes, I was able to see a &ldquo;Run workflow&rdquo; button that allows me to run the workflow manually.</p>
<img src="/how-to-enable-manual-runs-of-github-actions-workflows/manual-run-enabled.webp" alt="GitHub Actions now shows a manual way of running the workflow." width="720" height="306" style="max-width: 100%; height: auto; aspect-ratio: 1854 / 790;" loading="lazy" decoding="async">
<p>You can also run workflows using the 

<a href="https://cli.github.com/" target="_blank" rel="noopener">GitHub CLI</a> once <code>workflow_dispatch</code> is in your workflow YAML file. Assuming your workflow YAML is named <code>main.yml</code>, you can run:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">gh workflow run main.yml</span></span></code></pre></div><p>And you&rsquo;ll get output similar to the following:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">✓ Created workflow_dispatch event for main.yml at master
</span></span><span class="line"><span class="cl">https://github.com/nelsonfigueroa/nelson.cloud/actions/runs/22656361802
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">To see the created workflow run, try: gh run view 22656361802</span></span></code></pre></div><p>Note that there are a lot more configuration options available when adding the <code>workflow_dispatch</code> key. However, I just wanted to enable manual runs and nothing more. Refer to 

<a href="https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows#workflow_dispatch" target="_blank" rel="noopener">the documentation</a> for more information.</p>
<h2 id="references">References</h2>
<ul>
<li>

<a href="https://docs.github.com/en/actions/how-tos/manage-workflow-runs/manually-run-a-workflow" target="_blank" rel="noopener">https://docs.github.com/en/actions/how-tos/manage-workflow-runs/manually-run-a-workflow</a></li>
<li>

<a href="https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows#workflow_dispatch" target="_blank" rel="noopener">https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows#workflow_dispatch</a></li>
<li>

<a href="https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows" target="_blank" rel="noopener">https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows</a></li>
<li>

<a href="https://cli.github.com/manual/gh_workflow_run" target="_blank" rel="noopener">https://cli.github.com/manual/gh_workflow_run</a></li>
</ul>
]]></content:encoded></item><item><title>Scraping GitHub Contributor Emails</title><link>https://nelson.cloud/scraping-github-contributor-emails/?ref=rss</link><pubDate>Sat, 30 Oct 2021 00:00:00 +0000</pubDate><guid>https://nelson.cloud/scraping-github-contributor-emails/?ref=rss</guid><description>Scraping GitHub contributor emails, and how you can protect yourself.</description><content:encoded><![CDATA[<blockquote><p><strong>Note:</strong></p>2022-07-21 update: I discovered a better way to do this and I wrote about it in a separate blog post. Check it out here: 

<a href="https://nelson.cloud/scrape-contributor-emails-from-any-git-repository/" target="_blank" rel="noopener">Scrape Contributor Emails From Any Git Repository</a></blockquote>

<h2 id="git-emails">Git Emails</h2>
<p>When setting up Git on the command line, you are asked for your email.
When pushing commits to GitHub, the email you are using for Git gets pushed along with your code as part of the metadata.
While your GitHub email does not publicly show when viewing a repository&rsquo;s commits, it does come up when viewing commits using the GitHub API.</p>
<p>This presents a privacy risk and the potential for someone to find the email associated with your GitHub account.
I wanted to see how easily someone could do this so I created a scraper to do this for me. It turns out it&rsquo;s not hard to scrape commits for emails that are otherwise hidden from public view.</p>
<blockquote><p><strong>Disclaimer:</strong></p>I don&rsquo;t plan on doing anything malicious with this script or the emails collected. I did this out of curiosity and for demonstrational purposes.</blockquote>

<p>The scraper I created is below. Instructions can be found on the README:</p>
<ul>
<li>

<a href="https://github.com/nelsonfigueroa/github-email-scraper" target="_blank" rel="noopener">https://github.com/nelsonfigueroa/github-email-scraper</a></li>
</ul>
<h2 id="scraping-for-emails">Scraping for Emails</h2>
<p>By running the script, I can scrape for emails found in each commit for a given repository:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-console" data-lang="console"><span class="line"><span class="cl"><span class="gp">$</span> ruby main.rb -u torvalds -r linux
</span></span><span class="line"><span class="cl"><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="go">	+-------------------+
</span></span></span><span class="line"><span class="cl"><span class="go">	|   GitHub          |
</span></span></span><span class="line"><span class="cl"><span class="go">	|       Email       |
</span></span></span><span class="line"><span class="cl"><span class="go">	|         Scraper   |
</span></span></span><span class="line"><span class="cl"><span class="go">	+-------------------+
</span></span></span><span class="line"><span class="cl"><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="go">Scraping https://github.com/torvalds/linux/
</span></span></span><span class="line"><span class="cl"><span class="go">Rate limit exceeded.
</span></span></span><span class="line"><span class="cl"><span class="go">Pages scraped: 1-46 out of 10449
</span></span></span><span class="line"><span class="cl"><span class="go">53 emails written to torvalds-linux.txt
</span></span></span></code></pre></div><p>Just like that, I&rsquo;ve scraped several emails. It&rsquo;s not much, and I could get a lot more if I bothered to authenticate to prevent rate limiting.
A patient scraper could simply run this periodically to get as many emails as possible.</p>
<p>So what can we do about this?</p>
<h2 id="hiding-your-email-in-github-commits">Hiding your Email in GitHub Commits</h2>
<p>You can choose to hide your email when performing Git operations on the GitHub site as well as the command line. There are two checkboxes you&rsquo;ll need to tick. Instructions are below:</p>
<ul>
<li>

<a href="https://docs.github.com/en/account-and-profile/how-tos/email-preferences/blocking-command-line-pushes-that-expose-your-personal-email-address" target="_blank" rel="noopener">Blocking command line pushes that expose your personal email address</a></li>
</ul>
<p>Next, you&rsquo;ll need to change your email Git uses on your machine to the <code>@users.noreply.github.com</code> email that GitHub provided in the previous step. Run the following:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-console" data-lang="console"><span class="line"><span class="cl"><span class="gp">$</span> git config --global user.email <span class="s2">&#34;00000000+yourusername@users.noreply.github.com&#34;</span>
</span></span></code></pre></div><p>Then verify that the email has been set:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-console" data-lang="console"><span class="line"><span class="cl"><span class="gp">$</span> git config --global user.email
</span></span><span class="line"><span class="cl"><span class="go">00000000+yourusername@users.noreply.github.com
</span></span></span></code></pre></div><p>Now your actual email will be hidden from Git commits that have been pushed from your machine as well as any Git operations on GitHub. Note that your email will still show up in older commits that were pushed before these changes.
However, this will still improve your privacy on GitHub going forward.</p>
]]></content:encoded></item></channel></rss>