306 lines
49 KiB
XML
306 lines
49 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
||
<?xml-stylesheet type="text/xsl" href="/simple-atom.xslt"?>
|
||
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US">
|
||
<title>joshua.seigler.net - technical</title>
|
||
<subtitle>Personal homepage of Joshua Seigler</subtitle>
|
||
<link href="https://joshua.seigler.net/feeds/technical.xml" rel="self" />
|
||
<link href="https://joshua.seigler.net/" />
|
||
<updated>2025-07-04T00:00:00Z</updated>
|
||
<id>https://joshua.seigler.net/</id>
|
||
<author>
|
||
<name></name>
|
||
</author>
|
||
<entry>
|
||
<title>FFmpeg audio cleanup</title>
|
||
<link href="https://joshua.seigler.net/posts/ffmpeg-audio-cleanup/" />
|
||
<updated>2025-06-26T00:00:00Z</updated>
|
||
<id>https://joshua.seigler.net/posts/ffmpeg-audio-cleanup/</id>
|
||
<content type="html"><p>I recently needed to process 20+ phone audio recordings. The files are mp3 recordings in stereo, made in an environment with echoes and noise from fans/heaters.</p>
|
||
<p>Although I could do it easily with <a href="https://tenacityaudio.org/" target="_blank" rel="noopener">Tenacity</a> I didn’t want to use a manual process, since it would take days. So I tried using FFmpeg filters and Bash scripting.</p>
|
||
<p>I found an FFmpeg filter called <a href="https://ffmpeg.org/ffmpeg-filters.html#compand" target="_blank" rel="noopener">compand</a> which lets you map an input decibel range to an output decibel range. I also used the <a href="https://ffmpeg.org/ffmpeg-filters.html#anlmdn" target="_blank" rel="noopener">anlmdn</a> filter to reduce noise, and the <a href="https://ffmpeg.org/ffmpeg-filters.html#highpass" target="_blank" rel="noopener">highpass</a> filter to help with clarity.</p>
|
||
<p>I ran into a couple gotchas.</p>
|
||
<ol>
|
||
<li><code>mpv</code> does something special for audio playback that prevents audio from clipping. <code>vlc</code> plays the file as it is.</li>
|
||
<li>Because the compressor has an attack and decay (which is necessary for things to sound good) it can cause clipping if the volume rises sharply. Applying a <code>delay</code> parameter with half the duration of the attack length fixed this.</li>
|
||
</ol>
|
||
<p>Here is the script:</p>
|
||
<p><code>process-audio.sh</code></p>
|
||
<pre class="language-bash"><code class="language-bash"><span class="token shebang important">#!/bin/bash</span>
|
||
<span class="token keyword">if</span> <span class="token punctuation">[</span> <span class="token string">"<span class="token variable">$#</span>"</span> <span class="token operator">==</span> <span class="token string">"0"</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">then</span>
|
||
<span class="token builtin class-name">echo</span> <span class="token string">"Error: no arguments provided."</span>
|
||
<span class="token builtin class-name">echo</span> <span class="token string">"Usage: <span class="token variable">$0</span> file1 file2 file3 ..."</span>
|
||
<span class="token builtin class-name">echo</span> <span class="token string">"or <span class="token variable">$0</span> *.ext"</span>
|
||
<span class="token builtin class-name">exit</span> <span class="token number">1</span>
|
||
<span class="token keyword">fi</span>
|
||
|
||
<span class="token builtin class-name">trap</span> <span class="token string">"exit"</span> INT
|
||
|
||
<span class="token keyword">while</span> <span class="token punctuation">[</span> <span class="token string">"<span class="token variable">$#</span>"</span> <span class="token operator">!=</span> <span class="token string">"0"</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">do</span>
|
||
<span class="token assign-left variable">path</span><span class="token operator">=</span><span class="token string">"<span class="token variable">${1<span class="token operator">%</span><span class="token operator">/</span>*}</span>"</span>
|
||
<span class="token assign-left variable">file</span><span class="token operator">=</span><span class="token string">"<span class="token variable">${1<span class="token operator">##</span>*<span class="token operator">/</span>}</span>"</span>
|
||
<span class="token assign-left variable">outfile</span><span class="token operator">=</span><span class="token string">"./normalized--<span class="token variable">$file</span>"</span>
|
||
<span class="token keyword">if</span> <span class="token punctuation">[</span> <span class="token operator">!</span> <span class="token parameter variable">-f</span> <span class="token string">"<span class="token variable">$outfile</span>"</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">then</span>
|
||
<span class="token builtin class-name">echo</span> <span class="token string">"Processing <span class="token variable">$1</span>"</span>
|
||
ffmpeg <span class="token parameter variable">-i</span> <span class="token string">"<span class="token variable">$1</span>"</span> <span class="token parameter variable">-v</span> warning <span class="token parameter variable">-ac</span> <span class="token number">1</span> <span class="token parameter variable">-af</span> <span class="token string">"compand=attacks=0.3:decays=0.3:delay=0.15:points=-80/-300|-45/-25|-27/-15|0/-12|20/-12,anlmdn=s=10,highpass=f=500"</span> <span class="token parameter variable">-threads</span> <span class="token number">4</span> <span class="token string">"<span class="token variable">$outfile</span>"</span>
|
||
<span class="token keyword">else</span>
|
||
<span class="token builtin class-name">echo</span> <span class="token string">"Skipping <span class="token variable">$1</span>, already processed."</span>
|
||
<span class="token keyword">fi</span>
|
||
<span class="token builtin class-name">shift</span>
|
||
<span class="token keyword">done</span>
|
||
</code></pre>
|
||
<p>If this is useful to you please leave a comment or send an email, I would love to hear about it.</p>
|
||
</content>
|
||
</entry>
|
||
<entry>
|
||
<title>My Very Own GitHub Pages</title>
|
||
<link href="https://joshua.seigler.net/posts/my-very-own-github-pages/" />
|
||
<updated>2025-06-15T00:00:00Z</updated>
|
||
<id>https://joshua.seigler.net/posts/my-very-own-github-pages/</id>
|
||
<content type="html"><p>I recently started self-hosting <a href="https://forgejo.org/" target="_blank" rel="noopener">Forgejo</a>, but I wanted something to replace GitHub pages, which has been very convenient for publishing little website projects. My server runs Debian, so I decided to use <a href="https://github.com/adnanh/webhook" target="_blank" rel="noopener">webhook</a> and <a href="https://caddyserver.com/" target="_blank" rel="noopener">Caddy</a>. I’m very happy how it turned out.</p>
|
||
<h2 id="the-objective" tabindex="-1"><a class="header-anchor" href="https://joshua.seigler.net/posts/my-very-own-github-pages/#the-objective" aria-hidden="true"></a> The objective</h2>
|
||
<p>When I push a <code>gh-pages</code> branch to any public repository on my Forgejo instance, the name of the repo is used as a domain name (e.g. <a href="https://marklink.pages.seigler.net/" target="_blank" rel="noopener">marklink.pages.seigler.net</a>) and the branch contents are automatically served with SSL. If I push updates to the branch, they are automatically published. If the branch or repo is deleted, the site is taken down.</p>
|
||
<h2 id="how-to-do-it" tabindex="-1"><a class="header-anchor" href="https://joshua.seigler.net/posts/my-very-own-github-pages/#how-to-do-it" aria-hidden="true"></a> How to do it</h2>
|
||
<h3 id="debian-server-preparation" tabindex="-1"><a class="header-anchor" href="https://joshua.seigler.net/posts/my-very-own-github-pages/#debian-server-preparation" aria-hidden="true"></a> Debian server preparation</h3>
|
||
<p>In case you don’t have a basic server setup routine yet, this is a good start:</p>
|
||
<ul>
|
||
<li>Change the default root password.</li>
|
||
<li>Create a new user and add it to the sudo group. In my examples below the user is <code>joshua</code>.</li>
|
||
<li>Use <code>ssh-copy-id</code> to install your ssl pubkey for easier login.</li>
|
||
<li>Disable/lock root’s password.</li>
|
||
<li>Disable root login over ssh and change the SSL port number. Pick a new port lower than 1024.</li>
|
||
<li>Edit your local <code>~/.ssh/config</code> so you don’t have to specify the port number every time you connect.</li>
|
||
<li>On the server, install and enable <code>ufw</code> and <code>fail2ban</code>. In addition to allowing your custom SSL port, be sure to enable ports 80 and 443 with <code>sudo ufw allow &quot;WWW Full&quot;</code>.</li>
|
||
</ul>
|
||
<h3 id="caddy" tabindex="-1"><a class="header-anchor" href="https://joshua.seigler.net/posts/my-very-own-github-pages/#caddy" aria-hidden="true"></a> Caddy</h3>
|
||
<p>I usually use nginx, but I wanted to give Caddy a shot, and it has been a great experience. I installed Caddy using the <a href="https://caddyserver.com/docs/install" target="_blank" rel="noopener">official instructions</a>.<br>
|
||
Here is the Caddyfile I made—you will need to change the domain names and the email. Email could be removed, but it is there so that SSL certificate issuers can contact you if there is a problem with your certificates.</p>
|
||
<p><code>/etc/caddy/Caddyfile</code></p>
|
||
<pre class="language-caddy"><code class="language-caddy"># Global options block
|
||
{
|
||
email you@example.com # &lt;&lt;&lt;&lt; CHANGE THIS &lt;&lt;&lt;&lt;
|
||
on_demand_tls {
|
||
ask http://localhost/check
|
||
}
|
||
}
|
||
|
||
# Webhooks
|
||
https://webhooks.subdomain.here.tld { &lt;&lt;&lt;&lt; CHANGE THIS &lt;&lt;&lt;&lt;
|
||
reverse_proxy localhost:9000
|
||
}
|
||
|
||
# Filter for which SSL certs we will create. Prevents abuse.
|
||
http://localhost {
|
||
handle /check {
|
||
root * /var/www
|
||
@deny not file /{query.domain}/
|
||
respond @deny 404
|
||
}
|
||
}
|
||
|
||
# This automatically handles upgrading http:// requests with a redirect
|
||
https:// {
|
||
tls {
|
||
on_demand
|
||
}
|
||
root /var/www
|
||
rewrite /{host}{uri}
|
||
@forbidden {
|
||
path /.*
|
||
}
|
||
respond @forbidden 404
|
||
file_server
|
||
}
|
||
|
||
# Refer to the Caddy docs for more information:
|
||
# https://caddyserver.com/docs/caddyfile
|
||
|
||
# This config based on information at
|
||
# https://caddy.community/t/on-demand-tls-with-dynamic-content-paths/18140
|
||
# checked and corrected with `caddy validate`
|
||
</code></pre>
|
||
<p>I also took ownership of <code>/var/www</code> with <code>chown -R joshua:joshua /var/www</code> since the webhooks will run as my login account.</p>
|
||
<h3 id="webhooks" tabindex="-1"><a class="header-anchor" href="https://joshua.seigler.net/posts/my-very-own-github-pages/#webhooks" aria-hidden="true"></a> Webhooks</h3>
|
||
<p>In my home directory I defined two hook scripts:</p>
|
||
<p><code>~/webhooks/update-pages.sh</code></p>
|
||
<pre class="language-bash"><code class="language-bash"><span class="token shebang important">#!/bin/bash</span>
|
||
<span class="token comment"># parameter 1 is repo name, parameter 2 is clone url</span>
|
||
<span class="token punctuation">[</span><span class="token punctuation">[</span> <span class="token string">"<span class="token variable">$1</span>"</span> <span class="token operator">==</span> *<span class="token string">"/"</span>* <span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token operator">&amp;&amp;</span> <span class="token builtin class-name">exit</span> <span class="token number">1</span><span class="token punctuation">;</span>
|
||
<span class="token punctuation">[</span><span class="token punctuation">[</span> <span class="token string">"<span class="token variable">$1</span>"</span> <span class="token operator">==</span> *<span class="token string">".."</span>* <span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token operator">&amp;&amp;</span> <span class="token builtin class-name">exit</span> <span class="token number">1</span><span class="token punctuation">;</span>
|
||
<span class="token punctuation">[</span><span class="token punctuation">[</span> <span class="token string">"<span class="token variable">$1</span>"</span> <span class="token operator">==</span> *<span class="token string">"*"</span>* <span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token operator">&amp;&amp;</span> <span class="token builtin class-name">exit</span> <span class="token number">1</span><span class="token punctuation">;</span>
|
||
<span class="token keyword">if</span> <span class="token punctuation">[</span> <span class="token parameter variable">-d</span> <span class="token string">"/var/www/<span class="token variable">$1</span>"</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">then</span>
|
||
<span class="token builtin class-name">cd</span> <span class="token string">"/var/www/<span class="token variable">$1</span>"</span><span class="token punctuation">;</span>
|
||
<span class="token function">git</span> fetch origin gh-pages<span class="token punctuation">;</span>
|
||
<span class="token function">git</span> reset <span class="token parameter variable">--hard</span> origin/gh-pages<span class="token punctuation">;</span>
|
||
<span class="token builtin class-name">exit</span><span class="token punctuation">;</span>
|
||
<span class="token keyword">fi</span><span class="token punctuation">;</span>
|
||
<span class="token function">git</span> clone <span class="token parameter variable">-b</span> gh-pages --single-branch <span class="token string">"<span class="token variable">$2</span>"</span> <span class="token string">"<span class="token variable">$1</span>"</span> <span class="token operator">||</span> <span class="token builtin class-name">exit</span> <span class="token number">1</span><span class="token punctuation">;</span>
|
||
</code></pre>
|
||
<p><code>~/webhooks/remove-pages.sh</code></p>
|
||
<pre class="language-bash"><code class="language-bash"><span class="token shebang important">#!/bin/bash</span>
|
||
<span class="token comment"># parameter 1 is repo name</span>
|
||
<span class="token punctuation">[</span><span class="token punctuation">[</span> <span class="token string">"<span class="token variable">$1</span>"</span> <span class="token operator">==</span> *<span class="token string">"/"</span>* <span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token operator">&amp;&amp;</span> <span class="token builtin class-name">exit</span> <span class="token number">1</span><span class="token punctuation">;</span>
|
||
<span class="token punctuation">[</span><span class="token punctuation">[</span> <span class="token string">"<span class="token variable">$1</span>"</span> <span class="token operator">==</span> *<span class="token string">".."</span>* <span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token operator">&amp;&amp;</span> <span class="token builtin class-name">exit</span> <span class="token number">1</span><span class="token punctuation">;</span>
|
||
<span class="token punctuation">[</span><span class="token punctuation">[</span> <span class="token string">"<span class="token variable">$1</span>"</span> <span class="token operator">==</span> *<span class="token string">"*"</span>* <span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token operator">&amp;&amp;</span> <span class="token builtin class-name">exit</span> <span class="token number">1</span><span class="token punctuation">;</span>
|
||
<span class="token punctuation">[</span> <span class="token parameter variable">-d</span> <span class="token string">"/var/www/<span class="token variable">$1</span>"</span> <span class="token punctuation">]</span> <span class="token operator">||</span> <span class="token builtin class-name">exit</span> <span class="token number">1</span><span class="token punctuation">;</span>
|
||
<span class="token builtin class-name">cd</span> <span class="token string">"/var/www"</span><span class="token punctuation">;</span>
|
||
<span class="token function">rm</span> <span class="token parameter variable">-rf</span> <span class="token string">"/var/www/<span class="token variable">$1</span>"</span><span class="token punctuation">;</span>
|
||
</code></pre>
|
||
<p>To trigger these hooks I am using <code>webhook</code> which is in the default Debian repository.</p>
|
||
<p>Here are the hook definitions: one for creating/updating a site, and one for deleting. You will need to generate one or two secret values that the server can use to know that the webhook is authorized to run. I used linux command <code>uuidgen -r</code> to create mine. Save these values so you can enter them in Forgejo later.</p>
|
||
<p>Also make sure to replace your execute-command lines with ones referencing your username and script paths.</p>
|
||
<p><code>/etc/webhook.conf</code></p>
|
||
<pre class="language-json"><code class="language-json"><span class="token punctuation">[</span>
|
||
<span class="token punctuation">{</span>
|
||
<span class="token property">"id"</span><span class="token operator">:</span> <span class="token string">"update-pages"</span><span class="token punctuation">,</span>
|
||
<span class="token property">"execute-command"</span><span class="token operator">:</span> <span class="token string">"/usr/bin/sudo"</span><span class="token punctuation">,</span>
|
||
<span class="token property">"pass-arguments-to-command"</span><span class="token operator">:</span>
|
||
<span class="token punctuation">[</span>
|
||
<span class="token punctuation">{</span> <span class="token property">"source"</span><span class="token operator">:</span> <span class="token string">"string"</span><span class="token punctuation">,</span> <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"-u"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
|
||
<span class="token punctuation">{</span> <span class="token property">"source"</span><span class="token operator">:</span> <span class="token string">"string"</span><span class="token punctuation">,</span> <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"joshua"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
|
||
<span class="token punctuation">{</span> <span class="token property">"source"</span><span class="token operator">:</span> <span class="token string">"string"</span><span class="token punctuation">,</span> <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"/home/joshua/webhooks/update-pages.sh"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
|
||
<span class="token punctuation">{</span> <span class="token property">"source"</span><span class="token operator">:</span> <span class="token string">"payload"</span><span class="token punctuation">,</span> <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"repository.name"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
|
||
<span class="token punctuation">{</span> <span class="token property">"source"</span><span class="token operator">:</span> <span class="token string">"payload"</span><span class="token punctuation">,</span> <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"repository.clone_url"</span> <span class="token punctuation">}</span>
|
||
<span class="token punctuation">]</span><span class="token punctuation">,</span>
|
||
<span class="token property">"trigger-rule"</span><span class="token operator">:</span>
|
||
<span class="token punctuation">{</span>
|
||
<span class="token property">"and"</span><span class="token operator">:</span>
|
||
<span class="token punctuation">[</span>
|
||
<span class="token punctuation">{</span>
|
||
<span class="token property">"match"</span><span class="token operator">:</span>
|
||
<span class="token punctuation">{</span>
|
||
<span class="token property">"type"</span><span class="token operator">:</span> <span class="token string">"payload-hmac-sha256"</span><span class="token punctuation">,</span>
|
||
<span class="token property">"secret"</span><span class="token operator">:</span> <span class="token string">"(omitted)"</span><span class="token punctuation">,</span>
|
||
<span class="token property">"parameter"</span><span class="token operator">:</span>
|
||
<span class="token punctuation">{</span>
|
||
<span class="token property">"source"</span><span class="token operator">:</span> <span class="token string">"header"</span><span class="token punctuation">,</span>
|
||
<span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"X-Forgejo-Signature"</span>
|
||
<span class="token punctuation">}</span>
|
||
<span class="token punctuation">}</span>
|
||
<span class="token punctuation">}</span><span class="token punctuation">,</span>
|
||
<span class="token punctuation">{</span>
|
||
<span class="token property">"match"</span><span class="token operator">:</span>
|
||
<span class="token punctuation">{</span>
|
||
<span class="token property">"type"</span><span class="token operator">:</span> <span class="token string">"value"</span><span class="token punctuation">,</span>
|
||
<span class="token property">"value"</span><span class="token operator">:</span> <span class="token string">"refs/heads/gh-pages"</span><span class="token punctuation">,</span>
|
||
<span class="token property">"parameter"</span><span class="token operator">:</span>
|
||
<span class="token punctuation">{</span>
|
||
<span class="token property">"source"</span><span class="token operator">:</span> <span class="token string">"payload"</span><span class="token punctuation">,</span>
|
||
<span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"ref"</span>
|
||
<span class="token punctuation">}</span>
|
||
<span class="token punctuation">}</span>
|
||
<span class="token punctuation">}</span>
|
||
<span class="token punctuation">]</span>
|
||
<span class="token punctuation">}</span>
|
||
<span class="token punctuation">}</span><span class="token punctuation">,</span>
|
||
<span class="token punctuation">{</span>
|
||
<span class="token property">"id"</span><span class="token operator">:</span> <span class="token string">"remove-pages"</span><span class="token punctuation">,</span>
|
||
<span class="token property">"execute-command"</span><span class="token operator">:</span> <span class="token string">"/usr/bin/sudo"</span><span class="token punctuation">,</span>
|
||
<span class="token property">"pass-arguments-to-command"</span><span class="token operator">:</span>
|
||
<span class="token punctuation">[</span>
|
||
<span class="token punctuation">{</span> <span class="token property">"source"</span><span class="token operator">:</span> <span class="token string">"string"</span><span class="token punctuation">,</span> <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"-u"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
|
||
<span class="token punctuation">{</span> <span class="token property">"source"</span><span class="token operator">:</span> <span class="token string">"string"</span><span class="token punctuation">,</span> <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"joshua"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
|
||
<span class="token punctuation">{</span> <span class="token property">"source"</span><span class="token operator">:</span> <span class="token string">"string"</span><span class="token punctuation">,</span> <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"/home/joshua/webhooks/remove-pages.sh"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
|
||
<span class="token punctuation">{</span> <span class="token property">"source"</span><span class="token operator">:</span> <span class="token string">"payload"</span><span class="token punctuation">,</span> <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"repository.name"</span> <span class="token punctuation">}</span>
|
||
<span class="token punctuation">]</span><span class="token punctuation">,</span>
|
||
<span class="token property">"trigger-rule"</span><span class="token operator">:</span>
|
||
<span class="token punctuation">{</span>
|
||
<span class="token property">"and"</span><span class="token operator">:</span>
|
||
<span class="token punctuation">[</span>
|
||
<span class="token punctuation">{</span>
|
||
<span class="token property">"match"</span><span class="token operator">:</span>
|
||
<span class="token punctuation">{</span>
|
||
<span class="token property">"type"</span><span class="token operator">:</span> <span class="token string">"payload-hmac-sha256"</span><span class="token punctuation">,</span>
|
||
<span class="token property">"secret"</span><span class="token operator">:</span> <span class="token string">"(omitted)"</span><span class="token punctuation">,</span>
|
||
<span class="token property">"parameter"</span><span class="token operator">:</span>
|
||
<span class="token punctuation">{</span>
|
||
<span class="token property">"source"</span><span class="token operator">:</span> <span class="token string">"header"</span><span class="token punctuation">,</span>
|
||
<span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"X-Forgejo-Signature"</span>
|
||
<span class="token punctuation">}</span>
|
||
<span class="token punctuation">}</span>
|
||
<span class="token punctuation">}</span>
|
||
<span class="token punctuation">]</span>
|
||
<span class="token punctuation">}</span>
|
||
<span class="token punctuation">}</span>
|
||
<span class="token punctuation">]</span>
|
||
</code></pre>
|
||
<h3 id="forgejo" tabindex="-1"><a class="header-anchor" href="https://joshua.seigler.net/posts/my-very-own-github-pages/#forgejo" aria-hidden="true"></a> Forgejo</h3>
|
||
<p>Forgejo supports running webhooks conditionally triggered by certain conditions.<br>
|
||
Under my main user settings I set up each webhook:</p>
|
||
<h4 id="update-pages" tabindex="-1"><a class="header-anchor" href="https://joshua.seigler.net/posts/my-very-own-github-pages/#update-pages" aria-hidden="true"></a> Update pages</h4>
|
||
<p>Target URL: https:// <em>your domain here</em> /hooks/update-pages<br>
|
||
HTTP Method: <code>POST</code> (the default)<br>
|
||
POST content type: <code>application/json</code> (the default)<br>
|
||
Secret: <em>omitted, use your own</em><br>
|
||
Trigger on: Push events<br>
|
||
Branch filter: <code>gh-pages</code></p>
|
||
<h4 id="remove-pages" tabindex="-1"><a class="header-anchor" href="https://joshua.seigler.net/posts/my-very-own-github-pages/#remove-pages" aria-hidden="true"></a> Remove pages</h4>
|
||
<p>Target URL: https:// <em>your domain here</em> /hooks/remove-pages<br>
|
||
HTTP Method: <code>POST</code> (the default)<br>
|
||
POST content type: <code>application/json</code> (the default)<br>
|
||
Secret: <em>omitted, use your own</em><br>
|
||
Trigger on: Custom Events &gt; Repository &gt; Delete<br>
|
||
Branch filter: <code>gh-pages</code></p>
|
||
<h2 id="conclusion" tabindex="-1"><a class="header-anchor" href="https://joshua.seigler.net/posts/my-very-own-github-pages/#conclusion" aria-hidden="true"></a> Conclusion</h2>
|
||
<p>It works!<br>
|
||
Here is <a href="https://git.apps.seigler.net/joshua/marklink.pages.seigler.net" target="_blank" rel="noopener">the marklink repo in my Forgejo instance</a> and <a href="https://marklink.pages.seigler.net/" target="_blank" rel="noopener">its contents on my Caddy server</a>.</p>
|
||
<p>That repo is just HTML and JS with only a gh-pages branch, but for repos with npm build scripts, I use <a href="https://www.npmjs.com/package/gh-pages" target="_blank" rel="noopener">gh-pages @ npm</a> to push the build to a gh-pages branch and up to the server.</p>
|
||
<p>I’m putting off rolling my own CI server, but I imagine that’s the next stage here. Stay tuned.</p>
|
||
</content>
|
||
</entry>
|
||
<entry>
|
||
<title>Tools of the trade</title>
|
||
<link href="https://joshua.seigler.net/posts/tools-of-the-trade/" />
|
||
<updated>2025-05-15T00:00:00Z</updated>
|
||
<id>https://joshua.seigler.net/posts/tools-of-the-trade/</id>
|
||
<content type="html"><p>Everyone has different tools that they find especially effective. Here are some I have found with a few words about why I like them.</p>
|
||
<blockquote>
|
||
<p>Update: I made a <a href="https://joshua.seigler.net/uses">/uses</a> page that lists these tools and many others I like.</p>
|
||
</blockquote>
|
||
<h3 id="mise-en-place" tabindex="-1"><a class="header-anchor" href="https://joshua.seigler.net/posts/tools-of-the-trade/#mise-en-place" aria-hidden="true"></a> <a href="https://mise.jdx.dev/" target="_blank" rel="noopener">mise-en-place</a></h3>
|
||
<p>Universal dev tool version manager. Specify tool versions in a config file and this tool can ensure that they are installed and active when entering the project directory. Amazing for getting a new dev environment set up in seconds. Replaces <code>asdf</code>, <code>nvm</code>, <code>pyenv</code>, <code>venv</code>, <code>rbenv</code>, and many other tool-specific version managers. Supports an incredible number of tools thanks to compatibility with <code>asdf</code>.</p>
|
||
<p>It also supports installing specific global tools, like <code>angular-cli</code> from <code>npm</code>, or <code>stack-pr</code> from <code>pipx</code>.</p>
|
||
<h3 id="stack-pr" tabindex="-1"><a class="header-anchor" href="https://joshua.seigler.net/posts/tools-of-the-trade/#stack-pr" aria-hidden="true"></a> <a href="https://github.com/modular/stack-pr" target="_blank" rel="noopener">stack-pr</a></h3>
|
||
<p>Open source tool for <a href="https://www.stacking.dev/" target="_blank" rel="noopener">stacking PRs</a>.</p>
|
||
<p>PR stacks are, as far as I can tell, the best way to manage large features in git. I first heard about this practice in a series of blog posts from Graphite, a company offering free PR-stacking software and related paid services. But you don’t need a custom CI flow or managed service for stacking to work - this CLI tool or one of the others at <a href="https://www.stacking.dev/" target="_blank" rel="noopener">stacking.dev</a> can take care of this.</p>
|
||
<p>If you start using PR stacks your whole company will start copying you.</p>
|
||
<h3 id="xc" tabindex="-1"><a class="header-anchor" href="https://joshua.seigler.net/posts/tools-of-the-trade/#xc" aria-hidden="true"></a> <a href="https://xcfile.dev/" target="_blank" rel="noopener">xc</a></h3>
|
||
<p>Markdown based task runner.</p>
|
||
<p>Define tasks in code blocks in markdown, and call them from the CLI. Serves as both task definition and documentation.</p>
|
||
<h3 id="pd2slack" tabindex="-1"><a class="header-anchor" href="https://joshua.seigler.net/posts/tools-of-the-trade/#pd2slack" aria-hidden="true"></a> <a href="https://github.com/sidpremkumar/pd2slack" target="_blank" rel="noopener">pd2slack</a></h3>
|
||
<p>Simple python script to update the members of a Slack group such as <code>@oncall</code> to match the active member(s) of a PagerDuty schedule. This replaces several expensive SAAS services.</p>
|
||
<h3 id="syncthing" tabindex="-1"><a class="header-anchor" href="https://joshua.seigler.net/posts/tools-of-the-trade/#syncthing" aria-hidden="true"></a> <a href="https://syncthing.net/" target="_blank" rel="noopener">SyncThing</a></h3>
|
||
<p>P2P alternative to Dropbox, supports mobile and desktop. Synchronize folders of content across all my devices.</p>
|
||
<h3 id="obsidian" tabindex="-1"><a class="header-anchor" href="https://joshua.seigler.net/posts/tools-of-the-trade/#obsidian" aria-hidden="true"></a> <a href="https://obsidian.md/" target="_blank" rel="noopener">Obsidian</a></h3>
|
||
<p>For notes and reference. Sync across devices with <code>syncthing</code>.</p>
|
||
<h3 id="keepassxc" tabindex="-1"><a class="header-anchor" href="https://joshua.seigler.net/posts/tools-of-the-trade/#keepassxc" aria-hidden="true"></a> <a href="https://keepassxc.org/" target="_blank" rel="noopener">KeePassXC</a></h3>
|
||
<p>For passwords. Sync across devices with <code>syncthing</code>.</p>
|
||
</content>
|
||
</entry>
|
||
<entry>
|
||
<title>Site design updated</title>
|
||
<link href="https://joshua.seigler.net/posts/site-design-updated/" />
|
||
<updated>2024-06-05T00:00:00Z</updated>
|
||
<id>https://joshua.seigler.net/posts/site-design-updated/</id>
|
||
<content type="html"><style>@import url('/fonts/ftaurebesh/ftaurebesh.css');</style>
|
||
<p>New design! The tools I used before have a lot of unmaintained or outdated dependencies and I wanted something a little simpler. The new site uses <a href="https://pnpm.io/" target="_blank" rel="noopener">pnpm</a>, <a href="https://www.11ty.dev/" target="_blank" rel="noopener">11ty</a>, and <a href="https://mozilla.github.io/nunjucks/" target="_blank" rel="noopener">Nunjucks</a>. Content is still in <a href="https://daringfireball.net/projects/markdown/" target="_blank" rel="noopener">markdown</a>.</p>
|
||
<p>One thing I’m proud of is a visual ping for footnotes.<sup class="footnote-ref"><a href="https://joshua.seigler.net/posts/site-design-updated/#footnote1">[1]</a><a class="footnote-anchor" id="footnote-ref1"></a></sup> When you click a footnote<sup class="footnote-ref"><a href="https://joshua.seigler.net/posts/site-design-updated/#footnote2">[2]</a><a class="footnote-anchor" id="footnote-ref2"></a></sup> it briefly highlights the thing you jumped to.</p>
|
||
<p>In the upper right I added a style toggle that applies the font from Star Wars, “Aurebesh”. I learned how to read it but sometimes want some practice. <span data-language="aurebesh">People who can read this are cool and I like them.</span></p>
|
||
<p>I also finally made a section for recipes!</p>
|
||
<blockquote>
|
||
<p>May 2025 edit: I updated the design some more without changing the tech stack. The main improvements are animated clouds and a host of minor adjustments.</p>
|
||
</blockquote>
|
||
<blockquote>
|
||
<p>June 2025 edit: I have continued to alter the design. Pray I don’t alter it any further.</p>
|
||
</blockquote>
|
||
<hr class="footnotes-sep">
|
||
<section class="footnotes">
|
||
<ol class="footnotes-list">
|
||
<li id="footnote1" class="footnote-item"><p>It highlights when you click back, too. <a href="https://joshua.seigler.net/posts/site-design-updated/#footnote-ref1" class="footnote-backref">↩︎</a></p>
|
||
</li>
|
||
<li id="footnote2" class="footnote-item"><p>Hi. <a href="https://joshua.seigler.net/posts/site-design-updated/#footnote-ref2" class="footnote-backref">↩︎</a></p>
|
||
</li>
|
||
</ol>
|
||
</section>
|
||
</content>
|
||
</entry>
|
||
</feed>
|