<?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: christine</title>
    <description>The latest articles on DEV Community by christine (@cseeman).</description>
    <link>https://dev.to/cseeman</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%2F77243%2F5dbbe7a7-3411-4644-b415-cc14b80d7fbc.jpg</url>
      <title>DEV Community: christine</title>
      <link>https://dev.to/cseeman</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cseeman"/>
    <language>en</language>
    <item>
      <title>A Simple Tmux Script for Your Daily Dev Session</title>
      <dc:creator>christine</dc:creator>
      <pubDate>Mon, 06 Apr 2026 21:31:09 +0000</pubDate>
      <link>https://dev.to/cseeman/a-simple-tmux-script-for-your-daily-dev-session-2bjb</link>
      <guid>https://dev.to/cseeman/a-simple-tmux-script-for-your-daily-dev-session-2bjb</guid>
      <description>&lt;p&gt;A couple of years ago I wrote about &lt;a href="https://dev.to/cseeman/how-to-copy-text-from-one-pane-macostmuxalacritty-2ll0"&gt;copying text between tmux panes&lt;/a&gt;. At the time I was still figuring out how all the pieces of my terminal setup fit together (a recurring theme, honestly). Since then, tmux has become the first thing I open every morning. I wrote a small bash script that sets up my dev session, and I've tweaked it enough times that I thought it was worth sharing where it ended up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where I Started
&lt;/h2&gt;

&lt;p&gt;My first version created a four-pane layout:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+------------------+------------------+
| nvim             | rails server     |
+------------------+------------------+
| lazygit          | claude           |
+------------------+------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neovim for editing, Rails server running &lt;code&gt;bin/dev&lt;/code&gt; (which kicks off Overmind with the full Procfile.dev), lazygit for staging and committing, and Claude Code for when I need a second brain. It felt very productive to look at. Four panes! Everything visible! I am a real developer!&lt;/p&gt;

&lt;p&gt;And then I actually used it for a while. The Rails server pane just... sat there, taking up screen real estate while I was writing code that didn't need a running server. Lazygit is great, but I reach for &lt;code&gt;git status&lt;/code&gt; and &lt;code&gt;git diff&lt;/code&gt; in a regular shell just as often. And four panes on a laptop screen? Everything is tiny.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where I Landed
&lt;/h2&gt;

&lt;p&gt;Two panes. A shell on the left, Claude Code on the right.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+------------------+------------------+
| shell            | claude           |
+------------------+------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The shell handles whatever I need in the moment: editing, git, spinning up the server, running tests. Turns out I don't need a dedicated pane for each tool. I just need a place to work and a place to think out loud.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Script
&lt;/h2&gt;

&lt;p&gt;The full script is in my &lt;a href="https://github.com/cseeman/dotfiles/tree/main/dev-scripts" rel="noopener noreferrer"&gt;dotfiles&lt;/a&gt;, but here's what it does:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="c"&gt;# Universal Development Session Script&lt;/span&gt;
&lt;span class="c"&gt;# Creates a 2-pane tmux layout for any Rails project or worktree&lt;/span&gt;
&lt;span class="c"&gt;# Usage: ./dev-session [session-name] [directory]&lt;/span&gt;

&lt;span class="c"&gt;# Configuration&lt;/span&gt;
&lt;span class="nv"&gt;DEFAULT_EDITOR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"nvim"&lt;/span&gt;
&lt;span class="nv"&gt;DEFAULT_PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"3000"&lt;/span&gt;

get_current_dir&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;pwd&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

get_project_name&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;basename&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;get_current_dir&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

get_branch_name&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;git rev-parse &lt;span class="nt"&gt;--git-dir&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null 2&amp;gt;&amp;amp;1&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;git branch &lt;span class="nt"&gt;--show-current&lt;/span&gt; 2&amp;gt;/dev/null &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"main"&lt;/span&gt;
    &lt;span class="k"&gt;else
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"no-git"&lt;/span&gt;
    &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

generate_session_name&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;project_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;get_project_name&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;branch_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;get_branch_name&lt;span class="si"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$branch_name&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s2"&gt;"main"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$branch_name&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s2"&gt;"develop"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$branch_name&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s2"&gt;"no-git"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nv"&gt;safe_branch&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$branch_name&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/[\/:]/-/g'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;project_name&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;safe_branch&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;else
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$project_name&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nv"&gt;SESSION_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;1&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;generate_session_name&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nv"&gt;WORK_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;2&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;get_current_dir&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$WORK_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Error: Directory &lt;/span&gt;&lt;span class="nv"&gt;$WORK_DIR&lt;/span&gt;&lt;span class="s2"&gt; does not exist"&lt;/span&gt;
    &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# Reattach if session already exists&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;tmux has-session &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SESSION_NAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; 2&amp;gt;/dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Session '&lt;/span&gt;&lt;span class="nv"&gt;$SESSION_NAME&lt;/span&gt;&lt;span class="s2"&gt;' already exists. Attaching..."&lt;/span&gt;
    tmux attach-session &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SESSION_NAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="nb"&gt;exit &lt;/span&gt;0
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# Create session and split into two panes&lt;/span&gt;
tmux new-session &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SESSION_NAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$WORK_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
tmux split-window &lt;span class="nt"&gt;-h&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$WORK_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# Left pane: shell, right pane: Claude Code&lt;/span&gt;
tmux send-keys &lt;span class="nt"&gt;-t&lt;/span&gt; 1 &lt;span class="s2"&gt;"# Ready for commands (server, etc.)"&lt;/span&gt; C-m
tmux send-keys &lt;span class="nt"&gt;-t&lt;/span&gt; 2 &lt;span class="s2"&gt;"claude"&lt;/span&gt; C-m

tmux &lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="nt"&gt;-pane&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; 1
tmux rename-window &lt;span class="s2"&gt;"dev"&lt;/span&gt;
tmux attach-session &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SESSION_NAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I alias it in my shell config so I can run &lt;code&gt;dev&lt;/code&gt; from any project directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;dev&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"~/Documents/Repos/dev-scripts/dev-session"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Parts I Actually Like
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;It names sessions from your git branch.&lt;/strong&gt; If I'm on &lt;code&gt;main&lt;/code&gt;, the session is just the project name (&lt;code&gt;qualify&lt;/code&gt;). On a feature branch, it tacks on the branch name (&lt;code&gt;qualify-fix-event-registry&lt;/code&gt;). Slashes in branch names get swapped to hyphens so tmux doesn't choke on them.&lt;/p&gt;

&lt;p&gt;This is my favorite part, because I usually have multiple sessions going at once, one per feature branch or worktree. &lt;code&gt;tmux list-sessions&lt;/code&gt; gives me a quick snapshot of what I've got cooking:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;qualify: 1 windows (created Thu Apr  3 09:15:00 2026)
qualify-add-snapshot-tests: 1 windows (created Thu Apr  3 10:30:00 2026)
rubygems: 1 windows (created Wed Apr  2 14:00:00 2026)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;It won't create duplicates.&lt;/strong&gt; If a session with that name already exists, the script just attaches to it. Detach with &lt;code&gt;Ctrl-b d&lt;/code&gt;, go make coffee, come back, run &lt;code&gt;dev&lt;/code&gt; again, and you're right where you left off. Sessions survive sleep/wake cycles too, which still feels like magic to me.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It works anywhere.&lt;/strong&gt; The script doesn't assume Rails or even git. I use it for this blog, for Ruby gems, for random one-off scripts. If there's a git repo, it uses the branch name. If not, you just get the directory name. No fuss.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Claude Code Pane
&lt;/h2&gt;

&lt;p&gt;The right pane launches &lt;a href="https://docs.anthropic.com/en/docs/claude-code/overview" rel="noopener noreferrer"&gt;Claude Code&lt;/a&gt; automatically. I like having it right there instead of in a separate terminal window. I can glance over at its output while I'm working, and &lt;code&gt;Ctrl-b z&lt;/code&gt; (tmux zoom) is my best friend here, blowing the Claude pane up to full screen when I'm reading a longer response and then popping back to the split.&lt;/p&gt;

&lt;p&gt;The other nice thing is that Claude Code's context stays warm. I can ask it something, go write code in the left pane for twenty minutes, come back and ask a follow-up without re-explaining everything. That alone is worth the dedicated pane.&lt;/p&gt;

&lt;h2&gt;
  
  
  Things I'd Change
&lt;/h2&gt;

&lt;p&gt;My &lt;code&gt;.tmux.conf&lt;/code&gt; is still embarrassingly minimal. It's literally just a scrollback buffer increase. The README in my dotfiles repo documents vim-style pane navigation bindings that I haven't actually configured yet. I will get to it. Eventually. (I tell myself this every week.)&lt;/p&gt;

&lt;p&gt;The four-pane version (&lt;code&gt;dev-session-fixed&lt;/code&gt;) is still sitting in the repo too. I keep it around for when I'm debugging something where I really do need server logs visible the whole time. But I haven't reached for it in weeks, which tells me something.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;Grab the script from &lt;a href="https://github.com/cseeman/dotfiles/tree/main/dev-scripts" rel="noopener noreferrer"&gt;my dotfiles&lt;/a&gt;, drop it somewhere in your path, and alias it. The only real dependency is tmux itself. If you don't have Claude Code installed, no worries, that pane just becomes a regular shell.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;your-project
dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. Two panes, named after your branch, ready to go.&lt;/p&gt;

