Today I Learned

hashrocket A Hashrocket project

248 posts about #workflow surprise

Markdown alert style content blocks on Github

Use special markdown to emphasize content inside alert style content blocks on Github.

> [!NOTE]  
> Highlights information that users should take into account, even when skimming.

> [!TIP]
> Optional information to help a user be more successful.

> [!IMPORTANT]  
> Crucial information necessary for users to succeed.

> [!WARNING]  
> Critical content demanding immediate user attention due to potential risks.

> [!CAUTION]
> Negative potential consequences of an action.

image

Add metadata to Stripe webhooks using TwiML <Pay>

This is kind of a specific TIL, but hopefully it saves somebody else the time it took me to find the answer.

If you are using the TwiML <Pay> verb there is a noun on <Pay> called <Parameter> which lets you pass parameters to your action.

If your payment provider is Stripe and you want to send custom metadata, you can send a <Parameter> with a name prefaced as metadata_ and it will be added to the Stripe metadata that gets sent out in the webhook.

Here's an example:

<Pay paymentConnector="stripe"> 
   <Parameter name="metadata_testKey" value="value" /> 
</Pay>

and now the object you receive in your webhook will have the following:

"metadata": {
  "testKey": "value"
}

Custom email routing in Github

Is your Github account attached to multiple organizations? Does your primary address associated with Github get inundated with emails/notifications you don't care to find in your personal inbox?

Let me help you out by sorting your Github notification life. Get an email address to which you can flow relevant notifications and associate them with your Github account. Then head on over to Github > Settings > Notifications > Custom Routing

Click "Add new route" and choose an organization and an email address associated with your account.

Github custom routing settings page for notifications

As you can see, I have my primary email address with Github. Still, now all relevant notifications from Hashrocket projects will funnel into my Hashrocket email address.

Log into Github CI server using SSH

Have you ever needed to log into your Github CI run? Is it a flaky test that's hard to reproduce, and the logging output could be more helpful?

You can log into the CI run while it's going. Try out the Github action Debugging with SSH. Utilizing upterm and Tmux, allows for a session that can be logged into.

Add a step like this to your workflow:

name: CI
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Setup upterm session
      uses: lhotari/action-upterm@v1

A cool feature is that it lets you lock down who can log in via SSH keys. Add a limit-access-to-* declaration like so:

name: CI
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Setup upterm session
      uses: lhotari/action-upterm@v1
      with:
        ## limits ssh access and adds the ssh public key for the user which triggered the workflow
        limit-access-to-actor: true
        ## limits ssh access and adds the ssh public keys of the listed GitHub users
        limit-access-to-users: githubuser1,githubuser2

Then, you can log in via your workflow's 'checks' panel.

h/t JackC

Site-specific searching from the address bar

In Chromium based web-browsers (Chrome, Brave, etc.) go into your settings and search for site search.

Once you find the settings, click on Add under Site Search. This will give you a form like so:

image

Search engine is the name that will be displayed in the address bar when searching

Shortcut is the string you type in the address bar that will begin the site-specific searching

URL is the desired search url, putting %s where your search terms will go.

For example, searching through all of the TILs can be done with

https://til.hashrocket.com/?q=%s

Now with this in place, you should be able to something like the following, to quickly view all TILs on a certain topic:

til vim

image

Now you can enjoy easily learning about the thousands of things all the Hashrocketeers have learned for themselves over the years!

How to remove timestamp on screenshots in MacOS

When you take screenshots on MacOS they are saved with a rather long name, like Screenshot 2023-10-18 at 4.13.56 PM

To remove the timestamp making the names shorter just enter this in your terminal:

defaults write com.apple.screencapture "include-date" 0

After doing that go ahead and run this:

killall SystemUIServer

Now your screenshots will just be saved as Screenshot and successive screenshots in the same directory will have a number appended to them. (i.e Screenshot 1, Screenshot 2, etc.)

How to change the screenshot location on MacOS

By default, screenshots on MacOS are saved to the Desktop. To change this to a specific directory:

First, bring up the screenshot utilities by pressing CMD + SHIFT + 5.
Next, click on the Options selector.
Finally, choose a location under Save to

Note: Here is where you can set your screenshot to be on a timer, choose whether or not you want the mouse/cursor to show up on the screenshots, and a change few other options.

Skip auto updates for brew install/upgrade/tap

I think we've all been there. You're right in the middle of something, you need to brew install a formula, you go to install the formula, and then all of a sudden you're greeted with:

Running `brew update --auto-update`...

and so now you have to wait for all of your formulae to update, just so you can use the one that you need.

Well, if you're in a rush or on a slow internet connection, you can skip the auto update by setting the env var HOMEBREW_NO_AUTO_UPDATE to 1.

HOMEBREW_NO_AUTO_UPDATE=1 brew install <formula>

