Skip to content

Commit

Permalink
Setup the app locally with just one command: just contribute (#521)
Browse files Browse the repository at this point in the history
    ❯ just
    just --list
    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

Signed-off-by: Gerhard Lazu <[email protected]>
  • Loading branch information
gerhard committed Sep 4, 2024
1 parent 2b80e66 commit 7eedece
Show file tree
Hide file tree
Showing 7 changed files with 212 additions and 52 deletions.
1 change: 0 additions & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
Expand Up @@ -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
72 changes: 24 additions & 48 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,68 +78,44 @@ 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
- [Node.js](https://nodejs.org/en/download/) v20 LTS - [latest-v20.x](https://nodejs.org/download/release/latest-v20.x/)
- [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:

<img src="changelog-local-dev-2022.png">
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
<img src="changelog-local-dev-2024.png">

# 🏋️ 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?

Expand Down
Binary file removed changelog-local-dev-2022.png
Binary file not shown.
Binary file added changelog-local-dev-2024.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion config/dev.exs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
185 changes: 185 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
@@ -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
4 changes: 2 additions & 2 deletions magefiles/tools/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 7eedece

Please sign in to comment.