</description>
      <category>tmux</category>
      <category>bash</category>
      <category>devtools</category>
    </item>
    <item>
      <title>How to Run a Virtual Lean Coffee for Your Meetup Community</title>
      <dc:creator>christine</dc:creator>
      <pubDate>Wed, 01 Apr 2026 23:45:12 +0000</pubDate>
      <link>https://dev.to/cseeman/how-to-run-a-virtual-lean-coffee-for-your-meetup-community-52n7</link>
      <guid>https://dev.to/cseeman/how-to-run-a-virtual-lean-coffee-for-your-meetup-community-52n7</guid>
      <description>&lt;p&gt;For the March &lt;a href="https://www.wnb-rb.dev/" rel="noopener noreferrer"&gt;WNB.rb&lt;/a&gt; meetup, I tried something different. Instead of our usual speaker format, I facilitated a Lean Coffee online, a structured but agenda-less discussion where attendees set the topics and vote on what to talk about. It went really well, and I wanted to share how it worked in case you're thinking about trying one yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Lean Coffee?
&lt;/h2&gt;

&lt;p&gt;Lean Coffee is a meeting format where there's no pre-set agenda. Participants propose topics at the start, vote on what interests them most, and then discuss in priority order with timeboxed rounds. When the timer runs out, the group votes to keep going or move on. Simple as that.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Setup: What We Used
&lt;/h2&gt;

&lt;p&gt;I used &lt;a href="https://www.leancoffeetable.com/" rel="noopener noreferrer"&gt;Lean Coffee Table&lt;/a&gt; for the board and Google Meet for video. Lean Coffee Table handles the topic cards, voting, timer, and topic flow, and participants don't need to create accounts. I pre-loaded some seed topics to get things started, pasted the Google Meet link into the board, and shared one link with attendees. That was it for setup.&lt;/p&gt;

&lt;p&gt;The seed topics were a mix: AI and how it's changing our work, Ruby and Rails in 2026, and some fun wildcards like "If you had to explain your job to a medieval peasant, what would you say?" I put the wildcards in as energy resets if things got heavy, but honestly the group gravitated toward topics that were practical and personal all on their own.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We Actually Talked About
&lt;/h2&gt;

&lt;p&gt;We had 17 attendees, and between the seed topics and what the group proposed, there was plenty to choose from. The three that got the most votes were:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"What makes good team work in software engineering?"&lt;/strong&gt; (6 votes) - This one got the most votes, and the conversation did not disappoint. Communication was the obvious starting point, but the group went way beyond that. We talked about shared troubleshooting, actually collaborating on problems together instead of tossing tickets over the wall, and giving gracious feedback, in and out of pull requests. The part that really stuck with me: connecting on a human level and meeting people how &lt;em&gt;they&lt;/em&gt; communicate, not just how you prefer to.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Where do you draw the line on what you let AI write vs. what you write yourself?"&lt;/strong&gt; (5 votes) - This one got lively. Someone summed it up perfectly: "AI makes it work, I make it right." Everyone agreed that everything feels different now, but the group was surprisingly practical about it. The big takeaway: if you don't understand the generated code, ditch it and write it yourself. Can't argue with that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"What's the best advice you've ever received?"&lt;/strong&gt; (5 votes) - OK, this one hit different. The group shared some real gems: "Know what you want, and know how to ask for it." "Done is better than perfect." Someone recommended the book &lt;em&gt;Burnout: The Secret to Unlocking the Stress Cycle&lt;/em&gt; (adding it to my list). "The most important project you manage is your life." And my personal favorite: "Would your 85 year old self be proud of you?" I'm still thinking about that one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Topics We Didn't Get To
&lt;/h2&gt;

&lt;p&gt;That's the thing about lean coffee: you won't get to everything, and that's fine. The voting means the stuff people care about most floats to the top. We had some great ones waiting in the wings: "If your codebase were a kitchen, what state is it in right now?", the medieval peasant question, onboarding strategies, and a few more AI topics. Definitely saving some of these for next time.&lt;/p&gt;

&lt;p&gt;One thing I found interesting: the more technical Ruby/Rails topics (Ruby 4.0's ZJIT, Hanami 2.3) got zero votes. People wanted to talk about the human side of building software. I think that says something about where everyone's heads are at right now.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Worked
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Lean Coffee Table + Google Meet was the right combo.&lt;/strong&gt; The tool handled voting and timers smoothly, and the auto-generated PDF summary at the end meant I didn't have to scramble to take notes during the session.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Seed topics helped, but didn't take over.&lt;/strong&gt; I pre-loaded a bunch of conversation starters so nobody had to stare at a blank board, but the group also came up with their own topics (onboarding strategies, interview processes, team belonging) that got just as many votes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Everyone had a voice.&lt;/strong&gt; The voting and timer mechanics naturally spread things out. No one person can dominate when the group decides what to discuss and when to move on. That matters a lot for a community like WNB.rb.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An hour was the right length.&lt;/strong&gt; Three topics in depth felt like the right pace. I'd rather go deep on fewer topics than rush through a bunch.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd Do Differently
&lt;/h2&gt;

&lt;p&gt;Next time I'd spend a little more time explaining the format upfront. A few folks hadn't done lean coffee before, and walking through the voting and timer mechanics at the start would have saved some confusion in the first few minutes.&lt;/p&gt;

&lt;p&gt;I'd also trim down the seed topics. I had a lot pre-loaded, and a shorter list might push people to come up with more of their own.&lt;/p&gt;

&lt;h2&gt;
  
  
  Would I Do It Again?
&lt;/h2&gt;

&lt;p&gt;In a heartbeat. Not every meetup needs a speaker and slides. Sometimes the best stuff comes from just giving people space to talk about what's actually on their minds. That's exactly what happened here, and I'd love to make this a regular thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Want to Run Your Own?
&lt;/h2&gt;

&lt;p&gt;If you're an organizer thinking about trying a virtual lean coffee for your community, here's the short version of what worked for us:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.leancoffeetable.com/" rel="noopener noreferrer"&gt;Lean Coffee Table&lt;/a&gt;&lt;/strong&gt; for the board, voting, and timer. Free, no accounts needed for participants, and it generates a PDF summary when you're done. Honestly this tool did most of the heavy lifting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google Meet&lt;/strong&gt; for video. Nothing fancy, just screen share the Lean Coffee Table board so everyone can follow along. Any video tool works here.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pre-load 8-10 seed topics&lt;/strong&gt; across a few categories so nobody stares at a blank board. But keep the list short enough that people feel encouraged to add their own.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;5-minute timer per topic&lt;/strong&gt;, with the group voting to extend or move on. Three topics in an hour felt right.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Share one link.&lt;/strong&gt; I pasted the Google Meet link into the Lean Coffee Table board and only shared the board link. One less thing for attendees to keep track of.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The voting and timers do a lot of the facilitation work for you, everyone gets a say in what gets discussed, and no single person can take over the conversation. If that sounds like your kind of meetup, give it a shot.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Note About WNB.rb
&lt;/h2&gt;

&lt;p&gt;Full disclosure: I'm on the &lt;a href="https://www.wnb-rb.dev/" rel="noopener noreferrer"&gt;WNB.rb&lt;/a&gt; board, so I'm obviously not unbiased here. But I genuinely think this is one of the best communities in the Ruby world. It's a welcoming, supportive space for women and non-binary Rubyists, and the people who show up every month are the reason I keep coming back.&lt;/p&gt;

&lt;p&gt;WNB.rb is officially a non-profit, and if you'd like to support what we're doing, you can find out more at &lt;a href="https://www.wnb-rb.dev/sponsor-us" rel="noopener noreferrer"&gt;wnb-rb.dev/sponsor-us&lt;/a&gt;. Every bit helps us keep the meetups running, support our speakers, and grow the community.&lt;/p&gt;

</description>
      <category>community</category>
      <category>meetup</category>
      <category>ruby</category>
    </item>
    <item>
      <title>Why Your GitHub Actions Secrets Don't Work in Reusable Workflow Inputs</title>
      <dc:creator>christine</dc:creator>
      <pubDate>Fri, 13 Feb 2026 19:04:40 +0000</pubDate>
      <link>https://dev.to/cseeman/why-your-github-actions-secrets-dont-work-in-reusable-workflow-inputs-462g</link>
      <guid>https://dev.to/cseeman/why-your-github-actions-secrets-dont-work-in-reusable-workflow-inputs-462g</guid>
      <description>&lt;p&gt;We recently migrated our Docker build workflows to use a shared &lt;a href="https://docs.github.com/en/actions/how-tos/reuse-automations/reuse-workflows" rel="noopener noreferrer"&gt;reusable workflow&lt;/a&gt;. The migration looked straightforward: extract the build steps, parameterize the inputs, and call the shared workflow with &lt;code&gt;secrets: inherit&lt;/code&gt;. CI immediately broke.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Invalid workflow file (Line: 15, Col: 19):
Unrecognized named-value: 'secrets'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The fix took 20 minutes. Understanding &lt;em&gt;why&lt;/em&gt; took longer, and every answer led to another "but wait" question.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Setup
&lt;/h2&gt;

&lt;p&gt;The calling workflow passed a Rails master key as a build arg:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;our-org/shared/.github/workflows/build-image.yml@main&lt;/span&gt;
    &lt;span class="na"&gt;secrets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;inherit&lt;/span&gt;
    &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;build_args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;RAILS_MASTER_KEY=${{ secrets.RAILS_MASTER_KEY }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This fails at parse time. GitHub validates the workflow file &lt;em&gt;before&lt;/em&gt; anything runs and rejects &lt;code&gt;secrets&lt;/code&gt; in that &lt;code&gt;with:&lt;/code&gt; block.&lt;/p&gt;

&lt;h2&gt;
  
  
  Job-Level &lt;code&gt;with:&lt;/code&gt; Is Not Step-Level &lt;code&gt;with:&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;This is where it gets confusing, because &lt;code&gt;with:&lt;/code&gt; appears in two very different places in a workflow file, and they have different rules.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step-level &lt;code&gt;with:&lt;/code&gt;&lt;/strong&gt; passes inputs to an action. The &lt;code&gt;secrets&lt;/code&gt; context is available here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker/build-push-action@v6&lt;/span&gt;
    &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;build-args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;RAILS_MASTER_KEY=${{ secrets.RAILS_MASTER_KEY }}&lt;/span&gt;  &lt;span class="c1"&gt;# works&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Job-level &lt;code&gt;with:&lt;/code&gt;&lt;/strong&gt; passes inputs to a reusable workflow. The &lt;code&gt;secrets&lt;/code&gt; context is &lt;em&gt;not&lt;/em&gt; available here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;org/repo/.github/workflows/shared.yml@main&lt;/span&gt;
    &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;build_args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.RAILS_MASTER_KEY }}&lt;/span&gt;  &lt;span class="c1"&gt;# fails&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://docs.github.com/en/actions/reference/workflows-and-actions/contexts" rel="noopener noreferrer"&gt;contexts reference&lt;/a&gt; documents this in a table. For &lt;code&gt;jobs.&amp;lt;job_id&amp;gt;.with.&amp;lt;with_id&amp;gt;&lt;/code&gt;, the allowed contexts are:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;github, needs, strategy, matrix, inputs, vars&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No &lt;code&gt;secrets&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  But the Docs Say Secrets Are Available "From Any Step in a Job"
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://docs.github.com/en/actions/reference/workflows-and-actions/contexts#secrets-context" rel="noopener noreferrer"&gt;secrets context documentation&lt;/a&gt; says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This context is the same for each job in a workflow run. You can access this context from any step in a job.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's true, for &lt;em&gt;steps&lt;/em&gt;. The job-level &lt;code&gt;with:&lt;/code&gt; on a reusable workflow call is not a step. It's a job-level declaration that gets parsed and validated with a restricted set of contexts before any job runs.&lt;/p&gt;