You might find it helpful to throw this into an alias so that you can brew install without updates when you're in a rush, without needing to remember the name of the env var.

From the official docs:

HOMEBREW_NO_AUTO_UPDATE:
If set, Homebrew will not auto-update before running brew install, brew upgrade or brew tap.

Place screenshot straight to clipboard on Mac

Taking a screenshot is super helpful and there are many ways to do it. My go to on the Mac is the keyboard shortcut cmd+shift+4. This brings up a crosshair to select which part of the screen you want.

When you're done selecting you the image will be added to wherever you've configured screenshots to go. Normally the default is directly to your Desktop.

To add this screenshot directly to your pastebin you can do an alternate shortcut of cmd+ctrl+shift+4. Then you can just paste the image wherever as soon as you're done. This is awesome but is a hard keystroke for me. However I discovered that you can use the original cmd+shift+4 to activate the crosshair but it can be redirected to the pastebin if you hold ctrl before you click to finalize the screenshot'd section.

Hooray!

Modifier Keys with Hot Corners

If you don't know what Hot Corners are, check out this post.

Say you want to utilize the Hot Corner for Lock Screen, but don't want to type in your password every time you accidentally hit the corner of your screen. Well, you can add modifier keys when selecting a hot key.

To do this, simply hold down your preferred modifier key (Command, Shift, Option, or Control , or a combination of these keys) while selecting a shortcut from the dropdown. Now whenever you move your pointer into the corner of the screen, your shortcut won't fire unless you're also holding down that modifier key.

MacOS Hot Corners

On macOS you can take advantage of Hot Corners, which are shortcuts activated by moving your pointer into a corner of the screen.

Currently, you can only select from a handful of options, such as Mission Control, Launchpad, Lock Screen, Quick Note and a few others.

To customize each of the four corners, on macOS Ventura 13, it can be found under System Settings->Desktop & Dock->Hot Corners

If you're on a different version, you can see exactly where the setting is located here.

Easily connect to postgres via proxy with service

A client has their RDS postgresql databases locked down to only allow connection from their EC2 instances. I found an easy way to connect with my local clients.

Add a local forward to ssh config

In ~/.ssh/config add something like

Host prod.client
  User ubuntu
  Hostname prod-ec2-instance.example.com
  LocalForward localhost:5433 rds-gibberish.us-west-1.rds.amazonaws.com:5432
  IdentityFile ~/production-ec2-key.pem

Add the credentials to pg service

In ~/.pg_service.conf save the user, database name, and password

[client-prod]
host=localhost
port=5433
user=rds-user
dbname=client-production
password=blablabla

Now you can start your ssh tunnel in 1 terminal:

ssh prod.client

And connect with any postgres client tool (pg_dump, psql, etc.) in another:

psql service=client-prod

warning

Well you just saved a production password to a plain text file, and now you can easily connect and muck things up in production. Make sure your machine is secure and be careful and stuff.

Android crash logs

You can get android crash logs with adb

adb logcat --buffer=crash 

03-30 07:53:59.221 23769 23769 E AndroidRuntime: FATAL EXCEPTION: main
03-30 07:53:59.221 23769 23769 E AndroidRuntime: Process: expo.modules.mymodule.example, PID: 23769
03-30 07:53:59.221 23769 23769 E AndroidRuntime: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
03-30 07:53:59.221 23769 23769 E AndroidRuntime:    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:448)
03-30 07:53:59.221 23769 23769 E AndroidRuntime:    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:810)
03-30 07:53:59.221 23769 23769 E AndroidRuntime: Caused by: java.lang.reflect.InvocationTargetE

Chrome has a command palette

I had no idea that Google Chrome had a command palette!

Once your dev tools are open, you can activate through the interface by clicking the 'more' icon and then 'Run command' like so:

or by cmd+shift+p (on a mac). Coincidentally this is the same keyboard shortcut as the command palette in Visual Studio Code

Now you'll see the palette which gives you direct access to a lot of Chrome's hidden functionality!

image

Duplicating tabs in iTerm

If you want to open a new tab in iTerm in your same working directory, you can use the following steps:

  1. Navigate to preferences or use (⌘,).
  2. Click on the Keys settings.
  3. Hit + in the bottom left corner to add a new shortcut.
  4. Record a shortcut of your choosing
  5. Using the dropdown menu for Action: select 'Duplicate Tab"

Now your new shortcut will open a new iTerm tab in whatever directory you have currently open.

Saving screenshots to clipboard on Mac

Have you ever needed to take a screenshot just to send it to somebody, but then you are left with the cumbersome chore of having to actually delete the screenshot before they pile up on your desktop like a pile of dirty laundry?

Well, I am here to save you those 5 seconds you've been missing out on so you can enjoy that next sip of coffee--guilt free.

