Bash alias to switch between recent branches
If you have fzf installed, you may add an alias such as this to your ~/.bashrc
:
alias recent-branch="git for-each-ref --sort=-committerdate --format='%(refname:short)' refs/heads/ | fzf | sed 's/\* //g' | xargs -I '{}' git checkout {}"
alias rb=recent-branch
Now whenever you want to switch back and forth between your most recent branches, type recent-branch
, select one and press enter.
Upgrading Rails 2 from 2.3.8 through 2.3.18 to Rails LTS
This card shows how to upgrade a Rails 2 application from Rails 2.3.8 through every single patch level up to 2.3.18, and then, hopefully, Rails LTS.
2.3.8 to 2.3.9
This release has many minor changes and fixes to prepare your application for Rails 3.
Step-by-step upgrade instructions:
- Upgrade
rails
gem - Change your
environment.rb
so it saysRAILS_GEM_VERSION = '2.3.9'
- Change your ...
Updating a gem created with Bundler
Since May 2011 we are cutting new gems using Bundler, which is less painful than cutting gems using Jeweler. You know a gem was cut using Bundler if you see the word Bundler
in a gem project's Rakefile
.
This is how to update a gem that was cut using Bundler:
- Say
git pull
or check out a repository from Github likegit clone git@github.com:makandra/geordi.git
- Update the gem version in `lib/project...
Rails: How to restore a postgres dump from the past
It sometimes happen that a database dump, that would want to insert into your development database, does not match the current schema of the database. This often happens when you have an old dump, but your current setup is up to date with the the master.
Hint: In most cases it is sufficient to delete and recreate the local database in order to import the dump. If any problems occur, proceed as follows:
1. Figure out the original migration status of the dumpfile
- Convert your dump to plaintext: `pg_restore -f some.dump > some.dump....
Bundler 2.3 honors the version specified in `BUNDLED_WITH`
Bundler so far ignored the version specified under BUNDLED_WITH
in the Gemfile.lock
. This had two annoying consequences:
- If the bundler version on your system was lower than in the
Gemfile.lock
, you got an error message and had to manually install the correct version. - If the bundler version on your system was higher than in the
Gemfile.lock
, bundler silently updated the version in theGemfile.lock
to your system's bundler version. To avoid this, you had to always specify, which version you want to use for each bundler c...
Fix for mysql2 error "Incorrect MySQL client library version! This gem was compiled for x.x.x but the client library is y.y.y."
This should be fixed in the latest LTS-branches of our mysql2 fork, 0.2.x-lts and 0.3.x-lts.
Use
gem 'mysql2', git: 'https://github.com/makandra/mysql2', branch: '0.2.x-lts' # for Rails 2.x
gem 'mysql2', git: 'https://github.com/makandra/mysql2', branch: '0.3.x-lts' # for Rails 3.x
in your Gemfile, and do a
bundle update mysql2
Background
mysql2 used to check that the client library used at runtime actually matches the one it was compiled against. However, at least on Ubunt...
Run all RSpec tests edited or added in the current branch
With this command you can run all the spec files which have been edited or added in the current branch since master:
git diff --name-only master -- ./spec | xargs -I{} rspec {}
- If you have several spec folders add them for path parameter after
./spec
accordingly. - The option
-I{}
creates a placeholder to be replaced. - You can also compare edited/added specs between commits with
<commit>..<commit>
Manage your AWS credentials for multiple accounts
Create a directory mkdir ~/.aws
Initialise git repository cd ~/.aws && git init
Create a git branch with a name you want (e.g. development
for the aws development account credentials).
Add AWS credential file .aws_credentials
:
AWSAccessKeyId=ABCDEFG1234
AWSSecretKey=4321GFEDCBA
Also add your EC2 cert and private key file.
You can add other AWS account depending files like .fog
or .guignol.yml
too.
Create symlinks for some config files like .aws_credentials
and .fog
:
ln -s ~/.aws/.aws_credentials ~/.aws_cred...
Force GitHub Pull Requests to update the diff against its target branch
When you have a Pull Request on GitHub that includes commits from another Pull Request, you will still see them after the "child" PR has been merged. Unfortunately, GitHub won't automatically update the diff (or commit list).
Here is what worked for me:
- Check out the target branch
git checkout my-target-branch
- Make sure you are up to date against origin (e.g.
git fetch
andgit status
). You should be 0 commits ahead or behind.
- Add and commit a file
touch .please-update
git add .please-update
- `gi...
Installing old versions of mysql2 on Ubuntu 20.04+
On some of our older projects, we use the mysql2 gem. Unfortunately, versions 0.2.x (required for Rails 2.3) and versions 0.3.x (required for Rails 3.2) can no longer be installed on Ubuntu 20.04. Trying this either leads to errors when compiling the native extension, or a segfaults when using it.
For Rails 4.2, mysql2 version 0.4.10 seems to work okay. If you still have issues, upgrade to 0.5.x, which should be compatible.
To install it, you have to switch the mysql2 gem to our fork. In your Gemfile, ...
Prefer using Dir.mktmpdir when dealing with temporary directories in Ruby
Ruby's standard library includes a class for creating temporary directories. Similar to Tempfile it creates a unique directory name.
Note:
- You need to use a block or take care of the cleanup manually
- You can create a prefix and suffix e.g.
Dir.mktmpdir(['foo', 'bar']) => /tmp/foo20220912-14561-3g93n1bar
- You can choose a different base directory than
Dir.tmpdir
e.g. `Dir.mktmpdir('foo', Rails.root.join('tmp')) => /home/user/rails_example/tmp/foo20220912-14...
Local deployment after pipeline succeeds
If you have a fully functional CI pipeline but no CD, you might find yourself frequently waiting for CI (with "merge after pipeline succeeds") just to perform the deployment.
The following command waits for the next commit that lands on the current branch (should be main
or similar) and proceeds to deploy staging afterwards:
alias await-deployment='watch -g git pull && bundle exec cap staging deploy'
Note
Use at your own risk.
You could be deploying code from someone else that was pushed to the same branch in the meantime.
Speed up Capistrano deployments using a remote cached copy of repository
You can seriously speed up deployments with Capistrano when using a local git repository on the server you are deploying to.
Simply add
set :deploy_via, :remote_cache
set :copy_exclude, [ '.git' ]
to your config/deploy.rb
and Capistrano will create a clone in shared/cached-copy
. This will be updated using git pull
when deploying which transfers less bytes and is usually much faster. If deploy_via
is set to use default settings (being "export
"), Capistrano will do a full clone of the repository from your git host otherwi...
Automatically build sprites with Lemonade
How it works
See the lemonade descriptions.
Unfortunately, the gem has a few problems:
- it does not work with Sass2
- it always generates all sprites when the sass file changes, which is too slow for big projects
- it expects a folder structure quite different to our usual
All these problems are solved for us, in our own lemonade fork. This fork has since been merged to the original gem, maybe we can use t...
rbenv: How to update list of available Ruby versions on Linux
When you tell rbenv to install a Ruby it does not know about, you will get an error message.
$ rbenv install 2.1.2
ruby-build: definition not found: 2.1.2
You can list all available versions with `rbenv install --list'.
If the version you're looking for is not present, first try upgrading
ruby-build. If it's still missing, open a request on the ruby-build
issue tracker: https://github.com/sstephenson/ruby-build/issues
(Fun fact: Recent versions of ruby-build will give you a more helpful error message which...
Protip: Clone large projects multiple times
Large projects usually have large test suites that can run for a long time.
This can be annoying as running tests blocks you from picking up the next story -- but it doesn't have to be that way!
Simply clone your project's repo twice (or even more often).
When your work on a feature branch is done, simply push that branch and check it out on your 2nd copy to run tests there.
You can pick up a new story and work on that on your "main" project directory.
If you do it right, you will even be able to run tests in both your 2nd copy and your m...
Upgrading from Capistrano 2 to 3
Capistrano 3 is a major rework of the framework and requires several adjustments to your deploy configuration files. The biggest change is that they moved away from their custom DSL and use Rake
instead. For connecting with and operating on the servers, they bring a new gem SSHKit
which does the heavy lifting. It's SSHKit's DSL that is used anywhere inside the Rake tasks. See #Resources at the bottom for examples.
Step 1: Upgrade guide
For migration from 2 to 3, follow this tutorial: [Capistrano 3 Upgrade Guide](https://semaphorec...
How to revert features for deployment, merge back, and how to stay sane
Removing features and merging those changes back can be painful. Here is how it worked for me.\
tl;dr: Before merging back: reinstate reverted features in a temporary branch, then merge that branch.
Scenario
Consider your team has been working on several features in a branch, made many changes over time and thus several commits for each feature.\
Now your client wants you to deploy while there are still stories that were rejected previously and can't be deployed.
...
Capistrano + Rails: Tagging production deploys
Just like Ruby Gems tag their version releases to the corresponding Git commit, it can be helpful to track production deploys within the commit history. This task does the tagging for you.
Capistrano 3
# lib/capistrano/tasks/deploy.rb
namespace :deploy do
...
desc 'Tag the deployed revision'
task :tag_revision do
date = Date.today.to_s
puts `git tag deploy-#{date} #{fetch :current_revision}`
puts `git push --tags origin`
end
end
# config/deploy/production.rb
after 'deploy:finished', 'deploy:tag_revi...
Fix: esbuild assets are missing after capistrano deploy
Issue: You have an app using jsbundling-rails and esbuild. After deploy, the assets built by esbuild are missing in public/assets.
Solution: Add app/builds
to your git repo (by adding a app/builds/.keep
file).
Something in sprockets is caching paths and refuses to accept files in "unknown" locations.
Migrate gem tests from Travis CI to Github Actions with gemika
We currently test most of our gems on Travis CI, but want to migrate those tests to Github Actions. This is a step-by-step guide on how to do this.
Note that this guide requires the gem to use gemika.
- Go to a new "ci" branch:
git checkout -b ci
- Update gemika to version >= 0.5.0 in all your Gemfiles.
- Have gemika generate a Github Actions workflow definition by running
mkdir -p .github/workflows; bundle exec rake gemika:generate_github_actions_workflow > .github/workf...
Bash script to list commits by Pivotal Tracker ID
The main benefit of our convention to prefix commits by their corresponding Pivotal Tracker ID is that we can easily detect commits that belong to the same story. You can either do that manually or use the bash script below by copying it somewhere to your .bashrc
.
# Usage: ptcommits 123456
function ptcommits {
if test "$1"
then
local PTID=$(echo "$1" | grep "[0-9]*" -o) # Allow URLs
git log --onel...
Hack of the day: One-liner to run all changed Cucumber features
Similar to our snippet that runs all Cucumber features matching a given string, the following will run all modified or new Cucumber features by looking at your git status:
git status --short | grep -v '^ D ' | grep '.feature' | sed 's/.. //' | tr '\n' ' ' | xargs geordi cucumber
If you want to know what each of the above commands does, see [explainshell](http://explainshell.com/explain?cmd=git+status+--short+%7C+grep+-v+%27%5E+D+%27+%7C+grep+%27.feature%27+%7C+sed+%27s%2F..+%2F%2F%27+%7C+tr+%27%5Cn%27+%27+%27+%7C...
MongoMapper for Rails 2 on Ruby 1.9
MongoMapper is a MongoDB adapter for Ruby. We've forked it so it works for Rails 2.3.x applications running on Ruby 1.9. [1]
makandra/mongomapper
is based on the "official" rails2
branch [2] which contains commits that were added after 0.8.6 was released. Tests are fully passing on our fork for Ruby 1.8.7, REE, and Ruby 1.9.3.
To use it, add this to your Gemfile
:
gem 'mongo_mapper', :git => 'git://github.com/makandra/mongomapper.git', :branch => 'rails2'
...