Here-doc headache

I was working on the deployment pipeline for a service that launches an app in a dedicated VM using GitHub Actions. In the last step of the workflow, the CI SSHs into the VM and runs several commands using a here document in bash. The simplified version looks like this: # SSH into the remote machine and run commands to deploy the service ssh $SSH_USER@$SSH_HOST <<EOF # Go to the work directory cd $WORK_DIR # Make a git pull git pull # Export environment variables required for the service to run export AUTH_TOKEN=$APP_AUTH_TOKEN # Start the service docker compose up -d --build EOF The fully working version can be found in the serve-init repo with here-doc. ...

July 19, 2024

The sane pull request

One of the reasons why I’m a big advocate of rebasing and cleaning up feature branches, even when the changes get squash-merged to the mainline, is that it makes the PR reviewer’s life a little easier. I’ve written about my rebasing workflow before and learned a few new things from the Hacker News discussion around it. While there’s been no shortage of text on why and how to craft atomic commits, I often find those discussions focus too much on VCS hygiene, and the main benefit gets lost in the minutiae. When working in a team setup, I’ve discovered that individual commits matter much less than the final change list. ...

July 14, 2024

I kind of like rebasing

People tend to get pretty passionate about Git workflows on different online forums. Some like to rebase, while others prefer to keep the disorganized records. Some dislike the extra merge commit, while others love to preserve all the historical artifacts. There’s merit to both sides of the discussion. That being said, I kind of like rebasing because I’m a messy committer who: Usually doesn’t care for keeping atomic commits. Creates a lot of short commits with messages like “fix” or “wip”. Likes to clean up the untidy commits before sending the branch for peer review. Prefers a linear history over a forked one so that git log --oneline --graph tells a nice story. Git rebase allows me to squash my disordered commits into a neat little one, which bundles all the changes with passing tests and documentation. Sure, a similar result can be emulated using git merge --squash feat_branch or GitHub’s squash-merge feature, but to me, rebasing feels cleaner. Plus, over time, I’ve subconsciously picked up the tricks to work my way around rebase-related gotchas. ...

June 18, 2024

Building a CORS proxy with Cloudflare Workers

Cloudflare absolutely nailed the serverless function DX with Cloudflare Workers. However, I feel like it’s yet to receive widespread popularity like AWS Lambda since as of now, the service only offers a single runtime - JavaScript. But if you can look past that big folly, it’s a delightful piece of tech to work with. I’ve been building small tools with it for a couple of years but never got around to writing about the immense productivity boost it usually gives me whenever I need to quickly build and deploy a self-contained service. ...

May 21, 2023

Periodic readme updates with GitHub Actions

I recently gave my personal blog a fresh new look and decided it was time to spruce up my GitHub profile’s landing page as well. GitHub has a special way of treating the README.md file of your repo, displaying its content as the landing page for your profile. My goal was to showcase a brief introduction about myself and my work, along with a list of the five most recent articles on my blog. Additionally, I wanted to ensure that the article list stayed up to date. ...

May 4, 2023

Auditing commit messages on GitHub

After reading Simon Willison’s amazing piece on how he builds a feature, I wanted to adopt some of the good practices and incorporate them into my own workflow. One of the highlights of that post was how to kick off a feature work. The process roughly goes like this: Opening a new GitHub issue for the feature in the corresponding repository. Adding a rough description of the feature to the issue. Creating a feature branch off of main/master/trunk. If the feature is trivial or just a doc update, this step can be skipped. Referring to the issue in every commit message as you start working on the feature: Appending #refs <issue-number> to every commit message. This will attach the commit to the concerning issue on the GitHub UI. Appending #closes <issue-number> to the final commit message when the feature is complete. If you need to refer to an issue after it’s closed, you can still do that by appending #refs <issue-number> to the commit message. So a commit message should look similar to Feature foo, refs #120 or Update foo, closes #115. The comma (,) before refs/closes is essential here. I like to enforce it. This pattern also works for bugfixes without any changes. Here’s an example issue that shows the workflow in action. Plus, I follow a similar pattern to write the blogs on this site as well. This is what a feature issue might look like on GitHub: ...

October 6, 2022

When to use 'git pull --rebase'

Whenever your local branch diverges from the remote branch, you can’t directly pull from the remote branch and merge it into the local branch. This can happen when, for example: You checkout from the main branch to work on a feature in a branch named alice. When you’re done, you merge alice into main. After that, if you try to pull the main branch from remote again and the content of the main branch changes by this time, you’ll encounter a merge error. Reproduce the issue Create a new branch named alice from main. Run: ...

July 14, 2022

Automerge Dependabot PRs on GitHub

Whether I’m trying out a new tool or just prototyping with a familiar stack, I usually create a new project on GitHub and run all the experiments there. Some examples of these are: rubric: linter config initializer for Python exert: declaratively apply converter functions to class attributes hook-slinger: generic service to send, retry, and manage webhooks think-async: exploring cooperative concurrency primitives in Python epilog: container log aggregation with Elasticsearch, Kibana & Filebeat While many of these prototypes become full-fledged projects, most end up being just one-time journies. One common theme among all of these endeavors is that I always include instructions in the readme.md on how to get the project up and running - no matter how small it is. Also, I tend to configure a rudimentary CI pipeline that runs the linters and tests. GitHub Actions and Dependabot make it simple to configure a basic CI workflow. Dependabot keeps the dependencies fresh and makes pull requests automatically when there’s a new version of a dependency used in a project. ...

July 7, 2022

Github action template for Python based projects

Five traits that almost all the GitHub Action workflows in my Python projects share are: If a new workflow is triggered while the previous one is running, the first one will get canceled. The CI is triggered every day at UTC 1. Tests and the lint-checkers are run on Ubuntu and MacOS against multiple Python versions. Pip dependencies are cached. Dependencies, including the Actions dependencies are automatically updated via Dependabot. I use pip-tools for managing dependencies in applications and setuptools setup.py combo for managing dependencies in libraries. Here’s an annotated version of the template action syntax: ...

March 2, 2022