When taking a screenshot with CMD + shift + 3, hold down control as well.

When taking a screenshot with CMD + shift + 4, hold down control while dragging the crosshairs to select a section of screen to capture.

Now, instead of saving to your default screenshot location, it will just copy it to your clipboard. You can now just paste the image into your message with no cleanup necessary.

TL;DR
Hold down control when taking a screenshot to copy it to the clipboard.

Use encrypted env vars with direnv

Direnv can execute shell scripts, so given that your env file is encrypted, you can automatically have it become decrypted for you:

───────┬──────────────────────
       │ File: .env
───────┼──────────────────────
   1   │ STRIPE_PK="123456789"
   2   │ API_KEY="qwertyuiop"
───────┴──────────────────────

Say is was encrypted:

ansible-vault encrypt --vault-password-file config/master.key .env
cat .env
───────┬─────────────────────────────────────────────────────────────────────────────────
       │ File: .env
───────┼─────────────────────────────────────────────────────────────────────────────────
   1   │ $ANSIBLE_VAULT;1.1;AES256
   2   │ 35306466356632363334643432343132356662376462333964366534393462366333623764336161
   3   │ 6131336435323834623539323462626235383330346562660a323534656133653237656634346235
   4   │ 30653635663438313931393966383266663535313361613339396234373164323830373262633661
   5   │ 6262356131306530350a643362623636323762656132326363323736633431396463616137343139
   6   │ 66666438623230333636373563393165333562633964616536663363323334343235386465346663
   7   │ 3365643263643766323835356230636539353034643034346136
───────┴─────────────────────────────────────────────────────────────────────────────────

Now that we have an encrypted .env file, we just need direnv to decrypt it whenever we're in our directory:

───────┬────────────────────────────────────────────────────────────────────────────────────────────────
       │ File: .envrc
───────┼────────────────────────────────────────────────────────────────────────────────────────────────
   1   │ export $(ansible-vault decrypt --vault-password-file config/master.key --output - .env | xargs)
───────┴────────────────────────────────────────────────────────────────────────────────────────────────

Output:

$ cd rails_app
direnv: loading ~/dev/rails_app/.envrc
direnv: export +API_KEY +STRIPE_PK
echo $API_KEY
qwertyuiop

Now whenever we enter the directory, we will have the unencrypted env vars, but the file remains encrypted on disk. For whatever that's worth.

Resize Window Keyboard Shortcuts in Windows 10

After using Magnet, a window manager in OSX, I remembered hearing that there was a similar facility built into Windows. Turns out, they are very easy-to-remember shortcuts for resizing windows.

  • Win + Right Arrow - Snap to right half of screen**
  • Win + Left Arrow - Snap to left half of screen**
  • Win + Up Arrow - Maximize current window
  • Win + Down Arrow - Minimize window if not currently maximized

**(will maximize the window if it is currently split on the opposite side of the screen)

There's a few others too, but these 4 I'm finding super useful. If you're interested in other Windows shortcuts, I found some other cool ones in this Lifewire article

Keep 5 most recent files in a directory

One can keep the most recent n files in a directory with just three shell programs: ls, tail, and xargs.

Here is an example to use in a nightly database backup cron job:

#!/bin/bash
# Keep last 5 files ending in .dump
# Don't forget to 

# Installation
# 1. cp pg-backups.sh /usr/local/bin/
# 2. chmod u+x /usr/local/bin/pg-backups.sh
# 3. Set the DB variable
# 4. Set the BACKUP_DIR variable

# Example usage for cron to run at 4:05 am every day:
# 5 4 * * * /usr/local/bin/pg-backups.sh

DB=mydatabase
BACKUP_DIR=/mnt/object/production/db-backups

DATE=$(date "+%Y-%m-%d_%H%M")
pg_dump -Fc $DB > $BACKUP_DIR/$DATE.dump

/bin/ls -t $BACKUP_DIR/*.dump | tail +6 | xargs rm

How to install sqlite3 on heroku

Using sqlite to persist data is superfluous on heroku, duh, but sometimes a third party service wants my rails app to read configuration in a sqlite db file. In order to read the read-only database file, I need to install the sqlite3 gem. To get this to work on heroku I needed to do two things:

  1. Install the apt buildpack
  2. Add an Aptfile in the root of the project
heroku buildpacks:add --index 1 heroku-community/apt

Then create an apt file:

# Aptfile
libsqlite3-dev
libsqlite3-0

Enable key repeat in VSCode

Even if your operating system enables key repeat, VSCode will disable it. To turn it on you need to update a default value and restart vscode:

defaults write com.microsoft.VSCode ApplePressAndHoldEnabled -bool false
osascript -e 'tell application "Visual Studio Code" to quit'
osascript -e 'tell application "Visual Studio Code" to activate'