Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setup the app locally with just one command: just contribute #521

Merged
merged 1 commit into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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