&lt;h2&gt;
  
  
  But I Have &lt;code&gt;secrets: inherit&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://docs.github.com/en/actions/how-tos/reuse-automations/reuse-workflows#example-reusable-workflow" rel="noopener noreferrer"&gt;reusable workflows docs&lt;/a&gt; explain that &lt;code&gt;secrets: inherit&lt;/code&gt; implicitly passes secrets to the called workflow. And it does. At runtime, the called workflow's steps can reference &lt;code&gt;secrets.RAILS_MASTER_KEY&lt;/code&gt; directly.&lt;/p&gt;

&lt;p&gt;The problem is that &lt;code&gt;with:&lt;/code&gt; is evaluated on the &lt;em&gt;caller&lt;/em&gt; side. &lt;code&gt;secrets: inherit&lt;/code&gt; makes secrets available &lt;em&gt;inside&lt;/em&gt; the called workflow, not in the caller's &lt;code&gt;with:&lt;/code&gt; expression. These are two parallel channels:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;with:&lt;/code&gt; sends named inputs (restricted contexts, validated at parse time)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;secrets:&lt;/code&gt; sends secrets (available at runtime in the called workflow's steps)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  But What About Org vs Repo Secrets?
&lt;/h2&gt;

&lt;p&gt;Doesn't matter for this error. &lt;code&gt;secrets: inherit&lt;/code&gt; passes both org-level and repo-level secrets to the called workflow. The error is a static validation failure at parse time. GitHub isn't even looking at which secrets exist or where they're stored. It's rejecting the &lt;code&gt;secrets&lt;/code&gt; context in &lt;code&gt;with:&lt;/code&gt; regardless.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fix
&lt;/h2&gt;

&lt;p&gt;Pass the secret &lt;em&gt;name&lt;/em&gt; as a string through &lt;code&gt;with:&lt;/code&gt;. Resolve it inside the called workflow where &lt;code&gt;secrets&lt;/code&gt; is available.&lt;/p&gt;

&lt;p&gt;In the calling workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;master_key_secret&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;RAILS_MASTER_KEY&lt;/span&gt;  &lt;span class="c1"&gt;# plain string, no secrets context&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the shared workflow, add an input and resolve it in the build step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;workflow_call&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;inputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;master_key_secret&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Secret&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Rails&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;master&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;key&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(empty&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;skip)"&lt;/span&gt;
        &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
        &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# In the build step:&lt;/span&gt;
