diff --git a/.tool-versions b/.tool-versions
index ee99ed180e..6637ef1256 100644
--- a/.tool-versions
+++ b/.tool-versions
@@ -6,5 +6,4 @@ erlang 26.2.5
flyctl 0.2.65
golang 1.22.4
nodejs 20.14.0
-postgres 16.3
yarn 1.22.22
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 67017a5e04..70a63d9aa4 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -78,7 +78,7 @@ Create a new pull request via https://github.com/thechangelog/changelog.com
## How do I run the application locally?
-You will need to have the following dependencies installed:
+You will need to have the following system dependencies installed:
- [PostgreSQL](https://www.postgresql.org/download/) v16
- [Elixir](https://elixir-lang.org/install.html) v1.16
- [Erlang/OTP](https://www.erlang.org/downloads) v26 - usually installed as an Elixir dependency
@@ -86,60 +86,36 @@ You will need to have the following dependencies installed:
- [Yarn](https://yarnpkg.com/getting-started/install) v1.22
- [Golang](https://go.dev/doc/install) v1.22 - if you want to run CI locally
-We are using [`asdf`](https://asdf-vm.com/) to install the correct dependency versions in our development environment.
+We are using [`just`](https://github.com/casey/just) to manage `brew` & `asdf` which in turn manage all app dependencies for development.
-This is what that looks like on macOS 12, our usual development environment:
-
-
+Once you have [`just` installed](https://github.com/casey/just?tab=readme-ov-file#installation), running `just` in the root of this repository will produce the following output:
```console
+Available recipes:
+ contribute # Setup everything needed for your first contribution
+ deps # Get app dependencies
+ dev # Run app in dev mode
+ install # Install all system dependencies
+ postgres-down # Stop Postgres server
+ postgres-up # Start Postgres server
+ test # Run app tests
+```
-# 🛠 INSTALL DEPENDENCIES 🛠
-awk '{ system("asdf plugin-add " $1) }' < .tool-versions
-# icu4c required by https://github.com/smashedtoatoms/asdf-postgres
-PKG_CONFIG_PATH="$(brew --prefix)/opt/icu4c/lib/pkgconfig" asdf install
-
-#👇 installed on a MacBook Pro 16" (2021) running macOS 12.7.1 in ~4mins on Dec 16, 2023 by @gerhard
-# - Elixir v1.14.5
-# - Erlang v26.2
-# - Golang 1.20.12
-# - Node.js v20.10.0
-# - Yarn v1.22.19
-# - PostgreSQL v16.1
-#👆 installed on a MacBook Pro 16" (2021) running macOS 12.7.1 in ~4mins on Dec 16, 2023 by @gerhard
-
-# You will also need to install imagemagick via Homebrew.
-# asdf imagemagick plugin did not work for me.
-brew install imagemagick
-
-# 🪣 CONFIGURE DATABASE 🪣
-# Start PostgreSQL
-postgres # or pg_ctl start
-# Create changelog_dev db owned by the postgres user
-createdb changelog_dev --username=postgres
-# Create changelog_test db owned by the postgres user
-createdb changelog_test --username=postgres
-
-# 💜 CONFIGURE APP 💜
-# Install deps
-mix deps.get --only dev
-mix deps.get --only test
-# Prepare dev database
-mix ecto.setup
+The only command that you need to run is `just contribute`.
+As per the description, this will setup everything needed for your first contribution:
+- installs all system dependencies (Postgres, Elixir, etc.)
+- downloads app (Elixir) dependencies
+- starts Postgres
+- runs app tests
+- runs app in dev mode
-# 🌈 CONFIGURE STATIC ASSETS 🌈
-cd assets
-# Install dependencies requires for static assets
-yarn install
-cd ..
+When the above succeeds, this is the end-result that you can expect to see on macOS 12, our team's development environment of choice:
-# 🏃 RUN APP 🏃
-mix phx.server
-# Go to http://localhost:4000
+
-# 🏋️ TESTS 🏋️
-mix test
-```
+> [!TIP]
+> 1. If you want to see what a full setup on a blank MacBook Pro looks like, you can [watch this 3 minutes-long video](https://github.com/thechangelog/changelog.com/pull/521).
+> 2. All the above works equally well on a Debian-based Linux distribution (tested on Ubuntu 22.04 & 24.04).
## How to upgrade 💜 Elixir, 🚜 Erlang/OTP & ⬢ Node.js?
diff --git a/changelog-local-dev-2022.png b/changelog-local-dev-2022.png
deleted file mode 100644
index ba2f4978a3..0000000000
Binary files a/changelog-local-dev-2022.png and /dev/null differ
diff --git a/changelog-local-dev-2024.png b/changelog-local-dev-2024.png
new file mode 100644
index 0000000000..0e503f7451
Binary files /dev/null and b/changelog-local-dev-2024.png differ
diff --git a/config/dev.exs b/config/dev.exs
index 7c7baeed32..785177e3e6 100644
--- a/config/dev.exs
+++ b/config/dev.exs
@@ -5,7 +5,7 @@ config :changelog, ChangelogWeb.Endpoint,
http: [port: port, ip: {0, 0, 0, 0, 0, 0, 0, 0}],
url: [host: System.get_env("HOST", "localhost")],
check_origin: false,
- static_url: [path: "/static"],
+ static_url: [host: System.get_env("HOST", "localhost"), path: "/static"],
debug_errors: true,
code_reloader: true,
cache_static_lookup: false,
diff --git a/justfile b/justfile
new file mode 100644
index 0000000000..7e383c2807
--- /dev/null
+++ b/justfile
@@ -0,0 +1,185 @@
+# vim: set tabstop=4 shiftwidth=4 expandtab:
+
+[private]
+default:
+ just --list
+
+[private]
+fmt:
+ just --fmt --check --unstable
+
+[private]
+brew:
+ @which brew >/dev/null \
+ || (echo {{ GREEN }}🍺 Installing Homebrew...{{ RESET }} \
+ && NONINTERACTIVE=1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" \
+ && echo {{ REDB }}{{ WHITE }} 👆 You must follow NEXT STEPS above before continuing 👆 {{ RESET }})
+
+[private]
+brew-linux-shell:
+ @echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"'
+
+[private]
+just: brew
+ @[ -f $(brew--prefix)/bin/just ] \
+ || brew install just
+
+[private]
+just0:
+ curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | sudo bash -s -- --to /usr/local/bin
+
+[private]
+imagemagick: brew
+ @[ -d $(brew --prefix)/opt/imagemagick ] \
+ || brew install imagemagick
+
+PGPATH := "PATH=$(brew --prefix)/opt/postgresql@16/bin:" + env_var("PATH")
+PGDATA := "PGDATA=$(brew --prefix)/var/postgresql@16"
+PG := PGPATH + " " + PGDATA
+
+[private]
+postgres: brew
+ @[ -d $(brew --prefix)/opt/postgresql@16 ] \
+ || brew install postgresql@16
+
+[private]
+gpg: brew
+ @[ -d $(brew --prefix)/opt/gpg ] \
+ || brew install gpg
+
+# https://tldp.org/LDP/abs/html/exitcodes.html
+[private]
+asdf:
+ @which asdf >/dev/null \
+ || (brew install asdf \
+ && echo {{ REDB }}{{ WHITE }} 👆 You must follow CAVEATS above before continuing 👆 {{ RESET }})
+
+[private]
+asdf-shell: brew
+ @echo "source $(brew --prefix)/opt/asdf/libexec/asdf.sh"
+
+# Install all system dependencies
+install: asdf brew imagemagick postgres gpg
+ @awk '{ system("asdf plugin-add " $1) }' < .tool-versions
+ @asdf install
+
+export ELIXIR_ERL_OPTIONS := if os() == "linux" { "+fnu" } else { "" }
+
+# Get app dependencies
+deps:
+ mix local.hex --force
+ mix deps.get --only dev
+ mix deps.get --only test
+
+[private]
+pg_ctl:
+ @{{ PG }} which pg_ctl >/dev/null \
+ || (echo "Please install Postgres using: {{ BOLD }}just install{{ RESET }}" && exit 127)
+
+# Start Postgres server
+postgres-up: pg_ctl
+ @({{ PG }} pg_ctl status | grep -q "is running") || {{ PG }} pg_ctl start
+
+# Stop Postgres server
+postgres-down: pg_ctl
+ @({{ PG }} pg_ctl status | grep -q "no server running") || {{ PG }} pg_ctl stop
+
+[private]
+postgres-db db:
+ @({{ PG }} psql --list --quiet --tuples-only | grep -q {{ db }}) \
+ || {{ PG }} createdb {{ db }}
+
+export DB_USER := `whoami`
+
+[private]
+changelog_test: postgres-up (postgres-db "changelog_test")
+
+# Run app tests
+test: changelog_test
+ mix test
+
+[private]
+changelog_dev: postgres-up (postgres-db "changelog_dev")
+ mix ecto.setup
+
+[private]
+yarn:
+ @which yarn >/dev/null \
+ || (echo "Please install Node.js & Yarn using: {{ BOLD }}just install{{ RESET }}" && exit 127)
+
+[private]
+assets: yarn
+ cd assets && yarn install
+
+# Run app in dev mode
+dev: changelog_dev assets
+ mix phx.server
+
+# Setup everything needed for your first contribution
+contribute: install
+ #!/usr/bin/env bash
+ eval "$(just asdf-shell)"
+ just deps
+ just test
+ just dev
+
+[private]
+actions-runner:
+ docker run --interactive --tty \
+ --volume=changelog-linuxbrew:/home/linuxbrew/.linuxbrew \
+ --volume=changelog-asdf:/home/runner/.asdf \
+ --volume=.:/home/runner/work --workdir=/home/runner/work \
+ --env=HOST=$(hostname) --publish=4000:4000 \
+ --pull=always ghcr.io/actions/actions-runner
+
+[linux]
+[private]
+do-it:
+ #!/usr/bin/env bash
+ sudo apt update
+ DEBIAN_FRONTEND=noninteractive sudo apt install -y build-essential curl git libncurses5-dev libssl-dev inotify-tools
+ just brew
+ eval "$(just brew-linux-shell)"
+ just asdf
+ eval "$(just asdf-shell)"
+ just contribute
+
+# https://linux.101hacks.com/ps1-examples/prompt-color-using-tput/
+
+BOLD := "$(tput bold)"
+RESET := "$(tput sgr0)"
+BLACK := "$(tput bold)$(tput setaf 0)"
+RED := "$(tput bold)$(tput setaf 1)"
+GREEN := "$(tput bold)$(tput setaf 2)"
+YELLOW := "$(tput bold)$(tput setaf 3)"
+BLUE := "$(tput bold)$(tput setaf 4)"
+MAGENTA := "$(tput bold)$(tput setaf 5)"
+CYAN := "$(tput bold)$(tput setaf 6)"
+WHITE := "$(tput bold)$(tput setaf 7)"
+BLACKB := "$(tput bold)$(tput setab 0)"
+REDB := "$(tput setab 1)$(tput setaf 0)"
+GREENB := "$(tput setab 2)$(tput setaf 0)"
+YELLOWB := "$(tput setab 3)$(tput setaf 0)"
+BLUEB := "$(tput setab 4)$(tput setaf 0)"
+MAGENTAB := "$(tput setab 5)$(tput setaf 0)"
+CYANB := "$(tput setab 6)$(tput setaf 0)"
+WHITEB := "$(tput setab 7)$(tput setaf 0)"
+
+# just actions-runner
+# DEBIAN_FRONTEND=noninteractive sudo apt install -y curl
+# eval $(grep j_ust.systems justfile)
+# cd ../
+# sudo chown -fR runner:runner work ~/.asdf
+# cd work
+# just do-it
+#
+# du -skh _build
+# 72M
+#
+# du -skh deps
+# 41M
+#
+# du -skh /home/linuxbrew/.linuxbrew
+# 1.5G
+# du -skh ~/.asdf
+# 728M
diff --git a/magefiles/tools/main.go b/magefiles/tools/main.go
index 1879202894..2640db000e 100644
--- a/magefiles/tools/main.go
+++ b/magefiles/tools/main.go
@@ -49,9 +49,9 @@ func (v *Versions) Nodejs() string {
}
// https://www.postgresql.org/docs/release
-// asdf list all postgres
+// Hard-coding & installing via brew (keep hitting icu4c & root permissions with asdf)
func (v *Versions) Postgres() string {
- return v.toolVersions["postgres"]
+ return "16"
}
// https://github.com/yarnpkg/yarn/releases