<?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-Actions on Londopy</title><link>https://londopy.github.io/blog/tags/github-actions/</link><description>Recent content in Github-Actions on Londopy</description><image><title>Londopy</title><url>https://londopy.github.io/blog/og-image.png</url><link>https://londopy.github.io/blog/og-image.png</link></image><generator>Hugo</generator><language>en-us</language><copyright>2026 Londopy · Posts CC BY 4.0 · Code MIT</copyright><lastBuildDate>Thu, 24 Sep 2026 01:52:31 -0700</lastBuildDate><atom:link href="https://londopy.github.io/blog/tags/github-actions/index.xml" rel="self" type="application/rss+xml"/><item><title>Things GitHub Actions Can Do That Aren't CI</title><link>https://londopy.github.io/blog/posts/github-actions-beyond-ci/</link><pubDate>Thu, 22 Oct 2026 09:00:00 -0700</pubDate><guid>https://londopy.github.io/blog/posts/github-actions-beyond-ci/</guid><description>GitHub Actions is a free, event-driven computer attached to every repo. Running tests is just the start.</description><content:encoded><![CDATA[<p>Most people meet GitHub Actions as &ldquo;the thing that runs tests on pull requests.&rdquo; But under the hood it&rsquo;s much more general: a computer that wakes up when something happens, runs whatever you tell it, and goes back to sleep. For public repos, it&rsquo;s free.</p>
<p>Here are things you can do with it that have nothing to do with CI.</p>
<h2 id="how-it-works-in-30-seconds">How it works in 30 seconds</h2>
<p>A workflow is a YAML file in <code>.github/workflows/</code>. It has:</p>
<ul>
<li><strong>triggers</strong> (<code>on:</code>): a push, a new issue, a schedule, a button click</li>
<li><strong>jobs</strong> that run on a fresh virtual machine</li>
<li><strong>steps</strong>, each either a shell command or a reusable action</li>
</ul>
<p>That&rsquo;s it. Anything you can script, you can trigger.</p>
<h2 id="1-host-a-website">1. Host a website</h2>
<p>This blog is built by Actions. Every push to <code>main</code> builds the site with Hugo and publishes it to GitHub Pages. No server, no bill.</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">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 class="p">[</span><span class="l">main]</span><span class="w">
</span></span></span></code></pre></div><p>The official <code>actions/upload-pages-artifact</code> and <code>actions/deploy-pages</code> actions do the publishing.</p>
<h2 id="2-run-things-on-a-schedule">2. Run things on a schedule</h2>
<p>Actions supports cron:</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">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">schedule</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">cron</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;0 14 * * 1&#34;</span><span class="w">   </span><span class="c"># every Monday at 14:00 UTC</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">workflow_dispatch</span><span class="p">:</span><span class="w">        </span><span class="c"># plus a manual &#34;Run&#34; button</span><span class="w">
</span></span></span></code></pre></div><p>Uses: nightly data scrapes, weekly reports, checking whether a website is up, rebuilding a site so &ldquo;posted 3 days ago&rdquo; stays accurate.</p>
<p><strong>Know this:</strong></p>
<ul>
<li>Times are in <strong>UTC</strong>.</li>
<li>Scheduled runs can start late when GitHub is busy, sometimes by many minutes. Don&rsquo;t use it for anything that must happen at an exact second.</li>
<li>In public repos, scheduled workflows are <strong>automatically disabled after 60 days without repository activity</strong>. GitHub emails you first.</li>
</ul>
<h2 id="3-keep-a-file-updated-automatically">3. Keep a file updated automatically</h2>
<p>A workflow can edit files and commit them back. For example, a profile README that always lists your latest blog posts:</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">permissions</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">contents</span><span class="p">:</span><span class="w"> </span><span class="l">write</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">update</span><span class="p">:</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@v7</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="l">./scripts/update-readme.sh</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">          git config user.name &#34;github-actions[bot]&#34;
</span></span></span><span class="line"><span class="cl"><span class="sd">          git config user.email &#34;41898282+github-actions[bot]@users.noreply.github.com&#34;
</span></span></span><span class="line"><span class="cl"><span class="sd">          git add README.md
</span></span></span><span class="line"><span class="cl"><span class="sd">          git diff --cached --quiet || git commit -m &#34;Update latest posts&#34;
</span></span></span><span class="line"><span class="cl"><span class="sd">          git push</span><span class="w">
</span></span></span></code></pre></div><p>The <code>git diff --cached --quiet ||</code> part only commits if something actually changed, so you don&rsquo;t get empty commits.</p>
<h2 id="4-manage-issues-and-pull-requests">4. Manage issues and pull requests</h2>
<ul>
<li><strong>Auto-label</strong> PRs by which files they touch (<code>actions/labeler</code>).</li>
<li><strong>Welcome first-time contributors</strong> with a friendly comment.</li>
<li><strong>Close stale issues</strong> after a period of inactivity (<code>actions/stale</code>). Use gently; closing people&rsquo;s issues automatically can feel rude.</li>
<li><strong>Enforce PR title formats</strong> for changelogs.</li>
</ul>
<p>Triggers like <code>issues</code>, <code>issue_comment</code>, and <code>pull_request</code> make this easy.</p>
<h2 id="5-build-a-chatops-bot">5. Build a ChatOps bot</h2>
<p>A workflow can react to comments. Someone types <code>/deploy staging</code> on a PR, and a workflow checks their permissions and runs the deploy. Check the comment author&rsquo;s permission level before doing anything, or anyone on the internet can trigger it.</p>
<h2 id="6-watch-other-things-on-the-internet">6. Watch other things on the internet</h2>
<p>A scheduled job can:</p>
<ul>
<li>check whether your site returns 200 and open an issue if not</li>
<li>check whether a dependency released a new version</li>
<li>watch a page for changes and notify you</li>
</ul>
<p>GitHub isn&rsquo;t built for real-time monitoring, but for &ldquo;check once an hour and tell me,&rdquo; it&rsquo;s plenty.</p>
<h2 id="7-trigger-workflows-from-outside-github">7. Trigger workflows from outside GitHub</h2>
<p>With <code>repository_dispatch</code>, anything that can send an HTTP request with a GitHub token can start a workflow: a script on your server, a webhook from another service, a phone shortcut. The token needs write access to the repo, so treat it like a password.</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">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">repository_dispatch</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">types</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">rebuild-site]</span><span class="w">
</span></span></span></code></pre></div><h2 id="8-generate-release-artifacts">8. Generate release artifacts</h2>
<p>Build binaries for Windows, macOS, and Linux in parallel with a matrix, then attach them to a GitHub Release automatically when you push a version tag.</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">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">tags</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;v*&#34;</span><span class="p">]</span><span class="w">
</span></span></span></code></pre></div><h2 id="things-you-should-know">Things you should know</h2>
<p><strong>Least privilege.</strong> Set <code>permissions:</code> explicitly in every workflow. Give each workflow only what it needs.</p>
<p><strong>Secrets and forks.</strong> Workflows triggered by pull requests from forks don&rsquo;t get your secrets, on purpose. Be very careful with the <code>pull_request_target</code> trigger: it runs with your secrets and write permissions, and if it checks out and runs the fork&rsquo;s code, a stranger&rsquo;s PR can steal your secrets.</p>
<p><strong>Pin actions.</strong> A third-party action is someone else&rsquo;s code running with your permissions. Pin it to a full commit hash rather than a tag if you don&rsquo;t fully trust the author:</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">uses</span><span class="p">:</span><span class="w"> </span><span class="l">some-author/some-action@8f4b7f84864484a7bf31766abe9204da3cbe65b3</span><span class="w">
</span></span></span></code></pre></div><p><strong>Free isn&rsquo;t unlimited.</strong> Public repos get free minutes on standard runners. Private repos get a monthly allowance, then usage is billed. Check the current limits before you build something heavy.</p>
<h2 id="closing-thought">Closing thought</h2>
<p>Think of every repo as coming with a small, free, scriptable computer that listens for events. CI is one thing you can do with it. Your imagination and the terms of service are the rest.</p>
]]></content:encoded></item></channel></rss>