&lt;span class="na"&gt;build-args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
  &lt;span class="s"&gt;${{ inputs.master_key_secret != '' &amp;amp;&amp;amp; format('RAILS_MASTER_KEY={0}', secrets[inputs.master_key_secret]) || '' }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;secrets[inputs.master_key_secret]&lt;/code&gt; pattern dynamically looks up a secret by name. It's the same approach GitHub's own docs use for parameterized registry credentials. The input defaults to empty, so repos that don't need it aren't affected.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Takeaway
&lt;/h2&gt;

&lt;p&gt;Two things that look the same in YAML, &lt;code&gt;with:&lt;/code&gt; on a step and &lt;code&gt;with:&lt;/code&gt; on a reusable workflow call, have fundamentally different context availability. If you're migrating from inline steps to reusable workflows and your &lt;code&gt;secrets.*&lt;/code&gt; references break, that's why. Pass the name, not the value.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;References:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.github.com/en/actions/reference/workflows-and-actions/contexts" rel="noopener noreferrer"&gt;Contexts reference&lt;/a&gt;, context availability table&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.github.com/en/actions/how-tos/reuse-automations/reuse-workflows" rel="noopener noreferrer"&gt;Reusing workflows&lt;/a&gt;, &lt;code&gt;secrets: inherit&lt;/code&gt; and workflow inputs&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.github.com/en/actions/reference/workflows-and-actions/contexts#secrets-context" rel="noopener noreferrer"&gt;Secrets context&lt;/a&gt;, "available from any step in a job"&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>github</category>
      <category>devops</category>
      <category>learning</category>
    </item>
    <item>
      <title>The Quiet Work that Keeps Ruby Alive</title>
      <dc:creator>christine</dc:creator>
      <pubDate>Mon, 09 Feb 2026 22:53:14 +0000</pubDate>
      <link>https://dev.to/cseeman/the-people-behind-ruby-what-the-january-newsletter-gets-right-12ke</link>
      <guid>https://dev.to/cseeman/the-people-behind-ruby-what-the-january-newsletter-gets-right-12ke</guid>
      <description>&lt;p&gt;I've written some &lt;a href="https://christine-seeman.com/what-just-happened-to-rubygems/" rel="noopener noreferrer"&gt;critical things&lt;/a&gt; about Ruby Central. I've also written about &lt;a href="https://christine-seeman.com/contributing-to-rubygems-org/" rel="noopener noreferrer"&gt;choosing to contribute anyway&lt;/a&gt;, because the community matters more than the org chart. So when the January 2026 newsletter landed in my inbox, I read it with a specific question: is Ruby Central showing up for the people who make this ecosystem work?&lt;/p&gt;

&lt;p&gt;The short answer: yes, in some meaningful ways.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Gala Awards
&lt;/h2&gt;

&lt;p&gt;Ruby Central is hosting a gala with awards that recognize the kinds of contributions that often go uncelebrated. And the honorees they've chosen say a lot about what the community values right now.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ruby Heart Award -- Emily Samp
&lt;/h3&gt;

&lt;p&gt;The Ruby Heart Award honors extraordinary compassion and service to the community. Emily Samp is an Engineering Manager at Shopify, where she works on improving the Ruby development experience through open source tools like Sorbet and Prism. She's also an organizer and co-founder of WNB.rb, and current CEO of the group.&lt;/p&gt;

&lt;p&gt;That combination matters. Working on Sorbet and Prism makes every Ruby developer's experience better. Co-founding WNB.rb makes sure "every Ruby developer" actually means everyone. She's doing both at the same time, and that's not an accident.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ruby Guidepost Award -- Saron Yitbarek
&lt;/h3&gt;

&lt;p&gt;The Guidepost Award recognizes mentorship and guidance of the next generation, and Saron Yitbarek is the right person for it. Saron is the founder of CodeNewbie (now owned by DEV), a developer, speaker, and podcaster. I've had the pleasure of seeing her speak at RubyConf and NDC London.&lt;/p&gt;

&lt;p&gt;If you've ever been new to programming and found a community that made you feel like you belonged, there's a good chance Saron's work had something to do with it. CodeNewbie created space for people who were just starting out, at a time when "beginner-friendly" wasn't really a thing yet in tech.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cutting Edge Award -- Nadia Odunayo
&lt;/h3&gt;

&lt;p&gt;The Cutting Edge Award goes to bold experimentation and boundary-pushing work. Nadia Odunayo founded &lt;a href="https://thenodmag.com/content/storygraph-reading-app-goodreads-alternative-woman-founded" rel="noopener noreferrer"&gt;The StoryGraph&lt;/a&gt;, a book-tracking app that has grown to over 4 million users as a privacy-focused alternative to Goodreads. I'm a huge fan.&lt;/p&gt;

&lt;p&gt;And here's the thing -- The StoryGraph is built with Ruby. Millions of people use it every day who have no idea what Ruby is. That's what pushing the boundaries of this ecosystem actually looks like.&lt;/p&gt;

&lt;h3&gt;
  
  
  Community Leadership Gem Award -- You Decide
&lt;/h3&gt;

&lt;p&gt;The one that caught my attention is the Community Leadership Gem Award, which is community-nominated. That matters. Letting the community choose who to celebrate instead of a board making that call from the top down is a small but meaningful shift toward the kind of governance I've been asking for.&lt;/p&gt;

&lt;p&gt;If you know someone doing quiet, consistent work to make the Ruby community better, &lt;a href="https://airtable.com/appBBx7FkmSpx9T6h/shrTv37agumEMKb4O" rel="noopener noreferrer"&gt;nominate them&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  New Board Members
&lt;/h2&gt;

&lt;p&gt;Three new members joined the Ruby Central board:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.baweaver.com" rel="noopener noreferrer"&gt;Brandon Weaver&lt;/a&gt;&lt;/strong&gt; has been writing Ruby for 15 years and is known for his conference talks and education work. Having someone on the board who's been in the trenches as a speaker and educator is good representation. He is good people, and will be pushing for communication and transparency with the board. No one knows Ruby like Brandon and I'm really excited to see what he does on the board.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://thoughtbot.com/blog/authors/ran-craycraft" rel="noopener noreferrer"&gt;Ran Craycraft&lt;/a&gt;&lt;/strong&gt; is the Managing Director at thoughtbot. Thoughtbot has a long history of contributing to the Ruby ecosystem through open source and mentorship, so this feels like a natural fit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://jnf.dev" rel="noopener noreferrer"&gt;Jey Flores&lt;/a&gt;&lt;/strong&gt; leads Product Engineering at Code for America and previously worked at Bandcamp. Bringing in someone from the civic tech space broadens the perspective on who Ruby serves and how.&lt;/p&gt;

&lt;p&gt;The RubyGems situation showed what happens when leadership stops listening to the people doing the work. Fresh voices on the board could help with that.&lt;/p&gt;

&lt;h2&gt;
  
  
  WNB.rb and the Volunteers Who Build Community
&lt;/h2&gt;

&lt;p&gt;This is the part of the newsletter that I love is called out but heads up that I'm biased when it comes to WNB.rb. I've been a member of the community since it was founded and have joined up on WNB.rb's board. So the community means a lot to me, and I am so happy it is being shared in the newsletter.&lt;/p&gt;

&lt;p&gt;WNB.rb (Women and Non-Binary Rubyists) group is transitioning from a founder-led organization to a community-managed one. That's hard work, and it's how you make something last.&lt;/p&gt;

&lt;p&gt;The newsletter highlights two people by name:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sarah Eggleston&lt;/strong&gt;, WNB.rb's Deputy CTO, who's helped grow the community and make it a place people actually want to show up to. And &lt;strong&gt;Jess Sullivan&lt;/strong&gt;, the Book Club Lead, who makes it okay to not know things yet. Both amazing people, who care deeply about Ruby and WNB.rb.&lt;/p&gt;

&lt;p&gt;That last part is worth sitting with. Jess is normalizing imperfect learning. That doesn't show up on a GitHub contribution graph, but it changes how people experience this community.&lt;/p&gt;

&lt;p&gt;WNB.rb's mission of making the Ruby community accessible to marginalized individuals entering tech is worth paying attention to. If you're not already involved, &lt;a href="https://www.wnb-rb.dev/join-us" rel="noopener noreferrer"&gt;look into it&lt;/a&gt; and &lt;a href="https://www.wnb-rb.dev/sponsor-us" rel="noopener noreferrer"&gt;support the mission&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Looking Ahead
&lt;/h2&gt;

&lt;p&gt;The newsletter also covers some forward-looking items worth noting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RubyConf 2026&lt;/strong&gt; is heading to Red Rock, Nevada, with a new "Ruby Runway" pitch competition for Ruby-based projects&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RubyGems.org Organizations&lt;/strong&gt; is in private beta, adding multi-maintainer gem management (a feature that directly addresses some of the collaboration pain points I've seen firsthand)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google Summer of Code&lt;/strong&gt; is looking for Ruby projects and mentors, with a focus on AI/ML and security&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What This Means
&lt;/h2&gt;

&lt;p&gt;Governance issues don't resolve in a few months, and trust takes time to rebuild. But spotlighting community volunteers by name, letting the community nominate its own awards, bringing in new board members -- that's Ruby Central showing that it knows the community matters. I'm really liking what I'm seeing with the continued communication.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;The newsletter discussed in this post: &lt;a href="https://mailchi.mp/20fc57b4f4ee/the-ruby-central-readme-january2026-newsletter" rel="noopener noreferrer"&gt;Ruby Central README: January 2026&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>community</category>
    </item>
    <item>
      <title>Contributing to RubyGems (.org)</title>
      <dc:creator>christine</dc:creator>
      <pubDate>Wed, 28 Jan 2026 18:58:44 +0000</pubDate>
      <link>https://dev.to/cseeman/contributing-to-rubygems-org-5dpi</link>
      <guid>https://dev.to/cseeman/contributing-to-rubygems-org-5dpi</guid>
      <description>&lt;p&gt;A few months ago, &lt;a href="https://christine-seeman.com/what-just-happened-to-rubygems/" rel="noopener noreferrer"&gt;I wrote&lt;/a&gt; about a move that bypassed the maintainers who had built the RubyGems and Bundler projects for decades. I had some questions about trust, governance, and whether Ruby Central could be a responsible steward of our community's infrastructure.&lt;/p&gt;

&lt;p&gt;So it might seem strange that I recently submitted a pull request to rubygems.org.&lt;/p&gt;

&lt;p&gt;This post is about that contribution, but it's also about a question I had to answer for myself: Why help a project when you have concerns about the organization running it?&lt;/p&gt;

&lt;p&gt;The Short Answer: the code doesn't belong to Ruby Central. It belongs to the community.&lt;/p&gt;

&lt;p&gt;When I contribute to rubygems.org, I'm not endorsing Ruby Central's past governance decisions. I'm improving a piece of infrastructure that every Ruby developer depends on, including me, including my team, including developers who have no idea any controversy exists.&lt;/p&gt;

&lt;p&gt;The people reviewing my PR weren't board members making decisions. They were developers like me, with their time spent making the Ruby ecosystem better. Withholding contributions punishes them, not the people who had made the past governance decisions.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Problem That Got Me Involved&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;My team had adopted a shared GitHub Actions workflow for releasing our gems. Instead of duplicating release logic across repositories, we maintain one canonical workflow and call it a shared gem release, It's similar to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# In my-gem/.github/workflows/release.yml
jobs:
release:
uses: our-org/shared-workflows/.github/workflows/ruby-gem-release.yml@main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clean pattern, common in organizations with multiple gems. One problem: RubyGems.org's trusted publishing feature didn't support it.&lt;/p&gt;

&lt;p&gt;When you use a reusable workflow, the OIDC token from GitHub points to the shared workflow's location, not your repository. RubyGems.org expected these to match. Our releases were failing. I needed to revert back the old flow, where we have slight release difference in each repo. Not ideal.&lt;/p&gt;

&lt;p&gt;I found &lt;a href="https://github.com/rubygems/rubygems.org/issues/4294" rel="noopener noreferrer"&gt;https://github.com/rubygems/rubygems.org/issues/4294&lt;/a&gt; from 2023. No one had fixed it, yet.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Choosing to Contribute&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;I had options. I could work around the limitation. I could complain on social media. I could wait for someone else to fix it.&lt;/p&gt;

&lt;p&gt;Instead, I decided to fix it myself.&lt;/p&gt;

&lt;p&gt;Here's my reasoning: Open source is bigger than any single organization. RubyGems existed before Ruby Central, and the codebase will outlast whatever governance structure exists today. Contributing good code, code that helps developers, is worthwhile regardless of organizational politics.&lt;/p&gt;

&lt;p&gt;If you are going to contribute, you might as well do it well, so here are some tips doing just that and that I kept in mine with my RubyGems feature.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Structure Your Commits Like a Story&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Maintainers review a lot of code. Help them follow your thinking: Clear summaries, explanation of why not just what, security implications called out, and reviewer contributions credited.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Write a PR Description That Respects Their Time&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Your description is your pitch. Answer these questions immediately:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What problem does this solve?
&lt;/li&gt;
&lt;li&gt;How does it solve it?
&lt;/li&gt;
&lt;li&gt;Are there security implications?
&lt;/li&gt;
&lt;li&gt;How can reviewers verify it works?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Mine looked roughly like: Enables trusted publishing for gems using reusable workflows from external repositories&lt;/p&gt;

&lt;p&gt;Short. Scannable. No mystery about what's happening.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Tests Are Your Credibility&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Comprehensive tests tell maintainers you've thought through edge cases:&lt;/p&gt;

&lt;p&gt;The test names describe scenarios. A reviewer can understand what's verified without reading implementation details. And the security test verifying that mismatched workflows are rejected, matters a lot for authentication code.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Receive Feedback Graciously&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This is where contributing gets genuinely valuable. The reviewers know the codebase. Their feedback makes your code better.&lt;/p&gt;

&lt;p&gt;I received two pieces of feedback that improved my implementation:&lt;/p&gt;

&lt;p&gt;"The validation is tricky to understand. Could we use declarative Rails validations?"&lt;/p&gt;

&lt;p&gt;My original:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
def workflow_repository_fields_consistency
owner_present = workflow_repository_owner.present?
name_present = workflow_repository_name.present?
return if owner_present == name_present
errors.add(:base, "…")
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The suggestion:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
validates :workflow_repository_owner, presence: true, if: -&amp;gt; { workflow_repository_name.present? }
validates :workflow_repository_name, presence: true, if: -&amp;gt; { workflow_repository_owner.present? }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same behavior, more idiomatic.&lt;/p&gt;

&lt;p&gt;"This query branch is unreachable given your other validation."&lt;/p&gt;

&lt;p&gt;Dead code I hadn't noticed. The reviewer spotted that my .or() clause could never match because another validation prevented that data state from existing.&lt;/p&gt;

&lt;p&gt;Both changes made the code better. I implemented them, credited the reviewers, and the PR was approved.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Bigger Picture&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;After my code contribution was merged, I submitted a documentation PR to &lt;a href="https://github.com/rubygems/guides" rel="noopener noreferrer"&gt;https://github.com/rubygems/guides&lt;/a&gt; explaining how to configure the new fields. Features don't help if users don't know they exist.&lt;/p&gt;

&lt;p&gt;Now every Ruby developer using shared release workflows can use trusted publishing. That's a small improvement for potentially thousands of people.&lt;/p&gt;

&lt;p&gt;But here's what I keep coming back to: the people who reviewed my PR, who gave thoughtful feedback, who approved and merged the changes. They're developers who care about the Ruby ecosystem. They showed up, they did good work, and they made the project better.&lt;/p&gt;

&lt;p&gt;Open source is ultimately about people, not organizations. The code is written by individuals. The reviews are done by individuals. The community is made up of individuals who choose to contribute their time.&lt;/p&gt;

&lt;p&gt;Ruby Central's past governance may have disappointed me. But the Ruby community hasn't.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;If You're Hesitant to Contribute&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Maybe you have concerns about other projects' leadership. Here's what I'd say:&lt;/p&gt;

&lt;p&gt;Contribute to the code, not the org chart. Your pull request improves software that real people use. The maintainers aren't the executives. Don't punish them for decisions they didn't make.&lt;/p&gt;




&lt;p&gt;Find a problem you care about. Fix it. Submit the PR. The Ruby ecosystem, our community, is worth contributing to.&lt;/p&gt;




&lt;p&gt;The PR discussed in this post is &lt;a href="https://github.com/rubygems/rubygems.org/pull/6184" rel="noopener noreferrer"&gt;https://github.com/rubygems/rubygems.org/pull/6184&lt;/a&gt;. The documentation update is &lt;a href="https://github.com/rubygems/guides/pull/410" rel="noopener noreferrer"&gt;https://github.com/rubygems/guides/pull/410&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Originally Posted on &lt;a href="https://christine-seeman.com/contributing-to-rubygems-org/" rel="noopener noreferrer"&gt;https://christine-seeman.com/contributing-to-rubygems-org/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>opensource</category>
    </item>
    <item>
      <title>What Just Happened to RubyGems?</title>
      <dc:creator>christine</dc:creator>
      <pubDate>Wed, 24 Sep 2025 04:11:06 +0000</pubDate>
      <link>https://dev.to/cseeman/what-just-happened-to-rubygems-31n9</link>
      <guid>https://dev.to/cseeman/what-just-happened-to-rubygems-31n9</guid>
      <description>&lt;p&gt;By &lt;a href="https://christine-seeman.com/author/christine/" rel="noopener noreferrer"&gt;christine&lt;/a&gt; September 23, 2025, edited and updated September 25, 2025&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;And Why We Should Care&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Based on some solid reporting by &lt;a href="https://joel.drapper.me/p/rubygems-takeover/" rel="noopener noreferrer"&gt;Joel Drapper&lt;/a&gt; and &lt;a href="https://pup-e.com/goodbye-rubygems.pdf" rel="noopener noreferrer"&gt;Ellen’s breaking details&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, the Ruby community just went through something wild, and I think we need to talk about it. On September 9th, Ruby Central basically took over the RubyGems GitHub repos and gem ownership without asking the people who’ve been maintaining them for years. It’s… not great.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;TL;DR&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;What happened:&lt;/strong&gt; Ruby Central asserted control over RubyGems and bundler repos and ownership, blurring lines between running the service and owning the code.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Why it’s a problem:&lt;/strong&gt; Community‑built code isn’t corporate property; governance requires consent, transparency, and accountability.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Bundler context:&lt;/strong&gt; André Arko clarified Bundler’s code is community-owned, registered the trademark to prevent unilateral claims, and intends to transfer it to a democratic, community‑led org (&lt;a href="https://andre.arko.net/2025/09/25/bundler-belongs-to-the-ruby-community/" rel="noopener noreferrer"&gt;his post&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Story (As Best I Can Tell)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Joel Drapper did some really impressive investigative work here, and here’s what seems to have happened:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;The Money Problem:&lt;/strong&gt; Ruby Central lost $250k a year from Sidekiq after they had DHH speak at RailsConf 2025. That left them pretty much dependent on Shopify for funding.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;The Pressure:&lt;/strong&gt; Shopify apparently said “take control of RubyGems or we’re pulling our funding.” That’s… a pretty clear ultimatum.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;The Messy Execution&lt;/strong&gt;: HSBT went ahead and added Marty Haught as an owner and changed permissions before anyone really talked about it. When people complained, Marty said it was a mistake and some changes got reverted, but Marty stayed as owner.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;The Board Vote&lt;/strong&gt;: Even though Marty warned them about the consequences and suggested alternatives (like forking), the Ruby Central board voted to do the takeover anyway. And Marty went ahead and did it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Here’s What Really Bugs Me&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The whole thing comes down to this: Ruby Central is confusing two completely different things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  RubyGems (the open source code): This belongs to the community. People have been working on this for decades, unpaid, because they care about Ruby.&lt;/li&gt;
&lt;li&gt;  RubyGems Service (the website and servers): This is Ruby Central’s thing. They run the actual rubygems.org site.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Just because Ruby Central pays some people to work on the service doesn’t mean they own the open source code. That’s like saying you own Rails because you sponsored someone who made a PR to Rails. It doesn’t work that way.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Communication Has Been Terrible&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Honestly, this is what’s been most disappointing. Ruby Central’s response felt like corporate speak with no one willing to put their name on it. Board members keep saying things like “Ruby Central has been responsible for RubyGems for a long time” when that’s just not true—they’ve been responsible for running the service, not owning the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;So… What Now?&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;How do we protect community projects?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When corporate money is involved, how do we make sure the community still owns what it built?&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;What about transparency?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;How do we prevent stuff like this from happening again? And when hard decisions need to be made, how do we make sure everyone’s actually talking to each other?&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Corporate influence is tricky.&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;We need corporate support to keep things running, but how do we draw the line between “helping” and “taking over”?&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Trust is broken.&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Can we still trust Ruby Central to look after our infrastructure when they’ve shown they’ll take over community projects if a big company tells them to?&lt;/p&gt;

&lt;p&gt;Look, I get that running infrastructure is hard and expensive. But this wasn’t about infrastructure—this was about taking control of open source code that belongs to the community. And doing it under the guise of “supply chain security” when it was really about corporate pressure just makes it worse. The Ruby community deserves better than this.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Adarsh adds to the picture
&lt;/h3&gt;

&lt;p&gt;From Adarsh’s as a former Ruby Central director: &lt;a href="https://ruby.social/@adarsh/115254610927555600" rel="noopener noreferrer"&gt;Mastodon thread&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;He talks about the very real operational and funding pressures Ruby Central faces.&lt;/li&gt;
&lt;li&gt;Underscores the importance of clarity between running critical infrastructure (operator responsibilities, access, accountability) and stewarding community code (governance, consent, legitimacy).&lt;/li&gt;
&lt;li&gt;And points toward constructive next steps: explicit agreements, transparent governance, and rebuilding trust with maintainers rather than asserting ownership through access.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;The through‑line is pragmatic: secure the service, but do it in a way that respects community ownership and doesn’t burn the social capital the ecosystem relies on.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Quick recap: Bundler, RubyTogether, and community ownership&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Bundler belongs to the community:&lt;/strong&gt; André Arko registered the trademark to protect the project’s name from unilateral claims and commits to transfer it to a democratically accountable, community-led org.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Licenses and code stay open:&lt;/strong&gt; The code remains MIT; the real issue is governance, not access.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Bottom line:&lt;/strong&gt; Fund maintainers. Secure the service. According to the RubyTogether merger, Bundler’s code was never Ruby Central’s to claim and he wants to protect the name for the community and keep governance with maintainers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Sources: &lt;a href="https://joel.drapper.me/p/rubygems-takeover/" rel="noopener noreferrer"&gt;Joel Drapper's deep dive&lt;/a&gt;, &lt;a href="http://pup-e.com/goodbye-rubygems.pdf" rel="noopener noreferrer"&gt;Ellen's initial report&lt;/a&gt;&lt;/em&gt;, Adarsh (former Ruby Central director), &lt;a href="https://ruby.social/@adarsh/115254610927555600" rel="noopener noreferrer"&gt;Mastodon thread&lt;/a&gt;, &lt;a href="https://andre.arko.net/2025/09/25/bundler-belongs-to-the-ruby-community/" rel="noopener noreferrer"&gt;André Arko on Bundler &amp;amp; community&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rubygems</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Save your sanity – add a modifier key to your MacOS Hot Corners</title>
      <dc:creator>christine</dc:creator>
      <pubDate>Tue, 15 Apr 2025 19:57:29 +0000</pubDate>
      <link>https://dev.to/cseeman/save-your-sanity-add-a-modifier-key-to-your-macos-hot-corners-23m0</link>
      <guid>https://dev.to/cseeman/save-your-sanity-add-a-modifier-key-to-your-macos-hot-corners-23m0</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.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%2Fwommlc5wb0vjb1ydn5lr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fwommlc5wb0vjb1ydn5lr.png" alt=" " width="800" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I like the convenance of using Hot Corners to lock my screen. It just works for me. I know way, way too many keyboard shortcuts. Depends on what I am in, but I have been trying to shove Vim and tmux keybindings into by brain for years…and now with switching over to Cursor I have different ones to remember now.&lt;/p&gt;

&lt;p&gt;So, don’t get me wrong, I like keybindings just like any other software dev does…but sometimes you just want to lock your screen. There is nothing like dragging your mouse to a corner and it is just done. That is till you do it to yourself 3 times while on a video meeting, that’s when you start thinking to yourself that there has got to be something better.&lt;/p&gt;

&lt;p&gt;And that something is adding a modifier key. Brilliant, simple and you can still use hot corners without going nutty. So how do you stop activating Hot Corners accidentally?&lt;/p&gt;

&lt;p&gt;Go to System Preferences &amp;gt; Mission Control, then click on Hot Corners.&lt;br&gt;
Select any of the four active corners of your screen, and a drop-down menu appears. (my new option is the upper right corner)&lt;br&gt;
To assign a modifier key, press and hold the key (Shift, Command, Control, or Option, choose one) then pick an action, like Lock &lt;br&gt;
Screen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fa1v1z9ki71d3rlqklzdq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fa1v1z9ki71d3rlqklzdq.png" alt=" " width="800" height="749"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You are in control now! Or should I say command, because now just scrolling to the upper right corner won’t trigger that lock screen. You’ll have to add an extra keystroke for that, and that shouldn’t be too much to remember, just one extra key.&lt;/p&gt;

</description>
      <category>macos</category>
      <category>devtools</category>
    </item>
    <item>
      <title>Bringing together Mastodon and WordPress</title>
      <dc:creator>christine</dc:creator>
      <pubDate>Wed, 11 Oct 2023 21:48:34 +0000</pubDate>
      <link>https://dev.to/cseeman/bringing-together-mastodon-and-wordpress-62g</link>
      <guid>https://dev.to/cseeman/bringing-together-mastodon-and-wordpress-62g</guid>
      <description>&lt;p&gt;Reading Time: 2 minutes&lt;/p&gt;

&lt;p&gt;WordPress.com &lt;a href="https://wordpress.com/blog/2023/10/11/activitypub/" rel="noopener noreferrer"&gt;announced&lt;/a&gt; the release of the &lt;a href="https://wordpress.org/plugins/activitypub/" rel="noopener noreferrer"&gt;ActivityPub plugin&lt;/a&gt; on their blogs in October, I don’t use WordPress.com but it did make me aware of the plugin so I decided to give it a go.&lt;/p&gt;

&lt;p&gt;I have been on Mastodon (the excellently run ruby.social instance) since &lt;a href="https://ruby.social/@christine/109286434267949831" rel="noopener noreferrer"&gt;November 4th, 2022&lt;/a&gt;. Coming from the bird site, it was a bit of a shock but in a good way. But it was also confusing, just like when you had to learn about Git coming from a CVS system like Subversion, one is distributed and one is centralized.&lt;/p&gt;

&lt;p&gt;Now, with the ActivityPub plugin, I can make my WordPress site and posts publish to a federated profile and have people reply to that on ActivityPub but show up as WordPress comments. It is it’s own feed! This sounded pretty nifty, but my setup wasn’t just plug-and-play and required a bit more configuration than what was addressed in the WordPress.com announcement.&lt;/p&gt;

&lt;p&gt;I am on Flywheel as my WordPress host, and it seems like I might need some &lt;a href="https://github.com/Automattic/wordpress-activitypub/discussions/155#discussioncomment-4092547" rel="noopener noreferrer"&gt;additional redirects in my .htcaccess&lt;/a&gt; because in my site health, my webfinger kept on 404ing. But Flywheel doesn’t allow direct htcaccess but I can &lt;a href="https://getflywheel.com/wordpress-support/flywheel-redirects/" rel="noopener noreferrer"&gt;add redirects&lt;/a&gt;through the flywheel site. My first attempt at adding a redirect didn’t quite work as expected, I got instead a redirect to “&lt;a href="https://wp-json//activitypub//1/.0//webfinger?resource=acct:christine@christine-seeman.com%E2%80%9D" rel="noopener noreferrer"&gt;https://wp-json//activitypub//1/.0//webfinger?resource=acct:christine@christine-seeman.com”&lt;/a&gt;, which does not work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fb1boqo8gla0aj9r7mpgq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fb1boqo8gla0aj9r7mpgq.png" width="800" height="627"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Flywheel’s Add Redirect page for a site, this setup turned out to be not be the correct regex.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I am trying to simplify the redirect and make sure it hits the proper webfinger for ActivityPub (Mastadon)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fenj04qxx8olckzo91huc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fenj04qxx8olckzo91huc.png" width="800" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This worked! So I needed to add into my source redirect &lt;code&gt;^/.well-known/webfinger(.*)$&lt;/code&gt; and then for my destination &lt;code&gt;/wp-json/activitypub/1.0/webfinger$1&lt;/code&gt; and now you can subscribe to my infrequent posts from my blog, &lt;code&gt;hi-from@christine-seeman.com&lt;/code&gt;, or from me as an author (which umm not so many other authors on my website) &lt;code&gt;christine@christine-seeman.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Best of luck tying your WordPress and Mastodon/ActivityPub together.&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>activitypub</category>
      <category>mastodon</category>
    </item>
    <item>
      <title>How to copy text from one pane – MacOS/Tmux/Alacritty</title>
      <dc:creator>christine</dc:creator>
      <pubDate>Wed, 03 May 2023 17:54:19 +0000</pubDate>
      <link>https://dev.to/cseeman/how-to-copy-text-from-one-pane-macostmuxalacritty-2ll0</link>
      <guid>https://dev.to/cseeman/how-to-copy-text-from-one-pane-macostmuxalacritty-2ll0</guid>
      <description>

&lt;p&gt;My problem? I only want to copy text from one tmux pane, not across two.&lt;/p&gt;

&lt;p&gt;But I was finding that my mouse was failing me, and I knew there had to be a better way than just closing out my panes and only having one open. My journey on &lt;a href="https://christine-seeman.com/2021/04/lets-explore-what-is-a-shell-and-terminal/" rel="noopener noreferrer"&gt;understanding terminals, shells, editors,&lt;/a&gt; and how to use them correctly has been rocky, but I have been feeling in a good place lately. The current setup that I am using is bash shell (starship shell prompt for that added sparkle), &lt;a href="https://github.com/alacritty/alacritty" rel="noopener noreferrer"&gt;Alacritty terminal&lt;/a&gt;, &lt;a href="https://neovim.io/" rel="noopener noreferrer"&gt;Neovim editor&lt;/a&gt;, and &lt;a href="https://github.com/tmux/tmux/wiki" rel="noopener noreferrer"&gt;Tmux&lt;/a&gt; for running multiple terminals. I had gotten this all configured, which probably took too much time. Debugging your developer setup is a considerable learning experience, but developers (meaning me) sometimes (all the time) make it more complicated than it needs to be. I probably didn’t need to throw in attempting to theme everything too, but I like my consistent look.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fohmf4dj0bo8wene2j89p.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fohmf4dj0bo8wene2j89p.gif" width="649" height="237"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my search to figure out how to copy the text on one pane, some &lt;a href="https://dev.to/sophiabrandt/copy-and-paste-in-tmux-494a-temp-slug-1778453"&gt;Linux&lt;/a&gt; &lt;a href="https://www.rushiagr.com/blog/2016/06/16/everything-you-need-to-know-about-tmux-copy-pasting-ubuntu/" rel="noopener noreferrer"&gt;solutions&lt;/a&gt; were close to what I needed but not 100% the way there. This setup got me all the way there with a solution that should fit nicely in my vim workflow.&lt;/p&gt;

&lt;p&gt;The suggested Linux setup is a good start but does not work great for MacOS&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; bind-key -T copy-mode-vi v send-keys -X begin-selection
 bind-key -T copy-mode-vi y send-keys -X copy-selection
 bind-key -T copy-mode-vi r send-keys -X rectangle-toggle

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For MacOS, add the following onto your tmux configuration (for ex. at ~/.tmux.conf). This solution came from a &lt;a href="https://superuser.com/a/1743290" rel="noopener noreferrer"&gt;superuser post&lt;/a&gt; from user &lt;a href="https://superuser.com/users/809706/jeremysprofile" rel="noopener noreferrer"&gt;jeremysprofile&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;setw -g mode-keys vi
set -g set-clipboard off
bind-key -T copy-mode-vi v send-keys -X begin-selection
# bind y key in copy mode to select and copy to system clipboard
bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "pbcopy"
bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "pbcopy"

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The configuration will add some vi key bindings, and then to supercharge tmux copy mode. For copying and pasting, reach for typical vim keybindings. Start with &lt;code&gt;v&lt;/code&gt; to select the text, then &lt;code&gt;y&lt;/code&gt; to copy/yank the text. Then the text is in your copy buffer and ready for pasting.&lt;/p&gt;

&lt;p&gt;Let’s see our new bindings in action.&lt;/p&gt;

&lt;p&gt;Hit your terminal, start up &lt;code&gt;tmux&lt;/code&gt; ( &lt;strong&gt;&lt;code&gt;tmux source ~/.tmux.conf&lt;/code&gt;&lt;/strong&gt; ) and make sure to refresh your config if you already have tmux open.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fgnc9t7e632c2lj4tpztt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fgnc9t7e632c2lj4tpztt.png" width="800" height="680"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Split your pane (tmux default keys &lt;code&gt;C-b "&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fl4jf8ofv5hcn7c98i6m0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fl4jf8ofv5hcn7c98i6m0.png" alt="Untitled" width="800" height="677"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Load up some text on either side. I am looking at two readme files, one that I loaded up in vim and one that is just &lt;code&gt;cat&lt;/code&gt; on the terminal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F9y4042ys0ibkeul6hq1j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F9y4042ys0ibkeul6hq1j.png" alt="Untitled" width="800" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now attempt to use your mouse to highlight some text. You will notice that both sides will highlight.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fyl1xg7kb4ymehun057jl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fyl1xg7kb4ymehun057jl.png" alt="Untitled" width="800" height="245"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Frustrating if you want the output from just the right side! Let’s use the new keybindings we added to the tmux configuration instead.&lt;/p&gt;

&lt;p&gt;Switch over to tmux scroll mode (&lt;code&gt;C-b [&lt;/code&gt;), use your arrow keys to move around, and when you are on the text that you want to copy, use &lt;code&gt;v&lt;/code&gt; to make your selection.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Frv24btvtektfr2lq8mx6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Frv24btvtektfr2lq8mx6.png" alt="Untitled" width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What’s this? Only text selected on one side? Perfect! Copy the text using &lt;code&gt;y&lt;/code&gt; , and it is ready to put where you need it. In my case, moving to my left pane (&lt;code&gt;C-b&lt;/code&gt; then left arrow ), and then pasted (vim &lt;code&gt;p&lt;/code&gt;) into my other readme.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fqbwdotsnkv0n3k4p4ty4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fqbwdotsnkv0n3k4p4ty4.png" alt="Untitled" width="800" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we have a reusable, memorable solution for grabbing text in a single tmux pane!&lt;/p&gt;

</description>
      <category>learning</category>
      <category>tmux</category>
      <category>vim</category>
      <category>dev</category>
    </item>
    <item>
      <title>How to: Mastodon Verification for your Website</title>
      <dc:creator>christine</dc:creator>
      <pubDate>Fri, 11 Nov 2022 17:44:12 +0000</pubDate>
      <link>https://dev.to/cseeman/how-to-mastodon-verification-for-your-website-11b7</link>
      <guid>https://dev.to/cseeman/how-to-mastodon-verification-for-your-website-11b7</guid>
      <description>&lt;p&gt;Are you part of the &lt;a href="https://theconversation.com/what-is-mastodon-the-twitter-alternative-people-are-flocking-to-heres-everything-you-need-to-know-194059" rel="noopener noreferrer"&gt;twitter migration&lt;/a&gt;? Me too! I chose Mastodon as my social app of choice, and &lt;a href="https://ruby.social/explore" rel="noopener noreferrer"&gt;ruby.social&lt;/a&gt; as my community.&lt;/p&gt;

&lt;p&gt;Learning Mastodon takes time, and I am right there with you. There is one thing that I can be assistance with, helping you figure out how to verify your website link in your profile. I am on WordPress, because it is a cool content management system, allows me as a non-frontend dev to have something that looks halfway decent with a minimal amount of work, and well I believe in &lt;a href="https://www.edume.com/blog/what-is-dogfooding" rel="noopener noreferrer"&gt;dogfooding&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Head on over to your Mastodon profile, and click &lt;code&gt;edit profile&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Ftkdtfjv879dhmkap8wul.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ftkdtfjv879dhmkap8wul.png" width="150" height="74"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Author’s picture with the option to click “Edit profile”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In your Mastodon &lt;code&gt;Profile metadata&lt;/code&gt; section, add in your personal website, then &lt;code&gt;Save changes&lt;/code&gt;. Notice the &lt;code&gt;Verification&lt;/code&gt; section off to the right of the metadata options? Copy your customized verification link.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can  &lt;strong&gt;verify yourself as the owner of the links in your profile metadata&lt;/strong&gt;. For that, the linked website must contain a link back to your Mastodon profile. The link back  &lt;strong&gt;must&lt;/strong&gt;  have a &lt;code&gt;rel="me"&lt;/code&gt; attribute. The text content of the link does not matter. &lt;/p&gt;

&lt;p&gt;&lt;cite&gt;Mastodon settings/profile&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F5zjiilu3y23s7eqh3nyn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F5zjiilu3y23s7eqh3nyn.png" width="412" height="180"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Mastodon Verification section&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Next head to your website and add the link on your site anywhere. For example in a footer/header section where you might have other social links. For my WordPress site, I added a Custom HTML block in my sidebar widget section with my Mastodon profile link.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fknnvpd50h16thisaqsym.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fknnvpd50h16thisaqsym.png" width="443" height="789"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Screengrab of my default Sidebar section, with the Custom HTML block&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To check that everything is correct for verification, check out your page source. As with many things front end, checking on the raw HTML (for us the div tag) is the best way to see what the link actually is using in its metadata. The important part for Mastodon verification is the &lt;code&gt;rel="me"&lt;/code&gt; attribute. When I look at my page source, I see that it is there&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fe7kbtw2uanlv9kx6b3u5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fe7kbtw2uanlv9kx6b3u5.png" width="706" height="106"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Page source of christine-seeman.com view in Chrome Developer Tools&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That’s it! It might take a bit for your verification to show up on your profile (caching/propagation take time) but you should see that sweet green highlighting eventually to let everyone know that you really do control access to that link.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Frzw0hntdspdddhz80mq7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Frzw0hntdspdddhz80mq7.png" width="575" height="268"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>learning</category>
      <category>mastodon</category>
      <category>wordpress</category>
    </item>
    <item>
      <title>Updated! What's your bio?</title>
      <dc:creator>christine</dc:creator>
      <pubDate>Wed, 28 Sep 2022 19:58:29 +0000</pubDate>
      <link>https://dev.to/cseeman/updated-whats-your-bio-4a6o</link>
      <guid>https://dev.to/cseeman/updated-whats-your-bio-4a6o</guid>
      <description>&lt;p&gt;So about 4 years, I found myself in need of writing a biography for speaking at a conference. I reached out to &lt;a href="https://dev.to/cseeman/whats-your-bio-one-paragraph-describing-your-personalprofessional-life-391f"&gt;dev.to&lt;/a&gt; for ideas.&lt;/p&gt;

&lt;p&gt;Since then, I have spoken at a couple more conference and have found myself tweaking that bio along the way. Just like talk descriptions, it always feels like there is room for improvement. You change. Your talk changes. Why shouldn’t you make sure that is reflected in your bios?&lt;/p&gt;

&lt;p&gt;So here was a sample format that I started with(taken from a &lt;a href="https://dev.to/rdumais/comment/5pgb"&gt;comment on dev.to&lt;/a&gt;)&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;{Name} is from {City, State} where he/she works as an {Title} at {Company}. He/She has {#} years of experience with {Technology Name} with a focus on {Technology Focus}. In his/her spare time, {Name} enjoys {Personal Interest #1} and {Personal Interest #2}.&lt;/p&gt;

&lt;p&gt;&lt;cite&gt;&lt;a href="https://dev.to/rdumais"&gt;Ryan&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And that did get me one of my first bios:&lt;br&gt;&lt;br&gt;
&lt;em&gt;Christine is from Omaha, Nebraska where she works as a full stack Ruby on Rails engineer at Flywheel, WordPress hosting for creatives. She has 12 years experience as a Java software engineer with a focus on APIs and micro-services and took the plunge into Ruby just this May. In her spare time she is an avid long form reader, lover of all true-crime podcasts and is attempting to work through the primary Ashtanga yoga series.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now my bio looks a bit like this:&lt;br&gt;&lt;br&gt;
&lt;em&gt;Christine is a lifetime learner from Omaha, NE (in the middle of the USA), where she likes to read too much and eats food that probably took too long to prepare. Professionally she’s helping solve problems on the Identity team at WP Engine. She loves working with Ruby, showing people that long Git commits are impressive, and helping write secure, easy-to-read software that powers authorization and authentication at her company.&lt;/em&gt;  &lt;/p&gt;

&lt;p&gt;What changed from that time?&lt;br&gt;&lt;br&gt;
Well, the company I was at in 2018 was acquired. I have moved around teams 3-4 times and been to many more conferences.&lt;br&gt;&lt;br&gt;
To me, what you want to get out of a bio is, who is this person, and why should I listen to them? And it wouldn’t be wrong to see a bit of that person’s personality. I love whimsy and positivity and have tons of other interests that have nothing to do with why I do it for my career. My career is not my life. I want my bio to show that.&lt;/p&gt;

&lt;p&gt;So let me introduce an updated conference bio template:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;{Name} is from {Current Location} who enjoys {Personal Passion 1}, {Personal Passion 2}, and {Personal Passion 3} . {They/She/Him} professionally {verb ex. teach, code, design, architect, build…} {tech stack} at {company} and are passionate about {Technology/Professional focus} and have been involved in the field for {#} years. {Last sentence tie it back to your talk experience, ex. I talk about MFA, so I mention that is what I am involved with my career.}&lt;/p&gt;

&lt;p&gt;&lt;cite&gt;Christine’s 2022 Technical Conference Speaker BIO Template&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What do you think? Does this get you what you want to know about your conference speakers?&lt;/p&gt;

</description>
      <category>career</category>
      <category>speaking</category>
      <category>conferences</category>
      <category>community</category>
    </item>
    <item>
      <title>Oh, hello again Vim</title>
      <dc:creator>christine</dc:creator>
      <pubDate>Wed, 06 Oct 2021 21:33:51 +0000</pubDate>
      <link>https://dev.to/cseeman/oh-hello-again-vim-3deo</link>
      <guid>https://dev.to/cseeman/oh-hello-again-vim-3deo</guid>
      <description>&lt;h2&gt;
  
  
  aka How to Install vim-plug in Neovim
&lt;/h2&gt;




&lt;p&gt;Me and Vim have a love/hate relationship.&lt;/p&gt;

&lt;p&gt;I love using it… until I remember I don't actually remember the keybindings annnnd then I have to search multiple articles every time I want to do anything in it. Especially leave it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpics.onsizzle.com%2Fvim-68280725.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpics.onsizzle.com%2Fvim-68280725.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But here I am again, trying to do development in Vim.. again… for reasons. Mostly it is because sometimes you just want something more lightweight for coding. Maybe you find yourself in a different language then your normal one, or you just want to bust out a tutorial but you don’t want to have to make a brand new project. Or maybe you just want to see what all the fuss is about. Whatever the reason, it feels like there is a certain amount of knowledge you need even to get started. Even to install the darn thing.&lt;/p&gt;

&lt;p&gt;So, there I was attempting to &lt;a href="https://egghead.io/lessons/react-render-two-elements-side-by-side-with-react-fragments" rel="noopener noreferrer"&gt;push some React&lt;/a&gt; into my backend loving brain when I started down a rabbit hole.&lt;/p&gt;

&lt;p&gt;I opened the code examples in &lt;a href="https://neovim.io/" rel="noopener noreferrer"&gt;Neovim&lt;/a&gt; (which is Vim, but with some spice) but then I realized I probably would want to be able to do some searching through the code examples. To do that you need Plugins. Then if you want those, you probably want a &lt;a href="https://vi.stackexchange.com/questions/388/what-are-the-differences-between-the-vim-plugin-managers" rel="noopener noreferrer"&gt;Plugin Manager.&lt;/a&gt;.. and that there was where my rabbit hole took me. What manager? How do I install the manager? Wait, I need Python? And I am out of date?!? Oof and all I was trying to do was attempt a React tutorial 🤷!&lt;/p&gt;

&lt;p&gt;So upon attempting to open my Neovim editor today with multiple errors from my ill-fated and aborted plugin manager journey from yesterday, I was able to get straightened out with &lt;a href="https://www.chrisatmachine.com/Neovim/01-vim-plug/" rel="noopener noreferrer"&gt;some help from Christian&lt;/a&gt;. He was able to get me straightened out AND I was even able to get Plugins, and a Plugin Manager installed with much less fuss.&lt;/p&gt;

&lt;p&gt;My main problem was installing &lt;a href="https://github.com/junegunn/vim-plug" rel="noopener noreferrer"&gt;vim-plug&lt;/a&gt;, but into Neovim, not plain old Vim. Whenever you do something custom or slightly different (I’m looking at you bash instead of zsh) it always seems like that exponentially adds to the amount of articles you are going to have to wade through to find the answer.&lt;/p&gt;

&lt;p&gt;What I needed to do was create an init.vim file (a configuration file just for Neovim).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch ~/.config/nvim/init.vim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then install vim-plug&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -fLo ~/.config/nvim/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But the important part was where I was putting it, in the &lt;code&gt;.config&lt;/code&gt; folder where my configuration file (init.vim) is at, and into the &lt;code&gt;autoload&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;Then you are all ready to install plugins to your heart content in Neovim.&lt;/p&gt;

&lt;p&gt;Create yourself a new nifty &lt;code&gt;~/.config/nvim/vim-plug/plugins.vim&lt;/code&gt; file. For ex. start with adding a different default file explorer plugin NERDTree&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;call plug#begin('~/.config/nvim/autoload/plugged')

    " File Explorer
    Plug 'scrooloose/NERDTree'

call plug#end()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With your separate plugins file &lt;code&gt;~/.config/nvim/vim-plug/plugins.vim&lt;/code&gt; you need to tell your &lt;code&gt;init.vim&lt;/code&gt; file to use (or source) this file. You can do that by adding the following into &lt;code&gt;init.vim&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;source $HOME/.config/nvim/vim-plug/plugins.vim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let’s install and use this plugin.&lt;/p&gt;

&lt;p&gt;Open up Neovim, in your terminal type in &lt;code&gt;nvim&lt;/code&gt;. Check on your plugins status, one plugin was added into your plugins file but we haven’t actually installed it yet.&lt;/p&gt;

&lt;p&gt;So with Neovim open, hit Esc to go into Command mode. Now this may not be needed but if you are in any other state this like Visual mode this gets you back so you can actually put in commands. From there you run&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Let’s get that plugin installed now, go back into Command mode (hit Esc) and then run&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.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%2Fsylrr8f2mkc3i0z3b5wu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fsylrr8f2mkc3i0z3b5wu.png" width="796" height="282"&gt;&lt;/a&gt;View of vim-plug installing plugins&lt;/p&gt;

&lt;p&gt;That’s it. The plugin is installed! 🙌🏼&lt;br&gt;
You can now update &lt;code&gt;:PlugUpdate&lt;/code&gt; your plugins when you like, and go wild and install some more too.&lt;/p&gt;

&lt;p&gt;I wanted to check on how NERDTress was working, so I went back to my React tutorial directory and low and behold I have files! To use my newly installed plugin, I opened up one of my html files, then typed out &lt;code&gt;:NERDTree&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Ftdr3i1xhd08i0grye3y8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ftdr3i1xhd08i0grye3y8.png" width="800" height="568"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now back to my React learning…phew.&lt;/p&gt;

</description>
      <category>learning</category>
      <category>vim</category>
    </item>
  </channel>
</rss>
