Switch from `make` to `just`

This commit is contained in:
Mayel de Borniol 2022-05-23 14:20:39 +12:00
parent 38b08cd756
commit c3e494dbd2
12 changed files with 615 additions and 699 deletions

1
.env Symbolic link
View File

@ -0,0 +1 @@
./config/dev/.env

1
.gitignore vendored
View File

@ -41,6 +41,7 @@ npm-debug.log
# App and user data
/data/
/db/
.env
.secrets
config/dev
config/prod

522
Makefile
View File

@ -1,520 +1,2 @@
BASH := $(shell which bash)
#### Makefile config ####
#### NOTE: do not edit this file, override these in your env instead ####
# what flavour do we want?
FLAVOUR ?= classic
FLAVOUR_PATH ?= flavours/$(FLAVOUR)
# do we want to use Docker? set as env var:
# - WITH_DOCKER=total : use docker for everything (default)
# - WITH_DOCKER=partial : use docker for services like the DB
# - WITH_DOCKER=easy : use docker for services like the DB & compiled utilities like messctl
# - WITH_DOCKER=no : please no
WITH_DOCKER ?= total
# other configs
FORKS_PATH ?= forks/
MIX_ENV ?= dev
ORG_NAME ?= bonfirenetworks
APP_NAME ?= bonfire
UID := $(shell id -u)
GID := $(shell id -g)
APP_REL_CONTAINER="$(APP_NAME)_release"
WEB_CONTAINER ?= $(APP_NAME)_web
APP_REL_DOCKERFILE=Dockerfile.release
APP_REL_DOCKERCOMPOSE=docker-compose.release.yml
APP_VSN ?= `grep -m 1 'version:' mix.exs | cut -d '"' -f2`
APP_VSN_EXTRA ?= alpha
APP_BUILD ?= `git rev-parse --short HEAD`
APP_DOCKER_REPO="$(ORG_NAME)/$(APP_NAME)-$(FLAVOUR)"
DB_DOCKER_IMAGE ?= postgis/postgis:12-3.1-alpine
CONFIG_PATH=$(FLAVOUR_PATH)/config
#### GENERAL SETUP RELATED COMMANDS ####
export UID
export GID
define setup_env
$(eval ENV_DIR := $(CONFIG_PATH)/$(MIX_ENV))
@echo "Loading environment variables from $(ENV_DIR)"
@$(call load_env,$(ENV_DIR)/public.env)
@$(call load_env,$(ENV_DIR)/secrets.env)
endef
define load_env
$(eval ENV_FILE := $(1))
# @echo "Loading env vars from $(ENV_FILE)"
$(eval include $(ENV_FILE)) # import env into make
$(eval export) # export env from make
endef
pre-config: pre-init ## Initialise env files, and create some required folders, files and softlinks
@echo "You can now edit your config for flavour '$(FLAVOUR)' in config/$(MIX_ENV)/secrets.env, config/$(MIX_ENV)/public.env and ./config/ more generally."
pre-init:
@echo "Setting flavour to $(FLAVOUR_PATH)"
@ln -sfn $(FLAVOUR_PATH)/config ./config
@rm -rf ./priv/repo
@cp -rn $(FLAVOUR_PATH)/repo ./priv/repo
@mkdir -p data/
@rm -rf ./data/current_flavour
@ln -sf ../$(FLAVOUR_PATH) ./data/current_flavour
@mkdir -p $(CONFIG_PATH)/prod
@mkdir -p $(CONFIG_PATH)/dev
@touch $(CONFIG_PATH)/deps.path
@cp -n $(CONFIG_PATH)/templates/public.env $(CONFIG_PATH)/dev/ | true
@cp -n $(CONFIG_PATH)/templates/public.env $(CONFIG_PATH)/prod/ | true
@cp -n $(CONFIG_PATH)/templates/not_secret.env $(CONFIG_PATH)/dev/secrets.env | true
@cp -n $(CONFIG_PATH)/templates/not_secret.env $(CONFIG_PATH)/prod/secrets.env | true
pre-run: pre-init
@mkdir -p forks/
@mkdir -p data/uploads/
@mkdir -p priv/static/data
@ln -s data/uploads priv/static/data/ | true
@mkdir -p data/search/dev
@chmod 700 .erlang.cookie
init: pre-run
@$(call setup_env)
@echo "Light that fire... $(APP_NAME) with $(FLAVOUR) flavour in $(MIX_ENV) - docker:$(WITH_DOCKER) - $(APP_VSN) - $(APP_BUILD) - $(FLAVOUR_PATH)"
@make --no-print-directory pre-init
@make --no-print-directory services
help: ## Makefile commands help
@perl -nle'print $& if m{^[a-zA-Z_-~.%]+:.*?## .*$$}' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
env.exports: ## Display the vars from dotenv files that you need to load in your environment
@awk 'NF { if( $$1 != "#" ){ print "export " $$0 }}' $(FLAVOUR_PATH)/config/dev/*.env
#### COMMON COMMANDS ####
setup: build mix~setup js.deps.get ## First run - prepare environment and dependencies
dev: init dev.run ## Run the app in development
dev.run:
ifeq ($(WITH_DOCKER), total)
@make --no-print-directory docker.stop.web
docker-compose run --name $(WEB_CONTAINER) --service-ports web
# docker-compose --verbose run --name $(WEB_CONTAINER) --service-ports web
else
iex -S mix phx.server
endif
doc: ## Generate docs from code & readmes
@make --no-print-directory mix.remote~docs
recompile: ## Force the app to recompile
@make --no-print-directory cmd cmd="mix compile --force"
dev.test: init test.env.server dev.run
dev.bg: init ## Run the app in dev mode, as a background service
ifeq ($(WITH_DOCKER), total)
@make --no-print-directory docker.stop.web
docker-compose run --detach --name $(WEB_CONTAINER) --service-ports web elixir -S mix phx.server
else
elixir --erl "-detached" -S mix phx.server
echo Running in background...
ps au | grep beam
endif
db.migrate: mix~ecto.migrate ## Run latest database migrations (eg. after adding/upgrading an app/extension)
db.seeds: mix~ecto.migrate mix~ecto.seeds ## Run latest database seeds (eg. inserting required data after adding/upgrading an app/extension)
db.reset: init dev.search.reset db.pre-migrations mix~ecto.reset ## Reset the DB (caution: this means DATA LOSS)
dev.search.reset:
ifeq ($(WITH_DOCKER), no)
echo ...
else
@docker-compose rm -s -v search
endif
rm -rf data/search/dev
db.rollback: mix~ecto.rollback ## Rollback previous DB migration (caution: this means DATA LOSS)
db.rollback.all: ## Rollback ALL DB migrations (caution: this means DATA LOSS)
@make --no-print-directory cmd cmd="mix ecto.rollback --all"
#### UPDATE COMMANDS ####
update: init update.repo build update.forks update.deps mix~deps.get mix~ecto.migrate js.deps.get update.repo ## Update the dev app and all dependencies/extensions/forks, and run migrations
update.app: update.repo update.deps ## Update the app and Bonfire extensions in ./deps
update.deps: ## Update Bonfire extensions in ./deps
@rm -rf deps/*/assets/pnpm-lock.yaml
@make --no-print-directory mix.remote~updates
update.repo:
@chmod +x git-publish.sh && ./git-publish.sh . pull
update.repo.pull:
@chmod +x git-publish.sh && ./git-publish.sh . pull only
update.deps.bonfire: init mix.remote~bonfire.deps ## Update to the latest Bonfire extensions in ./deps
update.deps.all: ## Update evey single dependency (use with caution)
@make --no-print-directory update.dep~"--all"
update.dep~%: ## Update a specify dep (eg. `make update.dep~pointers`)
@chmod +x git-publish.sh && ./git-publish.sh $(FORKS_PATH)/$* pull
@make --no-print-directory mix.remote~"deps.update $*"
update.forks: ## Pull the latest commits from all ./forks
@jungle git fetch || echo "Jungle not available, will fetch one by one instead."
@chmod +x git-publish.sh && find $(FORKS_PATH) -mindepth 1 -maxdepth 1 -type d -exec ./git-publish.sh {} maybe-pull \;
# TODO: run in parallel? find $(FORKS_PATH) -mindepth 1 -maxdepth 1 -type d | xargs -P 50 -I '{}' ./git-publish.sh '{}'
update.fork~%: ## Pull the latest commits from all ./forks
@chmod +x git-publish.sh && find $(FORKS_PATH)/$* -mindepth 0 -maxdepth 0 -type d -exec ./git-publish.sh {} pull \;
deps.get: mix.remote~deps.get mix~deps.get js.ext.deps.get ## Fetch locked version of non-forked deps
deps.clean.data: mix~bonfire.deps.clean.data
deps.clean.api: mix~bonfire.deps.clean.api
#### DEPENDENCY & EXTENSION RELATED COMMANDS ####
js.deps.get: js.assets.deps.get js.ext.deps.get
js.assets.deps.get:
@pnpm -v || npm -g install pnpm
@chmod +x ./assets/install.sh
@make --no-print-directory cmd cmd=./assets/install.sh
js.ext.deps.get:
@chmod +x ./config/deps.js.sh
@make --no-print-directory cmd cmd=./config/deps.js.sh
deps.outdated:
@make mix.remote~"hex.outdated --all"
dep.clean:
make --no-print-directory cmd cmd="mix deps.clean $(dep) --build"
dep.clone.local: ## Clone a git dep and use the local version, eg: `make dep.clone.local dep="bonfire_me" repo=https://github.com/bonfire-networks/bonfire_me`
git clone $(repo) $(FORKS_PATH)$(dep) 2> /dev/null || (cd $(FORKS_PATH)$(dep) ; git pull)
@make --no-print-directory dep.go.local dep=$(dep)
deps.clone.local.all: ## Clone all bonfire deps / extensions
@curl -s https://api.github.com/orgs/bonfire-networks/repos?per_page=500 | ruby -rrubygems -e 'require "json"; JSON.load(STDIN.read).each { |repo| %x[make dep.clone.local dep="#{repo["name"]}" repo="#{repo["ssh_url"]}" ]}'
dep.go.local:
@make --no-print-directory dep.go.local.path dep=$(dep) path=$(FORKS_PATH)$(dep)
dep.go.local~%: ## Switch to using a local path, eg: make dep.go.local~pointers
@make --no-print-directory dep.go.local dep="$*"
dep.go.local.path: ## Switch to using a local path, specifying the path, eg: make dep.go.local dep=pointers path=./libs/pointers
@make --no-print-directory dep.local~add dep=$(dep) path=$(path)
@make --no-print-directory dep.local~enable dep=$(dep) path=""
dep.go.git: ## Switch to using a git repo, eg: make dep.go.git dep="pointers" repo=https://github.com/bonfire-networks/pointers (specifying the repo is optional if previously specified)
@make --no-print-directory dep.git~add dep=$(dep) $(repo) 2> /dev/null || true
@make --no-print-directory dep.git~enable dep=$(dep) repo=""
@make --no-print-directory dep.local~disable dep=$(dep) path=""
dep.go.hex: ## Switch to using a library from hex.pm, eg: make dep.go.hex dep="pointers" version="~> 0.2" (specifying the version is optional if previously specified)
@make --no-print-directory dep.hex~add dep=$(dep) version=$(version) 2> /dev/null || true
@make --no-print-directory dep.hex~enable dep=$(dep) version=""
@make --no-print-directory dep.git~disable dep=$(dep) repo=""
@make --no-print-directory dep.local~disable dep=$(dep) path=""
dep.hex~%: ## add/enable/disable/delete a hex dep with messctl command, eg: `make dep.hex.enable dep=pointers version="~> 0.2"
@make --no-print-directory messctl args="$* $(dep) $(version)"
@make --no-print-directory cmd cmd="mix deps.clean $(dep)"
dep.git~%: ## add/enable/disable/delete a git dep with messctl command, eg: `make dep.hex.enable dep=pointers repo=https://github.com/bonfire-networks/pointers#main
@make --no-print-directory messctl args="$* $(dep) $(repo) config/deps.git"
@make --no-print-directory cmd cmd="mix deps.clean $(dep)"
dep.local~%: ## add/enable/disable/delete a local dep with messctl command, eg: `make dep.hex.enable dep=pointers path=./libs/pointers
@make --no-print-directory messctl args="$* $(dep) $(path) config/deps.path"
@make --no-print-directory cmd cmd="mix deps.clean $(dep)"
messctl~%: ## Utility to manage the deps in deps.hex, deps.git, and deps.path (eg. `make messctl~help`)
@make --no-print-directory messctl args=$*
messctl: init
ifeq ($(WITH_DOCKER), total)
docker-compose run web messctl $(args)
else ifeq ($(WITH_DOCKER), easy)
docker-compose run web messctl $(args)
else
echo "Make sure you have compiled/installed messctl first: https://github.com/bonfire-networks/messctl"
messctl $(args)
endif
#### CONTRIBUTION RELATED COMMANDS ####
contrib.forks: contrib.forks.publish git.publish ## Push all changes to the app and extensions in ./forks
contrib.release: contrib.forks.publish contrib.app.release ## Push all changes to the app and extensions in ./forks, increment the app version number, and push a new version/release
contrib.app.up: update.app git.publish ## Update ./deps and push all changes to the app
contrib.app.release: update.app contrib.app.release.increment git.publish ## Update ./deps, increment the app version number and push
contrib.app.release.increment:
@cd lib/mix/tasks/release/ && mix escript.build && ./release ../../../../ $(APP_VSN_EXTRA)
contrib.forks.publish:
@jungle git fetch || echo "Jungle not available, will fetch one by one instead."
@chmod +x git-publish.sh && find $(FORKS_PATH) -mindepth 1 -maxdepth 1 -type d -exec ./git-publish.sh {} \;
# TODO: run in parallel?
git.forks.add: deps.git.fix ## Run the git add command on each fork
find $(FORKS_PATH) -mindepth 1 -maxdepth 1 -type d -exec echo add {} \; -exec git -C '{}' add --all . \;
git.forks.status: ## Run a git status on each fork
@jungle git status || find $(FORKS_PATH) -mindepth 1 -maxdepth 1 -type d -exec echo {} \; -exec git -C '{}' status \;
git.forks~%: ## Run a git command on each fork (eg. `make git.forks~pull` pulls the latest version of all local deps from its git remote
@find $(FORKS_PATH) -mindepth 1 -maxdepth 1 -type d -exec echo $* {} \; -exec git -C '{}' $* \;
git.diff: ## List all diffs in forks
@find $(FORKS_PATH) -mindepth 1 -maxdepth 1 -type d -exec echo {} \; -exec git -C '{}' --no-pager diff --color --exit-code \;
deps.git.fix: ## Run a git command on each dep, to ignore chmod changes
find ./deps -mindepth 1 -maxdepth 1 -type d -exec git -C '{}' config core.fileMode false \;
find ./forks -mindepth 1 -maxdepth 1 -type d -exec git -C '{}' config core.fileMode false \;
git.merge~%: ## Draft-merge another branch, eg `make git-merge-with-valueflows-api` to merge branch `with-valueflows-api` into the current one
git merge --no-ff --no-commit $*
git.conflicts: ## Find any git conflicts in ./forks
find $(FORKS_PATH) -mindepth 1 -maxdepth 1 -type d -exec echo add {} \; -exec git -C '{}' diff --name-only --diff-filter=U \;
git.publish:
chmod +x git-publish.sh
./git-publish.sh
#### TESTING RELATED COMMANDS ####
test.env:
$(eval export MIX_ENV=test)
$(eval export SERVER_PORT=4001)
$(eval export PUBLIC_PORT=4001)
test.env.server: test.env
$(eval export START_SERVER=true)
test: init test.env ## Run tests. You can also run only specific tests, eg: `make test only=forks/bonfire_social/test`
ifeq ($(WITH_DOCKER), total)
docker-compose run web mix test $(only)
else
mix test $(only)
endif
test.stale: init test.env ## Run only stale tests
ifeq ($(WITH_DOCKER), total)
docker-compose run web mix test $(only) --stale
else
mix test $(only) --stale
endif
test.remote: test.env ## Run tests (ignoring changes in local forks)
@make --no-print-directory mix.remote~"test $(only)"
test.watch: init test.env ## Run stale tests, and wait for changes to any module's code, and re-run affected tests
ifeq ($(WITH_DOCKER), total)
docker-compose run web mix test.watch --stale $(only)
else
mix test.watch --stale $(only)
endif
test.interactive: init test.env ## Run stale tests, and wait for changes to any module's code, and re-run affected tests, and interactively choose which tests to run
ifeq ($(WITH_DOCKER), total)
docker-compose run web mix test.interactive --stale $(only)
else
mix test.interactive --stale $(only)
endif
# dev-test-watch: init ## Run tests
# docker-compose run --service-ports -e MIX_ENV=test web iex -S mix phx.server
test.db.reset: init db.pre-migrations ## Create or reset the test DB
ifeq ($(WITH_DOCKER), total)
docker-compose run -e MIX_ENV=test web mix ecto.reset
else
MIX_ENV=test mix ecto.reset
endif
#### RELEASE RELATED COMMANDS (Docker-specific for now) ####
rel.env:
$(eval export MIX_ENV=prod)
$(eval export)
rel.config.prepare: rel.env # copy current flavour's config, without using symlinks
rm -rf ./data/current_flavour
mkdir -p data
@cp -rfL $(FLAVOUR_PATH) ./data/current_flavour
rel.prepare: rel.env rel.config.prepare # copy current flavour's config, without using symlinks
@mkdir -p forks/ && mkdir -p data/uploads/ && touch data/current_flavour/config/deps.path
rel.rebuild: rel.env init rel.prepare assets.prepare ## Build the Docker image
docker build \
--no-cache \
--build-arg FLAVOUR_PATH=data/current_flavour \
--build-arg APP_NAME=$(APP_NAME) \
--build-arg APP_VSN=$(APP_VSN) \
--build-arg APP_BUILD=$(APP_BUILD) \
-t $(APP_DOCKER_REPO):$(APP_VSN)-release-$(APP_BUILD) \
-f $(APP_REL_DOCKERFILE) .
@echo Build complete: $(APP_DOCKER_REPO):$(APP_VSN)-release-$(APP_BUILD)
rel.build: rel.env init rel.prepare assets.prepare ## Build the Docker image using previous cache
@echo "Building $(APP_NAME) with flavour $(FLAVOUR)"
docker build \
--build-arg FLAVOUR_PATH=data/current_flavour \
--build-arg APP_NAME=$(APP_NAME) \
--build-arg APP_VSN=$(APP_VSN) \
--build-arg APP_BUILD=$(APP_BUILD) \
-t $(APP_DOCKER_REPO):$(APP_VSN)-release-$(APP_BUILD) \
-f $(APP_REL_DOCKERFILE) .
@echo Build complete: $(APP_DOCKER_REPO):$(APP_VSN)-release-$(APP_BUILD)
@echo "Remember to run make rel.tag.latest or make rel.push"
rel.tag.latest: rel.env ## Add latest tag to last build
@docker tag $(APP_DOCKER_REPO):$(APP_VSN)-release-$(APP_BUILD) $(APP_DOCKER_REPO):latest
rel.push: rel.env ## Add latest tag to last build and push to Docker Hub
@docker push $(APP_DOCKER_REPO):latest
rel.run: rel.env init docker.stop.web ## Run the app in Docker & starts a new `iex` console
@docker-compose -p $(APP_REL_CONTAINER) -f $(APP_REL_DOCKERCOMPOSE) run --name $(WEB_CONTAINER) --service-ports --rm web bin/bonfire start_iex
rel.run.bg: rel.env init docker.stop.web ## Run the app in Docker, and keep running in the background
@docker-compose -p $(APP_REL_CONTAINER) -f $(APP_REL_DOCKERCOMPOSE) up -d
rel.stop: rel.env ## Stop the running release
@docker-compose -p $(APP_REL_CONTAINER) -f $(APP_REL_DOCKERCOMPOSE) stop
rel.update: rel.env update.repo.pull
@docker-compose -p $(APP_REL_CONTAINER) -f $(APP_REL_DOCKERCOMPOSE) pull
@echo Remember to run migrations on your DB...
rel.logs:
@docker-compose -p $(APP_REL_CONTAINER) -f $(APP_REL_DOCKERCOMPOSE) logs
rel.down: rel.env rel.stop ## Stop the running release
@docker-compose -p $(APP_REL_CONTAINER) -f $(APP_REL_DOCKERCOMPOSE) down
rel.shell: rel.env init docker.stop.web ## Runs a the app container and opens a simple shell inside of the container, useful to explore the image
@docker-compose -p $(APP_REL_CONTAINER) -f $(APP_REL_DOCKERCOMPOSE) run --name $(WEB_CONTAINER) --service-ports --rm web /bin/bash
rel.shell.bg: rel.env init ## Runs a simple shell inside of the running app container, useful to explore the image
@docker-compose -p $(APP_REL_CONTAINER) -f $(APP_REL_DOCKERCOMPOSE) exec web /bin/bash
rel.db.shell.bg: rel.env init ## Runs a simple shell inside of the DB container, useful to explore the image
@docker-compose -p $(APP_REL_CONTAINER) -f $(APP_REL_DOCKERCOMPOSE) exec db /bin/bash
rel.db.dump: rel.env init
docker-compose -p $(APP_REL_CONTAINER) -f $(APP_REL_DOCKERCOMPOSE) exec db /bin/bash -c "PGPASSWORD=$(POSTGRES_PASSWORD) pg_dump --username $(POSTGRES_USER) $(POSTGRES_DB)" > data/db_dump.sql
rel.db.restore: rel.env init
cat $(file) | docker exec -i bonfire_release_db_1 /bin/bash -c "PGPASSWORD=$(POSTGRES_PASSWORD) psql -U $(POSTGRES_USER) $(POSTGRES_DB)"
#### DOCKER-SPECIFIC COMMANDS ####
services: ## Start background docker services (eg. db and search backends).
ifeq ($(MIX_ENV), prod)
docker-compose -p $(APP_REL_CONTAINER) -f $(APP_REL_DOCKERCOMPOSE) up -d db search
else
ifeq ($(WITH_DOCKER), no)
@echo ....
else
docker-compose up -d db search
endif
endif
build: init ## Build the docker image
ifeq ($(WITH_DOCKER), no)
@echo Skip building container...
else
@mkdir -p deps
docker-compose pull
docker-compose build
endif
rebuild: init ## Build the docker image
ifeq ($(WITH_DOCKER), no)
@echo Skip building container...
else
@mkdir -p deps
docker-compose build --no-cache
endif
cmd~%: init ## Run a specific command in the container, eg: `make cmd-messclt` or `make cmd~time` or `make cmd~echo args=hello`
ifeq ($(WITH_DOCKER), total)
docker-compose run --service-ports web $* $(args)
else
@$* $(args)
endif
shell: init ## Open the shell of the Docker web container, in dev mode
@make cmd~bash
docker.stop.web:
@docker stop $(WEB_CONTAINER) 2> /dev/null || true
@docker rm $(WEB_CONTAINER) 2> /dev/null || true
#### MISC COMMANDS ####
cmd: init
ifeq ($(WITH_DOCKER), total)
docker-compose run web bash -c "$(cmd) $(args)"
else
$(cmd) $(args)
endif
cmd~%: init ## Run a specific command, eg: `make cmd~"mix deps.get"` or `make cmd~deps.update args=pointers`
@make --no-print-directory cmd cmd="$*" $(args)
mix~%: init ## Run a specific mix command, eg: `make mix~deps.get` or `make mix~deps.update args=pointers`
@make --no-print-directory cmd cmd="mix $*" $(args)
mix.remote~%: init ## Run a specific mix command, while ignoring any deps cloned into ./forks, eg: `make mix~deps.get` or `make mix~deps.update args=pointers`
ifeq ($(WITH_DOCKER), total)
docker-compose run -e WITH_FORKS=0 web mix $* $(args)
else
WITH_FORKS=0 mix $* $(args)
endif
ifeq (exh, $(firstword $(MAKECMDGOALS)))
args := $(wordlist 2, $(words $(MAKECMDGOALS)), $(MAKECMDGOALS))
$(eval $(args):;@true)
endif
exh%: init ## ## Run a specific exh command, see https://github.com/rowlandcodes/exhelp
@exh -S mix $(args)
licenses: init
@mkdir -p docs/DEPENDENCIES/
@make --no-print-directory mix.remote~licenses && mv DEPENDENCIES.md docs/DEPENDENCIES/$(FLAVOUR).md
localise.extract:
@make --no-print-directory mix~"bonfire.localise.extract --merge"
assets.prepare:
@cp lib/*/*/overlay/* rel/overlays/ 2> /dev/null || true
db.pre-migrations: ## Workaround for some issues running migrations
touch deps/*/lib/migrations.ex 2> /dev/null || echo "continue"
touch forks/*/lib/migrations.ex 2> /dev/null || echo "continue"
touch priv/repo/* 2> /dev/null || echo "continue"
secrets:
@cd lib/mix/tasks/secrets/ && mix escript.build && ./secrets 128 3
%:
@echo "Please use 'just' instead"

View File

@ -11,8 +11,7 @@ services:
ports:
- "4000:4000" # you may want to comment this in production
env_file:
- config/prod/public.env
- config/prod/secrets.env
- config/prod/.env
environment:
- POSTGRES_HOST=db
- SEARCH_MEILI_INSTANCE=http://search:7700
@ -29,7 +28,7 @@ services:
- "80:80"
- "443:443"
env_file:
- config/prod/public.env
- config/prod/.env
volumes:
- type: bind
source: ./config/deploy/Caddyfile2
@ -46,8 +45,7 @@ services:
# ports:
# - "5432:5432"
env_file:
- config/prod/public.env
- config/prod/secrets.env
- config/prod/.env
search:
image: getmeili/meilisearch:latest
# ports:
@ -55,5 +53,4 @@ services:
volumes:
- "./data/search/prod:/data.ms"
env_file:
- config/prod/public.env
- config/prod/secrets.env
- config/prod/.env

View File

@ -11,8 +11,7 @@ services:
ports:
- "4000:4000"
env_file:
- config/dev/public.env
- config/dev/secrets.env
- config/dev/.env
environment:
- POSTGRES_HOST=db
- SEARCH_MEILI_INSTANCE=http://search:7700
@ -41,8 +40,7 @@ services:
ports:
- "5432:5432"
env_file:
- config/dev/public.env
- config/dev/secrets.env
- config/dev/.env
# user: $UID:$GID
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
@ -57,6 +55,5 @@ services:
# - "./data/search/dev:/data.ms"
# - /etc/passwd:/etc/passwd:ro
env_file:
- config/dev/public.env
- config/dev/secrets.env
- config/dev/.env
# user: $UID:$GID

View File

@ -26,73 +26,72 @@ CREATE EXTENSION IF NOT EXISTS citext;
## Step 1 - Download and configure the app
1. Clone this repository and change into the directory:
1. Install dependencies. You will need to install [just](https://github.com/casey/just#packages), and other requirements such as Docker (check the exact list of requirements based on the option you choose in step 2.)
2. Clone this repository and change into the directory:
```sh
$ git clone https://github.com/bonfire-networks/bonfire-app.git bonfire
$ cd bonfire
```
2. The first thing to do is choosing what flavour of Bonfire you want to deploy (the default is `classic`), as each flavour has its own Docker image and config.
3. Specify that you want to run in production:
`export MIX_ENV=prod`
For example if you want to run the `cooperation` flavour (you may want to use direnv or something similar to persist this):
The first thing to do is choose what flavour of Bonfire you want to deploy, as each flavour uses different Docker images and set of configs. For example if you want to run the `classic` flavour (you may want to use direnv or something similar to persist this):
`export FLAVOUR=cooperation MIX_ENV=prod`
`just config classic`
3. Once you've picked a flavour, run this command to initialise some default config (.env files which won't be checked into git):
This will initialise some default config (a .env file which won't be checked into git)
`make pre-config`
5. Edit the config (especially the secrets) for the selected flavour in `./.env`
4. Edit the config (especially the secrets) for the current flavour in these files:
- `config/prod/secrets.env`
- `config/prod/public.env`
These are the config keys you should especially pay attention to, in secrets.env:
These are the config keys you should especially pay attention to:
- SECRET_KEY_BASE
- SIGNING_SALT
- ENCRYPTION_SALT
- POSTGRES_PASSWORD
- MEILI_MASTER_KEY
You can use `make secrets` to generate some secrets keys to use.
You can use `just secrets` to generate some random secret keys to use.
And in public.env:
- HOSTNAME
- PUBLIC_PORT
You can make registrations on your instance invite-only by setting `INVITE_ONLY=true` in public.env and setting an `INVITE_KEY` in secrets.env. You can then invite people by sending them to https://yourinstance.tld/signup/invitation/your_INVITE_KEY_here
You can just registrations on your instance invite-only by setting `INVITE_ONLY=true`.
`MAIL_DOMAIN` and `MAIL_KEY` are needed to configure transactional email, you can for example sign up at [Mailgun](https://www.mailgun.com/) and then configure the domain name and key.
### Further information on config
The app needs some environment variables to be configured in order to work. The easy way to manage that is whit the `make` commands which take care of loading the environment for you.
The app needs some environment variables to be configured in order to work. The easy way to manage that is whit the `just` commands which take care of loading the environment for you.
In the `${FLAVOUR_PATH}/config/` (depending on which flavour you choose to run) directory of the codebase, there are following default config files:
In the `./config/` (which is a symbolic link to the config of the flavour you choose to run) directory of the codebase, there are following config files:
- `config.exs`: default base configuration, which itself loads many other config files, such as one for each installed Bonfire extension.
- `dev.exs`: default extra configuration for `MIX_ENV=dev`
- `prod.exs`: default extra configuration for `MIX_ENV=prod`
- `runtime.exs`: extra configuration which is loaded at runtime (vs the others which are only loaded once at compile time, i.e. when you build a release)
- `bonfire_*.exs`: configs specific to different extensions, which are automatically imported by `config.exs`
You should *not* have to modify the files above. Instead, overload any settings from the above files using env variables (a list of which can be found in the file `${FLAVOUR_PATH}/config/templates/public.env` and `${FLAVOUR_PATH}/config/templates/secrets.env` in this same repository, both in the `main` and `release` branches).
You should *not* have to modify the files above. Instead, overload any settings from the above files using env variables or in `./.env`.
`MAIL_DOMAIN` and `MAIL_KEY` are needed to configure transactional email, you can for example sign up at [Mailgun](https://www.mailgun.com/) and then configure the domain name and key.
---
## Step 2 - Install
---
### Option A - Install using Co-op Cloud (recommended)
[https://coopcloud.tech](https://coopcloud.tech) is an alternative to corporate clouds built by tech co-ops, and provides very useful tools for setting up and managing many self-hosted free software tools using ready-to-use "recipes".
### Option A - Install using Docker comtainers (recommended)
If you're interested in hosting Bonfire alongside other open and/or federated projects, we recommend installing [Abra](https://docs.coopcloud.tech/abra/), [setting up a co-op cloud server](https://docs.coopcloud.tech/operators/) and using the [Bonfire recipe](https://recipes.coopcloud.tech/bonfire) to set up an instance.
The easiest way to launch the docker image is using the make commands.
### Option B - Install using Docker containers (easy mode)
The easiest way to launch the docker image is using the just commands.
The `docker-compose.release.yml` uses `config/prod/public.env` and `config/prod/secrets.env` to launch a container with the necessary environment variables along with its dependencies, currently that means an extra postgres container, along with a reverse proxy (Caddy server, which you may want to replace with nginx or whatever you prefer).
#### Install with docker-compose
Make sure you have [Docker](https://www.docker.com/), a recent [docker-compose](https://docs.docker.com/compose/install/#install-compose) (which supports v3 configs), and [make](https://www.gnu.org/software/make/) installed:
Make sure you have [Docker](https://www.docker.com/), a recent [docker-compose](https://docs.docker.com/compose/install/#install-compose) (which supports v3 configs), and [just](https://github.com/casey/just#packages) installed:
```sh
$ docker version
@ -101,14 +100,14 @@ Docker version 18.09.1-ce
$ docker-compose -v
docker-compose version 1.23.2
$ make --version
GNU Make 4.2.1
$ just --version
just 1.1.3
...
```
Now that your tooling is set up, you have the choice of using pre-built images or building your own. For example if your flavour does not have a prebuilt image on Docker Hub, or if you want to customise any of the extensions, you can build one yourself - see option A2 below.
#### Option A1 - Using pre-built Docker images (recommend to start with)
#### Option B1 - Using pre-built Docker images (recommend to start with)
- The `image` entry in `docker-compose.release.yml` will by default use the image on Docker Hub which corresponds to your chosen flavour (see step 1 above for choosing your flavour).
@ -117,7 +116,7 @@ You can see the images available per flavour, version (we currently recommend us
- Start the docker containers with docker-compose:
```
make rel.run
just rel.run
```
Run this at the prompt:
@ -130,16 +129,16 @@ The backend should now be running at [http://localhost:4000/](http://localhost:4
- If that worked, start the app as a daemon next time:
```
make rel.run.bg
just rel.run.bg
```
#### Docker-related handy commands
- `docker-compose pull` to update to the latest release of Bonfire (only if using a Docker Hub image) and other services (Postgres & Meili)
- `make rel.run` Run the app in Docker, in the foreground
- `make rel.run.bg` Run the app in Docker, and keep running in the background
- `make rel.stop` Stop the running release
- `make rel.shell` Runs a simple shell inside of the container, useful to explore the image
- `just update` to update to the latest release of Bonfire
- `just rel.run` Run the app in Docker, in the foreground
- `just rel.run.bg` Run the app in Docker, and keep running in the background
- `just rel.stop` Stop the running release
- `just rel.shell` Runs a simple shell inside of the container, useful to explore the image
Once in the shell, you can run `bin/bonfire` with the following commands:
Usage: `bonfire COMMAND [ARGS]`
@ -157,7 +156,7 @@ The known commands are:
- `pid` Prints the operating system PID of the running system via a remote command
- `version` Prints the release name and version to be booted
There are some useful database-related release tasks under `EctoSparkles.Migrator.` that can be run in an `iex` console (which you get to with `make rel.shell` followed by `bin/bonfire remote`, assuming the app is already running):
There are some useful database-related release tasks under `EctoSparkles.Migrator.` that can be run in an `iex` console (which you get to with `just rel.shell` followed by `bin/bonfire remote`, assuming the app is already running):
- `migrate` runs all up migrations
- `rollback(step)` roll back to step X
@ -166,17 +165,17 @@ There are some useful database-related release tasks under `EctoSparkles.Migrato
You can also directly call some functions in the code from the command line, for example:
- to migrate: `docker exec bonfire_web bin/bonfire rpc 'EctoSparkles.Migrator.migrate'`
- to make yourself an admin: `docker exec bonfire_web bin/bonfire rpc 'Bonfire.Me.Users.make_admin("my_username")'`
- to just yourself an admin: `docker exec bonfire_web bin/bonfire rpc 'Bonfire.Me.Users.make_admin("my_username")'`
#### Option A2 - Building your own Docker image
#### Option B2 - Building your own Docker image
`Dockerfile.release` uses the [multistage build](https://docs.docker.com/develop/develop-images/multistage-build/) feature to make the image as small as possible. It generates the OTP release which is later copied into the final image packaged in an Alpine linux container.
`Dockerfile.release` uses the [multistage build](https://docs.docker.com/develop/develop-images/multistage-build/) feature to just the image as small as possible. It generates the OTP release which is later copied into the final image packaged in an Alpine linux container.
There is a `Makefile` with relevant commands (make sure you set the `MIX_ENV=prod` env first):
There is a `justfile` with relevant commands (make sure set the `MIX_ENV=prod` env variable):
- `make rel.build` which builds the docker image
- `make rel.tag.latest` adds the "latest" tag to your last build, so that it will be used when running
- `make rel.push` if you want to push your latest build to Docker Hub
- `just rel.build` which builds the docker image
- `just rel.tag.latest` adds the "latest" tag to your last build, so that it will be used when running
- `just rel.push` if you want to push your latest build to Docker Hub
Once you've built and tagged your image, you may need to update the `image` name in `docker-compose.release.yml` to match (either your local image name if running on the same machine you used for the build, or a remote image on Docker Hub if you pushed it) and then follow the same steps as for option A1.
@ -184,25 +183,25 @@ For production, we recommend to set up a CI workflow to automate this, for an ex
---
### Option B - Manual installation (without Docker)
### Option C - Manual installation (without Docker)
#### Dependencies
- Postgres (or Postgis) version 12 or newer
- Build tools
- Elixir version 1.11.0 with OTP 23 (or newer). If your distribution only has an old version available, check [Elixir's install page](https://elixir-lang.org/install.html) or use a tool like [asdf](https://github.com/asdf-vm/asdf) (run `asdf install` in this directory).
- [just](https://github.com/casey/just#packages)
- Elixir version 1.13 with OTP 24 (or newer). If your distribution only has an old version available, check [Elixir's install page](https://elixir-lang.org/install.html) or use a tool like [asdf](https://github.com/asdf-vm/asdf) (run `asdf install` in this directory).
#### B-1. Building the release
#### C-1. Building the release
- Make sure you have erlang and elixir installed (check `Dockerfile` for what version we're currently using)
- Run `mix deps.get --only prod` to install elixir dependencies.
- Prepare assets with `make js.deps.get`, `make assets.release` and `mix phx.digest`
- Prepare assets with `just js.deps.get`, `just assets.release` and `mix phx.digest`
- Run `mix release` to create an elixir release. This will create an executable in your `_build/prod/rel/bonfire` directory. We will be using the `bin/bonfire` executable from here on.
#### B-2. Running the release
#### C-2. Running the release
- `cd _build/prod/rel/bonfire/`
@ -216,7 +215,7 @@ For production, we recommend to set up a CI workflow to automate this, for an ex
---
### Option C - with Nix
### Option D - with Nix
This repo is a Flake and includes a Nix module.
@ -227,7 +226,7 @@ Here are the detailed steps to deploy it:
- add `sandbox = false` in your nix.conf
- fetch and build the app and dependencies: `nix run github:bonfire-networks/bonfire-app start_iex`
- add it as an input to your system flake.
- add an overlay to make the package available
- add an overlay to just the package available
- add the required configuration in your system
Your `flake.nix` file would look like the following. Remember to replace `myHostName` with your actual hostname or however your deployed system is called.
@ -298,7 +297,7 @@ this repo is a flake and includes a nixos module.
Here are the detailed steps to deploy it.
- add it as an input to your system flake.
- add an overlay to make the package available
- add an overlay to just the package available
- add the required configuration in your system
Your flake.nix file would look like the following. Remember to replace myHostName with your actual hostname or however your deployed system is called.

View File

@ -16,6 +16,8 @@ Bonfire is currently alpha software. While it's fun to play with it,
we would _absolutely not_ recommend running any production instances
yet because it's just not ready for that today.
## Download
Either way, you need to first clone this repository and change into the directory and then do some configuration:
```sh
@ -23,67 +25,52 @@ $ git clone https://github.com/bonfire-networks/bonfire-app bonfire
$ cd bonfire
```
## Configuration
## Configure
### Picking a flavour
### Pick a flavour
Bonfire is a flexible platform that powers a variety of social networks. The first thing you have to choose is which app (or "flavour") you want to hack on:
- Classic ("Bonfire Social", a toot-based social network that interoperates with the fediverse)
- Cooperation (for building cooperative communities)
- Reflow (for community economic activities)
- Haha (for learning new things)
- `classic` ("Bonfire Social", a toot-based social network that interoperates with the fediverse)
- `cooperation` (for building cooperative communities)
- `reflow` (for community economic activities)
- `haha` (for learning new things)
Note that at the current time, the core team are focusing most of
their efforts on the classic flavour and this is where we recommend you start.
For example if you want to run the `classic` flavour (the default)
You first need to install [just](https://github.com/casey/just#packages) which is a handy tool (a `just` alternative) to run commands defined in `./justfile`.
`export FLAVOUR=classic`
So for example if you want to run the `classic` flavour, run:
### Initialise
`just config classic`
You need to clone this repository and change into the directory and then do some configuration:
### Configure
```sh
$ git clone https://github.com/bonfire-networks/bonfire-app.git bonfire
$ cd bonfire
```
- Then run this command to initialise some default config (.env files which won't be checked into git):
`make pre-config`
- Edit the config (especially the secrets) for the current flavour in these files:
- `config/dev/secrets.env`
- `config/dev/public.env`
- Then edit the config (especially the secrets) for the current flavour in `./.env`
### Option A - the entry way (fully managed via docker-compose, recommended when you're first exploring)
- Dependencies:
- `make`
- Recent versions of Docker & [docker-compose](https://docs.docker.com/compose/install/)
- Make sure you've edited your .env files (see above) before getting started and proceed to Hello world!
- Set an environment variable to indicate your choice: `export WITH_DOCKER=total`
- Make sure you've edited your .env file (see above) before getting started and proceed to Hello world!
### Option B - the easy way (with bare-metal elixir, and docker-managed tooling, database & search index, recommended for active development)
- Dependencies:
- `make`
- Recent versions of [Elixir](https://elixir-lang.org/install.html) (1.13+) and OTP/erlang (24+)
- Recent versions of Docker & [docker-compose](https://docs.docker.com/compose/install/)
- Set an environment variable to indicate your choice: `export WITH_DOCKER=easy`
- Make sure you've edited your .env files (see above) before getting started and proceed to Hello world!
- Make sure you've edited your .env file (see above) before getting started and proceed to Hello world!
### Option C - the partial way (with bare-metal elixir and tooling, and docker-managed database & search index)
- Dependencies:
- `make`
- Recent versions of [Elixir](https://elixir-lang.org/install.html) (1.13+) and OTP/erlang (24+)
- Recent versions of [Rust](https://www.rust-lang.org/tools/install) and Cargo
- [pnpm](https://pnpm.io)
@ -91,20 +78,18 @@ $ cd bonfire
- Set an environment variable to indicate your choice: `export WITH_DOCKER=partial`
- Make sure you've edited your .env files (see above) before getting started and proceed to Hello world!
- Make sure you've edited your .env file (see above) before getting started and proceed to Hello world!
### Option D - the bare metal (if you don't use docker)
- Dependencies:
- `make`
- Recent versions of [Elixir](https://elixir-lang.org/install.html) (1.13+) and OTP/erlang (24+)
- Recent versions of [Rust](https://www.rust-lang.org/tools/install) and Cargo
- [pnpm](https://pnpm.io)
- Postgres 12+ (or rather [Postgis](https://postgis.net/install/) if using the bonfire_geolocate extension)
- [Meili Search](https://docs.meilisearch.com/learn/getting_started/installation.html) (optional)
- You will need to set the relevant environment variables in the .env files (see above) to match your local install of Postgres.
- You will need to set the relevant environment variables in the .env file (see above) to match your local install of Postgres.
- If you want search capabilities, you'll also need to setup a Meili server and set the relevant env variables as well.
@ -136,16 +121,16 @@ You will need to create and init the db directory (keeping all your Postgres dat
- From a fresh checkout of this repository, this command will fetch the app's dependencies and setup the database (the same commands apply for all three options above):
```
make setup
just setup
```
- You should then be able to run the app with:
```
make dev
just dev
```
- See the `make` commands below for more things you may want to do.
- See the `just` commands below for more things you may want to do.
## Onboarding
@ -155,7 +140,7 @@ Your first step will be to create an account to log in with. The
easiest way to do this is with our mix task:
```
$ make mix~bonfire.account.new
$ just mix bonfire.account.new
Enter an email address: root@localhost
Enter a password:
```
@ -164,11 +149,10 @@ Your password must be at least 10 characters long and the output could be more h
You should then be able to log in and create a user through the web interface.
If you would like to become an administrator, there is a mix task for
that too:
If you would like to become an administrator, there is a mix task for that too:
```shell
make mix~"bonfire.user.admin.promote root" # for username `root`
just mix bonfire.user.admin.promote your_username
```
## The Bonfire Environment
@ -181,30 +165,29 @@ conveniences built in once you know how they all work. The gotcha is that while
- [Bonfire's Database: an Introduction](./DATABASE.md) - an overview of how our database is designed.
- [Boundaries](./BOUNDARIES.md) - an introduction to our access control system.
Note: these are still at the early draft stage, we expect to gradually improve documentation over time.
## Documentation
The code is somewhat documented inline. You can generate HTML docs (using `Exdoc`) by running `mix docs`.
The code is somewhat documented inline. You can generate HTML docs (using `Exdoc`) by running `just docs`.
## Additional information
- messctl is a little utility for programmatically updating the .deps files from which the final elixir dependencies list is compiled by the mess script. The only use of it is in the dep-\* tasks of the Makefile. It is used by some of the project developers and the build does not rely on it.
- `./forks/` is used to hack on local copies of dependencies. You can clone a dependency from its git repo (like a bonfire extension) and use the local version during development, eg: `make dep.clone.local dep=bonfire_me repo=https://github.com/bonfire-networks/bonfire_me`
- `./forks/` is used to hack on local copies of dependencies. You can clone a dependency from its git repo (like a bonfire extension) and use the local version during development, eg: `just dep.clone.local bonfire_me https://github.com/bonfire-networks/bonfire_me`
- You can migrate the DB when the app is running (useful in a release): `EctoSparkles.Migrator.migrate`
- You can migrate the DB when the app is running (also runs automatically on startup): `EctoSparkles.Migrator.migrate`
### Usage under Windows (WSL, MSYS or CYGWIN)
By default, the `Makefile` requires symlinks, which can be enabled with the help of [this link](https://stackoverflow.com/a/59761201).
By default, the `justfile` requires symlinks, which can be enabled with the help of [this link](https://stackoverflow.com/a/59761201).
See the [pull request adding WSL support](https://github.com/bonfire-networks/bonfire-app/pull/111) for details about usage without symlinks.
## Make commands
## `just` commands
Run `make` followed by any of these commands when appropriate rather than directly using the equivalent commands like `mix`, `docker`, `docker-compose`, etc. For example, `make setup` will get you started, and `make dev` will run the app.
Run `just` followed by any of these commands when appropriate rather than directly using the equivalent commands like `mix`, `docker`, `docker-compose`, etc. For example, `just setup` will get you started, and `just dev` will run the app.
You can first set an env variable to control which mode these commands will assume you're using. Here are your options:
@ -213,68 +196,8 @@ You can first set an env variable to control which mode these commands will assu
- `WITH_DOCKER=easy` : use docker for services like the DB & compiled utilities like messctl
- `WITH_DOCKER=no` : please no
```
make help Makefile commands help **(run this to get more up-to-date commands and help information than available in this document)**
make mix~help Help info for elixir's mix commands
make env.exports Display the vars from dotenv files that you need to load in your environment
Run `just help` to see the list of possible commands and what they do.
make setup First run - prepare environment and dependencies
make dev Run the app in development
make dev.bg Run the app in dev mode, as a background service
make db.reset Reset the DB (caution: this means DATA LOSS)
make db.rollback Rollback previous DB migration (caution: this means DATA LOSS)
make db.rollback.all Rollback ALL DB migrations (caution: this means DATA LOSS)
make update Update the app and all dependencies/extensions/forks, and run migrations
make update.app Update the app and Bonfire extensions in ./deps
make update.deps.bonfire Update to the latest Bonfire extensions in ./deps
make update.deps.all Update evey single dependency (use with caution)
make update.dep~% Update a specify dep (eg. `make update.dep~pointers`)
make update.forks Pull the latest commits from all ./forks
make deps.get Fetch locked version of non-forked deps
make dep.clone.local Clone a git dep and use the local version, eg: `make dep.clone.local dep=bonfire_me repo=https://github.com/bonfire-networks/bonfire_me`
make deps.clone.local.all Clone all bonfire deps / extensions
make dep.go.local~% Switch to using a local path, eg: make dep.go.local~pointers
make dep.go.local.path Switch to using a local path, specifying the path, eg: make dep.go.local dep=pointers path=./libs/pointers
make dep.go.git Switch to using a git repo, eg: make dep.go.git dep=pointers repo=https://github.com/bonfire-networks/pointers (specifying the repo is optional if previously specified)
make dep.go.hex Switch to using a library from hex.pm, eg: make dep.go.hex dep=pointers version="~> 0.2" (specifying the version is optional if previously specified)
make dep.hex~% add/enable/disable/delete a hex dep with messctl command, eg: `make dep.hex.enable dep=pointers version="~> 0.2"
make dep.git~% add/enable/disable/delete a git dep with messctl command, eg: `make dep.hex.enable dep=pointers repo=https://github.com/bonfire-networks/pointers#main
make dep.local~% add/enable/disable/delete a local dep with messctl command, eg: `make dep.hex.enable dep=pointers path=./libs/pointers
make messctl~% Utility to manage the deps in deps.hex, deps.git, and deps.path (eg. `make messctl~help`)
make contrib.forks Push all changes to the app and extensions in ./forks
make contrib.release Push all changes to the app and extensions in ./forks, increment the app version number, and push a new version/release
make contrib.app.up Update ./deps and push all changes to the app
make contrib.app.release Update ./deps, increment the app version number and push
make git.forks.add Run the git add command on each fork
make git.forks~% Run a git command on each fork (eg. `make git.forks~pull` pulls the latest version of all local deps from its git remote
make test Run tests. You can also run only specific tests, eg: `make test only=forks/bonfire_social/test`
make test.stale Run only stale tests
make test.remote Run tests (ignoring changes in local forks)
make test.watch Run stale tests, and wait for changes to any module's code, and re-run affected tests
make test.db.reset Create or reset the test DB
make rel.build Build the Docker image using previous cache
make rel.tag.latest Add latest tag to last build
make rel.push Add latest tag to last build and push to Docker Hub
make rel.run Run the app in Docker & starts a new `iex` console
make rel.run.bg Run the app in Docker, and keep running in the background
make rel.stop Run the app in Docker, and keep running in the background
make rel.shell Runs a simple shell inside of the container, useful to explore the image
make services Start background docker services (eg. db and search backends). This is automatically done for you if using Docker.
make build Build the docker image
make cmd~% Run a specific command in the container, eg: `make cmd-messclt` or `make cmd~time` or `make cmd~echo args=hello`
make shell Open the shell of the Docker web container, in dev mode
make mix~% Run a specific mix command, eg: `make mix~deps.get` or `make mix~deps.update args=pointers`
make mix.remote~% Run a specific mix command, while ignoring any deps cloned into ./forks, eg: `make mix~deps.get` or `make mix~deps.update args=pointers`
make deps.git.fix Run a git command on each dep, to ignore chmod changes
make git.merge~% Draft-merge another branch, eg `make git-merge-with-valueflows-api` to merge branch `with-valueflows-api` into the current one
make git.conflicts Find any git conflicts in ./forks
```
## Troubleshooting

View File

@ -1,6 +1,7 @@
## SECRET CONFIG VARIABLES
# COPY this file to /config/{dev|prod}/secrets.env and change ALL the values
# make sure you change everything to your own secrets!
# and do not check this into git or any public host
# make sure you change everything to your own secrets and do not check this into git or any public host!
# for sessions/cookies, you can generate strings for these by running: make secrets
SECRET_KEY_BASE="you-should-put-a-secure-string-here"
@ -35,4 +36,5 @@ WEB_PUSH_SUBJECT=mailto:administrator@mydomain.net
WEB_PUSH_PUBLIC_KEY=xyz
WEB_PUSH_PRIVATE_KEY=abc
GEOLOCATE_OPENCAGEDATA=
GITHUB_TOKEN=xyz
GITHUB_TOKEN=xyz

View File

@ -1,3 +1,5 @@
## PUBLIC CONFIG VARIABLES
FLAVOUR=classic
# COPY this file to /config/{dev|prod}/public.env and change any values as required
# server domain name:
@ -27,3 +29,4 @@ REPLACE_OS_VARS=true
LIVEVIEW_ENABLED=true
SHOW_DEBUG_IN_DEV=true
ACME_AGREE=true

511
justfile Normal file
View File

@ -0,0 +1,511 @@
# recipes for the `just` command runner: https://just.systems
# how to install: https://github.com/casey/just#packages
## Main configs - override these using env vars
# what flavour do we want?
FLAVOUR := env_var_or_default('FLAVOUR', "classic")
FLAVOUR_PATH := env_var_or_default('FLAVOUR_PATH', "flavours/" + FLAVOUR)
# do we want to use Docker? set as env var:
# - WITH_DOCKER=total : use docker for everything (default)
# - WITH_DOCKER=partial : use docker for services like the DB
# - WITH_DOCKER=easy : use docker for services like the DB & compiled utilities like messctl
# - WITH_DOCKER=no : please no
WITH_DOCKER := env_var_or_default('WITH_DOCKER', "total")
MIX_ENV := env_var_or_default('MIX_ENV', "dev")
## Other configs - edit these here if necessary
FORKS_PATH := "forks/"
ORG_NAME := "bonfirenetworks"
APP_NAME := "bonfire"
APP_VSN_EXTRA := "alpha"
DB_DOCKER_IMAGE := "postgis/postgis:12-3.1-alpine"
APP_REL_DOCKERFILE :="Dockerfile.release"
APP_REL_DOCKERCOMPOSE :="docker-compose.release.yml"
APP_REL_CONTAINER := APP_NAME + "_release"
WEB_CONTAINER := APP_NAME +"_web"
APP_VSN := `grep -m 1 'version:' mix.exs | cut -d '"' -f2`
APP_BUILD := `git rev-parse --short HEAD`
APP_DOCKER_REPO := ORG_NAME+"/"+APP_NAME+"-"+FLAVOUR
CONFIG_PATH := FLAVOUR_PATH + "/config"
UID := `id -u`
GID := `id -g`
# Configure just
set shell := ["bash", "-uc"]
# set shell := ["bash", "-uxc"]
set dotenv-load
set export
set positional-arguments
#### GENERAL SETUP RELATED COMMANDS ####
help:
@echo "Just commands for Bonfire:"
@just --list
pre-setup flavour:
@echo "Using flavour '$flavour' at flavours/$flavour with env '$MIX_ENV'"
@ln -sfn flavours/$flavour/config ./config
@mkdir -p data/
@rm -rf ./data/current_flavour
@ln -sf ../flavours/$flavour ./data/current_flavour
@mkdir -p ./config/prod
@mkdir -p ./config/dev
@touch ./config/deps.path
@test -f ./config/$MIX_ENV/.env || ((test -f ./config/$MIX_ENV/public.env && (cat ./config/$MIX_ENV/public.env ./config/$MIX_ENV/secrets.env > ./config/$MIX_ENV/.env) && rm ./config/$MIX_ENV/public.env && rm ./config/$MIX_ENV/secrets.env) || (cat ./config/templates/public.env ./config/templates/not_secret.env > ./config/$MIX_ENV/.env) && echo "MIX_ENV=$MIX_ENV" >> ./config/$MIX_ENV/.env)
@ln -sf ./config/$MIX_ENV/.env ./.env
@mkdir -p forks/
@mkdir -p data/uploads/
@mkdir -p priv/static/data
@ln -s data/uploads priv/static/data/ | true
@mkdir -p data/search/dev
@chmod 700 .erlang.cookie
# Initialise env files, and create some required folders, files and softlinks
config select_flavour:
@echo "Switching to flavour '$select_flavour'..."
@just pre-setup $select_flavour
@echo "You can now edit your config for flavour '$select_flavour' in /.env and ./config/ more generally."
pre-init:
@echo "Using flavour: $FLAVOUR at path: $FLAVOUR_PATH"
@rm -rf ./priv/repo
@cp -rn $FLAVOUR_PATH/repo ./priv/repo
init: pre-init services
@echo "Light that fire... $APP_NAME with $FLAVOUR flavour in $MIX_ENV - docker:$WITH_DOCKER - $APP_VSN - $APP_BUILD - $FLAVOUR_PATH"
#### COMMON COMMANDS ####
# First run - prepare environment and dependencies
setup:
just pre-setup $FLAVOUR
just build
just mix setup
just js-deps-get
# Prepare environment and dependencies
prepare:
just pre-setup $FLAVOUR
just build
# Run the app in development
dev: init dev-run
dev-run:
{{ if WITH_DOCKER == "total" { "just docker-stop-web && docker-compose run --name $WEB_CONTAINER --service-ports web" } else { "iex -S mix phx.server" } }}
# Generate docs from code & readmes
docs:
just mix-remote docs
# Force the app to recompile
recompile:
just mix "compile --force"
dev-test:
@MIX_ENV=test START_SERVER=true just dev-run
# Run the app in dev mode, as a background service
dev-bg: init
{{ if WITH_DOCKER == "total" { "just docker-stop-web && docker-compose run --detach --name $WEB_CONTAINER --service-ports web elixir -S mix phx.server" } else { 'elixir --erl "-detached" -S mix phx.server" && echo "Running in background..." && (ps au | grep beam)' } }}
# Run latest database migrations (eg. after adding/upgrading an app/extension)
db-migrate:
just mix ecto.migrate
# Run latest database seeds (eg. inserting required data after adding/upgrading an app/extension)
db-seeds:
just mix ecto.migrate
just mix ecto.seeds
# Reset the DB (caution: this means DATA LOSS)
db-reset: init dev-search-reset db-pre-migrations
just mix ecto.reset
dev-search-reset:
{{ if WITH_DOCKER != "no" { "docker-compose rm -s -v search" } else {""} }}
rm -rf data/search/dev
# Rollback previous DB migration (caution: this means DATA LOSS)
db-rollback:
just mix ecto.rollback
# Rollback ALL DB migrations (caution: this means DATA LOSS)
db-rollback-all:
just mix "ecto.rollback --all"
#### UPDATE COMMANDS ####
# Update the dev app and all dependencies/extensions/forks, and run migrations
update: init update-repo
just prepare
just update-forks
just update-deps
just mix deps.get
just mix ecto.migrate
just js-deps-get
# Update the app and Bonfire extensions in ./deps
update-app: update-repo update-deps
# Update Bonfire extensions in ./deps
update-deps:
@rm -rf deps/*/assets/pnpm-lock.yaml
just mix-remote updates
update-repo:
@chmod +x git-publish.sh && ./git-publish.sh . pull || git pull
update-repo-pull:
@chmod +x git-publish.sh && ./git-publish.sh . pull only
# Update to the latest Bonfire extensions in ./deps
update-deps-bonfire:
just mix-remote bonfire.deps
# Update evey single dependency (use with caution)
update-deps-all:
just update.dep "--all"
# Update a specify dep (eg. `just update.dep pointers`)
update-dep dep:
@chmod +x git-publish.sh && ./git-publish.sh $FORKS_PATH/$dep pull
just mix-remote "deps.update $dep"
# Pull the latest commits from all ./forks
update-forks:
@jungle git fetch || echo "Jungle not available, will fetch one by one instead."
@chmod +x git-publish.sh && find $FORKS_PATH -mindepth 1 -maxdepth 1 -type d -exec ./git-publish.sh {} maybe-pull \;
# TODO: run in parallel? find $FORKS_PATH -mindepth 1 -maxdepth 1 -type d | xargs -P 50 -I '{}' ./git-publish.sh '{}'
# Pull the latest commits from all ./forks
update-fork dep:
@chmod +x git-publish.sh && find $FORKS_PATH/$dep -mindepth 0 -maxdepth 0 -type d -exec ./git-publish.sh {} pull \;
# Fetch locked version of non-forked deps
deps-get:
just mix-remote deps.get
just mix deps.get
just js-ext-deps-get
deps-clean-data:
just mix bonfire.deps.clean.data
deps-clean-api:
just mix bonfire.deps.clean.api
#### DEPENDENCY & EXTENSION RELATED COMMANDS ####
js-deps-get: js-assets-deps-get js-ext-deps-get
js-assets-deps-get:
@pnpm -v || npm -g install pnpm
@chmod +x ./assets/install.sh
just cmd ./assets/install.sh
js-ext-deps-get:
@chmod +x ./config/deps.js.sh
just cmd ./config/deps.js.sh
deps-outdated:
@just mix-remote "hex.outdated --all"
dep-clean dep:
@just mix "deps.clean $dep --build"
# Clone a git dep and use the local version, eg: `just dep-clone-local bonfire_me https://github.com/bonfire-networks/bonfire_me`
dep-clone-local dep repo:
git clone $repo $FORKS_PATH$dep 2> /dev/null || (cd $FORKS_PATH$dep ; git pull)
just dep.go.local dep=$dep
# Clone all bonfire deps / extensions
deps-clone-local-all:
@curl -s https://api.github.com/orgs/bonfire-networks/repos?per_page=500 | ruby -rrubygems -e 'require "json"; JSON.load(STDIN.read).each { |repo| %x[just dep.clone.local dep="#{repo["name"]}" repo="#{repo["ssh_url"]}" ]}'
# Switch to using a local path, eg: just dep.go.local pointers
dep-go-local dep:
just dep-go-local-path $dep $FORKS_PATH$dep
# Switch to using a local path, specifying the path, eg: just dep.go.local dep=pointers path=./libs/pointers
dep-go-local-path dep path:
just dep-local add $dep $path
just dep-local enable $dep $path
# Switch to using a git repo, eg: just dep.go.git pointers https://github.com/bonfire-networks/pointers (specifying the repo is optional if previously specified)
dep-go-git dep repo:
just dep-git add $dep $repo 2> /dev/null || true
just dep-git enable $dep NA
just dep-local disable $dep NA
# Switch to using a library from hex.pm, eg: just dep.go.hex dep="pointers" version="_> 0.2" (specifying the version is optional if previously specified)
dep-go-hex dep version:
just dep-hex add dep=$dep version=$version 2> /dev/null || true
just dep-hex enable $dep NA
just dep-git disable $dep NA
just dep-local disable $dep NA
# add/enable/disable/delete a hex dep with messctl command, eg: `just dep-hex enable pointers 0.2`
dep-hex command dep version:
just messctl "$command $dep $version"
just mix "deps.clean $dep"
# add/enable/disable/delete a git dep with messctl command, eg: `just dep-hex enable pointers https://github.com/bonfire-networks/pointers#main
dep-git command dep repo:
just messctl "$command $dep $repo config/deps.git"
just mix "deps.clean $dep"
# add/enable/disable/delete a local dep with messctl command, eg: `just dep-hex enable pointers ./libs/pointers`
dep-local command dep path:
just messctl "$command $dep $path config/deps.path"
just mix "deps.clean $dep"
# Utility to manage the deps in deps.hex, deps.git, and deps.path (eg. `just messctl help`)
messctl *args='': init
{{ if WITH_DOCKER == "no" { "messctl $@" } else { "docker-compose run web messctl $@" } }}
#### CONTRIBUTION RELATED COMMANDS ####
# Push all changes to the app and extensions in ./forks
contrib-forks: contrib-forks-publish git-publish
# Push all changes to the app and extensions in ./forks, increment the app version number, and push a new version/release
contrib-release: contrib-forks-publish contrib-app-release
# Update ./deps and push all changes to the app
contrib-app-up: update-app git-publish
# Update ./deps, increment the app version number and push
contrib-app-release: update-app contrib-app-release-increment git-publish
contrib-app-release-increment:
@cd lib/mix/tasks/release/ && mix escript.build && ./release ../../../../ $APP_VSN_EXTRA
contrib-forks-publish:
@jungle git fetch || echo "Jungle not available, will fetch one by one instead."
@chmod +x git-publish.sh && find $FORKS_PATH -mindepth 1 -maxdepth 1 -type d -exec ./git-publish.sh {} \;
# TODO: run in parallel?
# Run the git add command on each fork
git-forks-add: deps-git-fix
find $FORKS_PATH -mindepth 1 -maxdepth 1 -type d -exec echo add {} \; -exec git -C '{}' add --all . \;
# Run a git status on each fork
git-forks-status:
@jungle git status || find $FORKS_PATH -mindepth 1 -maxdepth 1 -type d -exec echo {} \; -exec git -C '{}' status \;
# Run a git command on each fork (eg. `just git-forks pull` pulls the latest version of all local deps from its git remote
git-forks command:
@find $FORKS_PATH -mindepth 1 -maxdepth 1 -type d -exec echo $command {} \; -exec git -C '{}' $command \;
# List all diffs in forks
git-diff:
@find $FORKS_PATH -mindepth 1 -maxdepth 1 -type d -exec echo {} \; -exec git -C '{}' --no-pager diff --color --exit-code \;
# Run a git command on each dep, to ignore chmod changes
deps-git-fix:
find ./deps -mindepth 1 -maxdepth 1 -type d -exec git -C '{}' config core.fileMode false \;
find ./forks -mindepth 1 -maxdepth 1 -type d -exec git -C '{}' config core.fileMode false \;
# Draft-merge another branch, eg `just git-merge with-valueflows-api` to merge branch `with-valueflows-api` into the current one
git-merge branch:
git merge --no-ff --no-commit $branch
# Find any git conflicts in ./forks
git-conflicts:
find $FORKS_PATH -mindepth 1 -maxdepth 1 -type d -exec echo add {} \; -exec git -C '{}' diff --name-only --diff-filter=U \;
git-publish:
chmod +x git-publish.sh
./git-publish.sh
#### TESTING RELATED COMMANDS ####
# Run tests. You can also run only specific tests, eg: `just test forks/bonfire_social/test`
test *args='':
@MIX_ENV=test just mix test $@
# Run only stale tests
test-stale *args='':
@MIX_ENV=test just mix test --stale $@
# Run tests (ignoring changes in local forks)
test-remote *args='':
@MIX_ENV=test just mix-remote test $@
# Run stale tests, and wait for changes to any module code, and re-run affected tests
test-watch *args='':
@MIX_ENV=test just mix test.watch --stale $@
# Run stale tests, and wait for changes to any module code, and re-run affected tests, and interactively choose which tests to run
test-interactive *args='':
@MIX_ENV=test just mix test.interactive --stale $@
# dev-test-watch: init ## Run tests
# docker-compose run --service-ports -e MIX_ENV=test web iex -S mix phx.server
# Create or reset the test DB
test-db-reset: init db-pre-migrations
{{ if WITH_DOCKER == "total" { "docker-compose run -e MIX_ENV=test web mix ecto.reset" } else { "MIX_ENV=test mix ecto.reset" } }}
#### RELEASE RELATED COMMANDS (Docker-specific for now) ####
rel-env:
$(eval export MIX_ENV=prod)
$(eval export)
# copy current flavour's config, without using symlinks
rel-config-prepare: rel-env
rm -rf ./data/current_flavour
mkdir -p data
@cp -rfL $FLAVOUR_PATH ./data/current_flavour
# copy current flavour's config, without using symlinks
rel-prepare: rel-env rel-config-prepare
@mkdir -p forks/ && mkdir -p data/uploads/ && touch data/current_flavour/config/deps.path
# Build the Docker image
rel-rebuild: rel-env init rel-prepare assets-prepare
docker build \
--no-cache \
--build-arg FLAVOUR_PATH=data/current_flavour \
--build-arg APP_NAME=$APP_NAME \
--build-arg APP_VSN=$APP_VSN \
--build-arg APP_BUILD=$APP_BUILD \
-t $APP_DOCKER_REPO:$APP_VSN-release-$APP_BUILD \
-f $APP_REL_DOCKERFILE .
@echo Build complete: $APP_DOCKER_REPO:$APP_VSN-release-$APP_BUILD
# Build the Docker image using previous cache
rel-build: rel-env init rel-prepare assets-prepare
@echo "Building $APP_NAME with flavour $FLAVOUR"
docker build \
--build-arg FLAVOUR_PATH=data/current_flavour \
--build-arg APP_NAME=$APP_NAME \
--build-arg APP_VSN=$APP_VSN \
--build-arg APP_BUILD=$APP_BUILD \
-t $APP_DOCKER_REPO:$APP_VSN-release-$APP_BUILD \
-f $APP_REL_DOCKERFILE .
@echo Build complete: $APP_DOCKER_REPO:$APP_VSN-release-$APP_BUILD
@echo "Remember to run just rel.tag.latest or just rel.push"
# Add latest tag to last build
rel-tag-latest: rel-env
@docker tag $APP_DOCKER_REPO:$APP_VSN-release-$APP_BUILD $APP_DOCKER_REPO:latest
# Add latest tag to last build and push to Docker Hub
rel-push: rel-env
@docker push $APP_DOCKER_REPO:latest
# Run the app in Docker & starts a new `iex` console
rel-run: rel-env init docker-stop-web
@docker-compose -p $APP_REL_CONTAINER -f $APP_REL_DOCKERCOMPOSE run --name $WEB_CONTAINER --service-ports --rm web bin/bonfire start_iex
# Run the app in Docker, and keep running in the background
rel-run-bg: rel-env init docker-stop-web
@docker-compose -p $APP_REL_CONTAINER -f $APP_REL_DOCKERCOMPOSE up -d
# Stop the running release
rel-stop: rel-env
@docker-compose -p $APP_REL_CONTAINER -f $APP_REL_DOCKERCOMPOSE stop
rel-update: rel-env update-repo-pull
@docker-compose -p $APP_REL_CONTAINER -f $APP_REL_DOCKERCOMPOSE pull
@echo Remember to run migrations on your DB...
rel-logs:
@docker-compose -p $APP_REL_CONTAINER -f $APP_REL_DOCKERCOMPOSE logs
# Stop the running release
rel-down: rel-env rel-stop
@docker-compose -p $APP_REL_CONTAINER -f $APP_REL_DOCKERCOMPOSE down
# Runs a the app container and opens a simple shell inside of the container, useful to explore the image
rel-shell: rel-env init docker-stop-web
@docker-compose -p $APP_REL_CONTAINER -f $APP_REL_DOCKERCOMPOSE run --name $WEB_CONTAINER --service-ports --rm web /bin/bash
# Runs a simple shell inside of the running app container, useful to explore the image
rel-shell-bg: rel-env init
@docker-compose -p $APP_REL_CONTAINER -f $APP_REL_DOCKERCOMPOSE exec web /bin/bash
# Runs a simple shell inside of the DB container, useful to explore the image
rel-db-shell-bg: rel-env init
@docker-compose -p $APP_REL_CONTAINER -f $APP_REL_DOCKERCOMPOSE exec db /bin/bash
rel-db-dump: rel-env init
docker-compose -p $APP_REL_CONTAINER -f $APP_REL_DOCKERCOMPOSE exec db /bin/bash -c "PGPASSWORD=$POSTGRES_PASSWORD pg_dump --username $POSTGRES_USER $POSTGRES_DB" > data/db_dump.sql
rel-db-restore: rel-env init
cat $file | docker exec -i bonfire_release_db_1 /bin/bash -c "PGPASSWORD=$POSTGRES_PASSWORD psql -U $POSTGRES_USER $POSTGRES_DB"
rel-services:
{{ if WITH_DOCKER != "no" { "docker-compose -p $APP_REL_CONTAINER -f $APP_REL_DOCKERCOMPOSE up -d db search" } else {""} }}
#### DOCKER-SPECIFIC COMMANDS ####
# Start background docker services (eg. db and search backends).
services:
@{{ if MIX_ENV == "prod" { "just rel-services" } else { "just dev-services" } }}
dev-services:
@{{ if WITH_DOCKER != "no" { "docker-compose up -d db search" } else {""} }}
# Build the docker image
build: init
{{ if WITH_DOCKER != "no" { "mkdir -p deps && docker-compose pull && docker-compose build" } else { "Skip building container..." } }}
# Build the docker image
rebuild: init
{{ if WITH_DOCKER != "no" { "mkdir -p deps && docker-compose build --no-cache" } else { "Skip building container..." } }}
# Run a specific command in the container (if used), eg: `just cmd messclt` or `just cmd time` or `just cmd "echo hello"`
cmd *args='': init
@{{ if WITH_DOCKER == "total" { "docker-compose run --service-ports web $@" } else {"$@"} }}
# Open the shell of the web container, in dev mode
shell:
@just cmd bash
docker-stop-web:
@docker stop $WEB_CONTAINER 2> /dev/null || true
@docker rm $WEB_CONTAINER 2> /dev/null || true
#### MISC COMMANDS ####
# Run a specific mix command, eg: `just mix deps.get` or `just mix "deps.update pointers"`
mix *args='':
@just cmd mix $@
# Run a specific mix command, while ignoring any deps cloned into ./forks, eg: `just mix-remote deps.get` or `just mix-remote deps.update pointers`
mix-remote *args='': init
{{ if WITH_DOCKER == "total" { "docker-compose run -e WITH_FORKS=0 web mix $@" } else {"WITH_FORKS=0 mix $@"} }}
# Run a specific exh command, see https://github.com/rowlandcodes/exhelp
exh *args='':
@just cmd "exh -S mix $@"
licenses:
@mkdir -p docs/DEPENDENCIES/
just mix-remote licenses && mv DEPENDENCIES.md docs/DEPENDENCIES/$FLAVOUR.md
# Extract strings to-be-localised from the app and installed extensions
localise-extract:
@just mix "bonfire.localise.extract --merge"
assets-prepare:
@cp lib/*/*/overlay/* rel/overlays/ 2> /dev/null || true
# Workarounds for some issues running migrations
db-pre-migrations:
touch deps/*/lib/migrations.ex 2> /dev/null || echo "continue"
touch forks/*/lib/migrations.ex 2> /dev/null || echo "continue"
touch priv/repo/* 2> /dev/null || echo "continue"
# Generate secrets
secrets:
@cd lib/mix/tasks/secrets/ && mix escript.build && ./secrets 128 3

View File

@ -3,7 +3,7 @@ defmodule Bonfire.MixProject do
use Mix.Project
@config [ # TODO: put these in ENV or an external writeable config file similar to deps.*
version: "0.2.0-alpha.100", # note that the flavour will automatically be added where the dash appears
version: "0.2.0-alpha.101", # note that the flavour will automatically be added where the dash appears
elixir: "~> 1.13",
default_flavour: "classic",
logo: "assets/static/images/bonfire-icon.png",

View File

@ -26,7 +26,7 @@
"bonfire_data_social": {:git, "https://github.com/bonfire-networks/bonfire_data_social", "75da41940b0dfd9f572804f8ffbfce29f213e041", [branch: "main"]},
"bonfire_ecto": {:git, "https://github.com/bonfire-networks/bonfire_ecto", "88ad2c495c07a33d7df0f0b825e96c2b9cf1f2e0", [branch: "main"]},
"bonfire_editor_ck": {:git, "https://github.com/bonfire-networks/bonfire_editor_ck", "bac3329a5679cd990a98bf6923fcbb1daa89ab2b", [branch: "main"]},
"bonfire_editor_quill": {:git, "https://github.com/bonfire-networks/bonfire_editor_quill", "a17141645b83dfac98a65ff01d66be3eb91113ca", [branch: "main"]},
"bonfire_editor_quill": {:git, "https://github.com/bonfire-networks/bonfire_editor_quill", "ab758f018b872b85688e24b5b45715694a71739d", [branch: "main"]},
"bonfire_epics": {:git, "https://github.com/bonfire-networks/bonfire_epics", "34300053dbafa9b9cfede22bd4e6433d04344b69", [branch: "main"]},
"bonfire_fail": {:git, "https://github.com/bonfire-networks/bonfire_fail", "4ce2a1254c68388f8877e1c86dfd782a773600ea", [branch: "main"]},
"bonfire_federate_activitypub": {:git, "https://github.com/bonfire-networks/bonfire_federate_activitypub", "b718a551fd9e279cd15197f5f3705dc2c2790083", [branch: "main"]},
@ -40,7 +40,7 @@
"bonfire_search": {:git, "https://github.com/bonfire-networks/bonfire_search", "76fff2546ac4fd8c4fd06c892d09febe01de1f37", [branch: "main"]},
"bonfire_social": {:git, "https://github.com/bonfire-networks/bonfire_social", "ab18ec60d51cb4bea459670659c469e71556dea3", [branch: "main"]},
"bonfire_tag": {:git, "https://github.com/bonfire-networks/bonfire_tag", "ee02c6290a132a5b8da7d7c7e80cca1fe516ebbe", [branch: "main"]},
"bonfire_ui_common": {:git, "https://github.com/bonfire-networks/bonfire_ui_common", "6eeae70a59d04a4bdb74e06ab5d6c0855d24dbe3", [branch: "main"]},
"bonfire_ui_common": {:git, "https://github.com/bonfire-networks/bonfire_ui_common", "58251ae453edfa367e3257566631d7b2ff7a4f7a", [branch: "main"]},
"bonfire_ui_coordination": {:git, "https://github.com/bonfire-networks/bonfire_ui_coordination", "40b24b68b542c31a0c99be2650b8148c5ad01161", [branch: "main"]},
"bonfire_ui_kanban": {:git, "https://github.com/bonfire-networks/bonfire_ui_kanban", "69f42c5c38e5d63e4e60b4ef8d0191224c297b14", [branch: "main"]},
"bonfire_ui_me": {:git, "https://github.com/bonfire-networks/bonfire_ui_me", "fee5284fb3fb0a1fc03c7869c7e25475631a5ef4", [branch: "main"]},