Nice way to run a dev env

AI-generated summary

NateDhaliwal shared a script, rundiscourse.sh, designed to simplify the process of updating and starting a local Discourse development environment. The script automates fetching updates for Discourse core, plugins, running migrations, and starting the Ember server. It utilizes git pull, bundle install, pnpm install, and bin/rails db:migrate. The script also includes setup instructions for a terminal alias.

elmuerte provided several improvements to the script, including using #!/usr/bin/env sh for portability, adding set -e to halt execution on errors, and more robustly handling plugin git pull operations, including redirecting STDERR to STDOUT and checking exit codes. elmuerte also suggested simplifying the script by removing unnecessary cd commands and variable assignments. NateDhaliwal acknowledged the suggestions and plans to implement them.

Hi everyone, just sharing a handy script I’ve put together that helps me run my Discourse dev instance.

It pulls all the latest changes, pulls the updates from installed plugins, and runs all the migrations, as well as installing the necessary gems and pnpm packages.

The downside to the script is that it also pulls the plugins bundled with core, which technically wouldn’t do anything since they would be updated with the first git pull. Oh well.

Note: chatgpt.com helped me write the if statement logic (my initial experiments failed).
~/rundiscourse.sh:

#!/bin/bash

cd ~/discourse
git pull
cd plugins
PLUGIN_DIR=~/discourse/plugins

for folder in "$PLUGIN_DIR"/*; do
  if [ -d "$folder/.git" ]; then
    output=$(git -C "$folder" pull)
    if ! echo "$output" | grep -q "Already up to date."; then
      echo "[$(basename "$folder")] $output"
    fi
  fi
done
cd ~/discourse
bundle install
pnpm install
bin/rails db:migrate
DISCOURSE_HOSTNAME=localhost UNICORN_LISTENER=localhost:3000 bin/ember-cli -u

Then, run:

chmod +x rundiscourse.sh

Then, go to the ~/.bashrc file (using nano, or anything), and add this bit if you don’t already have it (it’s nearer the bottom)

# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.

if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

Then, add the following to the ~/.bash_aliases file:

alias discourse="~/rundiscourse.sh"

Close your terminal and re-open it.
Now, when you run discourse in the terminal, your development environment should start!


I hoped this helped! Also, do let me know if I’m doing something wrong, or if it can be improved. Thanks!

1 Like

Nice. A couple of suggestions.

The shebang should be #!/usr/bin/env sh, which is the most portable. The script doesn’t use any bash’isms so it should work in any Bourne shell compatible shell, not just bash.

After the shebang add set -e. This will cause the script to exit if any of the commands fail. Otherwise it will happily continue executing commands and failing later on because something like bundle install failed, and the error output is now gone from the user’s screen.

Now the plugin git pull is a bit more problematic as errors written to STDERR and a failing git execution will not be properly handled. So I pushed STDERR also to STDOUT and kept track of the exit code

No need for a bunch of cd commands, or setting the PLUGIN_DIR variable.

#!/usr/bin/env sh
set -e

cd ~/discourse
git pull

for folder in plugins/*; do
  if [ -d "$folder/.git" ]; then
    exitcode=0
    output=$(git -C "$folder" pull 2>&1) || exitcode=$?
    if echo "$output" | grep -q -v "Already up to date."; then
      echo "[$(basename "$folder")]"
      echo "$output"
      [ "$exitcode" -ne 0 ] && exit "$exitcode"
    fi
  fi
done

bundle install
pnpm install
bin/rails db:migrate
DISCOURSE_HOSTNAME=localhost UNICORN_LISTENER=localhost:3000 bin/ember-cli -u

I already had a similar script, except for the git pulling as I don’t want that to happen every time.

1 Like

Thanks for the insight! I’ll give that a shot.