mirror of
https://github.com/bonfire-networks/bonfire-app.git
synced 2024-05-10 13:12:40 +00:00
update makefile & add docs
This commit is contained in:
parent
b514a165c3
commit
61d195ad51
454
Makefile
454
Makefile
|
@ -1,12 +1,21 @@
|
|||
.PHONY: setup updates db-reset build dev shell
|
||||
|
||||
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
|
||||
BONFIRE_FLAVOUR ?= flavours/$(FLAVOUR)
|
||||
|
||||
LIBS_PATH ?= ./forks/
|
||||
# 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/
|
||||
ORG_NAME ?= bonfirenetworks
|
||||
APP_NAME ?= bonfire-$(FLAVOUR)
|
||||
UID := $(shell id -u)
|
||||
|
@ -18,6 +27,8 @@ 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)"
|
||||
|
||||
#### GENERAL SETUP RELATED COMMANDS ####
|
||||
|
||||
export UID
|
||||
export GID
|
||||
|
||||
|
@ -33,8 +44,11 @@ define load_env
|
|||
$(eval include $(ENV_FILE)) # import env into make
|
||||
$(eval export) # export env from make
|
||||
endef
|
||||
|
||||
init:
|
||||
|
||||
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/dev/secrets.env, config/dev/public.env and ./config/ more generally."
|
||||
|
||||
pre-init:
|
||||
@ln -sfn $(BONFIRE_FLAVOUR)/config ./config
|
||||
@mkdir -p config/prod
|
||||
@mkdir -p config/dev
|
||||
|
@ -43,212 +57,197 @@ init:
|
|||
@cp -n config/templates/public.env config/prod/ | true
|
||||
@cp -n config/templates/not_secret.env config/dev/secrets.env | true
|
||||
@cp -n config/templates/not_secret.env config/prod/secrets.env | true
|
||||
@$(call setup_env,dev)
|
||||
@echo "Light that fire... $(APP_NAME) with $(FLAVOUR) flavour $(APP_VSN) - $(APP_BUILD)"
|
||||
|
||||
pre-run:
|
||||
@mkdir -p forks/
|
||||
@mkdir -p data/uploads/
|
||||
@mkdir -p data/search/dev
|
||||
|
||||
help: init
|
||||
@perl -nle'print $& if m{^[a-zA-Z_-]+:.*?## .*$$}' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
||||
|
||||
mix-%: init ## Run a specific mix command, eg: `make mix-deps.get` or make mix-deps.update args="pointers"
|
||||
docker-compose run web mix $* $(args)
|
||||
init: pre-init pre-run
|
||||
@$(call setup_env,dev)
|
||||
@echo "Light that fire... $(APP_NAME) with $(FLAVOUR) flavour $(APP_VSN) - $(APP_BUILD)"
|
||||
@make --no-print-directory pre-init
|
||||
@make --no-print-directory services
|
||||
|
||||
setup: build mix-setup ## First run - prepare environment and dependencies
|
||||
help: init ## 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}'
|
||||
|
||||
db:
|
||||
docker-compose up -d db search
|
||||
env.exports: ## Display the vars from dotenv files that you need to load in your environment
|
||||
@awk 'NF { if( $$1 != "#" ){ print "export " $$0 }}' $(BONFIRE_FLAVOUR)/config/dev/*.env
|
||||
|
||||
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"
|
||||
|
||||
db-reset: db-pre-migrations mix-ecto.reset ## Reset the DB
|
||||
#### COMMON COMMANDS ####
|
||||
|
||||
db-rollback: ## Rollback last DB migration
|
||||
make mix-"ecto.rollback"
|
||||
setup: build mix~setup ## First run - prepare environment and dependencies
|
||||
|
||||
db-rollback-all: ## Rollback ALL DB migrations
|
||||
make mix-"ecto.rollback --all"
|
||||
dev: init ## Run the app in development
|
||||
ifeq ($(WITH_DOCKER), total)
|
||||
@make --no-print-directory docker.stop.web
|
||||
docker-compose run --name bonfire_web --service-ports web
|
||||
# docker-compose --verbose run --name bonfire_web --service-ports web
|
||||
else
|
||||
iex -S mix phx.server
|
||||
endif
|
||||
|
||||
test-db-reset: db-pre-migrations ## Create or reset the test DB
|
||||
docker-compose run -e MIX_ENV=test web mix ecto.reset
|
||||
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 bonfire_web --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
|
||||
|
||||
build: init ## Build the docker image
|
||||
docker-compose build
|
||||
db.reset: db.pre-migrations mix~ecto.reset ## Reset the DB (caution: this means DATA LOSS)
|
||||
|
||||
shell: init ## Open a shell, in dev mode
|
||||
docker-compose run --service-ports web bash
|
||||
db.rollback: mix~ecto.rollback ## Rollback previous DB migration (caution: this means DATA LOSS)
|
||||
|
||||
pull:
|
||||
git pull
|
||||
db.rollback.all: mix~"ecto.rollback --all" ## Rollback ALL DB migrations (caution: this means DATA LOSS)
|
||||
|
||||
update: init pull ## Update/prepare dependencies, without Docker
|
||||
WITH_FORKS=0 mix updates
|
||||
make deps-all-git-pull
|
||||
mix deps.get
|
||||
mix ecto.migrate
|
||||
|
||||
d-update: init pull build ## Update/prepare dependencies, using Docker
|
||||
docker-compose run -e WITH_FORKS=0 web mix updates
|
||||
make deps-all-git-pull
|
||||
make mix-deps.get
|
||||
make mix-ecto.migrate
|
||||
#### UPDATE COMMANDS ####
|
||||
|
||||
bonfire-updates: init
|
||||
docker-compose run -e WITH_FORKS=0 web mix bonfire.deps
|
||||
|
||||
bonfire-push-all-updates: deps-all-git-commit-push bonfire-push-app-updates
|
||||
update: init update.app build update.forks mix~deps.get mix~ecto.migrate ## Update the app and all dependencies/extensions/forks, and run migrations
|
||||
|
||||
bonfire-push-release: deps-all-git-commit-push bonfire-push-app-release
|
||||
|
||||
bonfire-app-updates:
|
||||
update.app: ## Update the app and Bonfire extensions in ./deps
|
||||
git add --all .
|
||||
git diff-index --quiet HEAD || git commit --all --verbose
|
||||
git pull --rebase
|
||||
WITH_FORKS=0 mix updates
|
||||
@make --no-print-directory mix.remote~updates
|
||||
|
||||
bonfire-push-app-updates: bonfire-app-updates
|
||||
make git-publish
|
||||
|
||||
bonfire-push-app-release: bonfire-app-updates
|
||||
cd lib/mix/tasks/release/ && mix escript.build && ./release ../../../../ alpha
|
||||
make git-publish
|
||||
|
||||
bonfire-deps-updates:
|
||||
git pull --rebase
|
||||
WITH_FORKS=0 mix updates
|
||||
make git-publish
|
||||
|
||||
d-bonfire-push-all-updates: deps-all-git-commit-push d-bonfire-push-app-updates
|
||||
|
||||
d-bonfire-push-app-updates:
|
||||
git add .
|
||||
git commit -a
|
||||
git pull --rebase
|
||||
docker-compose run -e WITH_FORKS=0 web mix updates
|
||||
make git-publish
|
||||
make dev
|
||||
|
||||
git-publish:
|
||||
chmod +x git-publish.sh
|
||||
./git-publish.sh
|
||||
|
||||
dep-hex-%: init ## add/enable/disable/delete a hex dep with messctl command, eg: `make dep-hex-enable dep=pointers version="~> 0.2"
|
||||
docker-compose run web messctl $* $(dep) $(version) config/deps.hex
|
||||
|
||||
dep-git-%: init ## 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
|
||||
docker-compose run web messctl $* $(dep) $(repo) config/deps.git
|
||||
|
||||
dep-local-%: init ## add/enable/disable/delete a local dep with messctl command, eg: `make dep-hex-enable dep=pointers path=./libs/pointers
|
||||
docker-compose run web messctl $* $(dep) $(path) config/deps.path
|
||||
|
||||
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) $(LIBS_PATH)$(dep) 2> /dev/null || (cd $(LIBS_PATH)$(dep) ; git pull)
|
||||
make dep-go-local dep=$(dep)
|
||||
|
||||
dep-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"]}" ]}'
|
||||
|
||||
deps-all-git-commit-push:
|
||||
chmod +x git-publish.sh
|
||||
find $(LIBS_PATH) -mindepth 1 -maxdepth 1 -type d -exec ./git-publish.sh {} \;
|
||||
# make deps-all-git-add
|
||||
# make deps-all-git-commit
|
||||
# make deps-all-git-pull
|
||||
# make deps-all-git-push
|
||||
|
||||
deps-all-git-%: ## runs a git command (eg. `make deps-all-git-pull` pulls the latest version of all local deps from its git remote
|
||||
# chown -R $$USER ./forks
|
||||
make git-forks-"config core.fileMode false"
|
||||
make git-forks-$*
|
||||
|
||||
deps-prepare-push:
|
||||
mv deps.path deps.path.disabled
|
||||
|
||||
dep-go-local: ## Switch to using a standard local path, eg: make dep-go-local dep=pointers
|
||||
make dep-go-local-path dep=$(dep) path=$(LIBS_PATH)$(dep)
|
||||
|
||||
dep-go-local-%: ## Switch to using a standard local path, eg: make dep-go-local dep=pointers
|
||||
make dep-go-local dep="$*"
|
||||
|
||||
dep-go-local-path: ## Switch to using a local path, eg: make dep-go-local dep=pointers path=./libs/pointers
|
||||
make dep-local-add dep=$(dep) path=$(path)
|
||||
make dep-local-enable dep=$(dep) path=""
|
||||
# make dep-git-disable dep=$(dep) repo=""
|
||||
# make dep-hex-disable dep=$(dep) version=""
|
||||
|
||||
dep-go-git: ## Switch to using a git repo, eg: make dep-go-git dep="pointers" repo=https://github.com/bonfire-networks/pointers (repo is optional if previously specified)
|
||||
make dep-git-add dep=$(dep) $(repo) 2> /dev/null || true
|
||||
make dep-git-enable dep=$(dep) repo=""
|
||||
make dep-hex-disable dep=$(dep) version=""
|
||||
make 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" (version is optional if previously specified)
|
||||
make dep-hex-add dep=$(dep) version=$(version) 2> /dev/null || true
|
||||
make dep-hex-enable dep=$(dep) version=""
|
||||
make dep-git-disable dep=$(dep) repo=""
|
||||
make dep-local-disable dep=$(dep) path=""
|
||||
|
||||
deps.get: init
|
||||
docker-compose run -e WITH_FORKS=0 web mix deps.get
|
||||
make mix-"deps.get"
|
||||
|
||||
deps.update.all:
|
||||
make deps.update-"--all"
|
||||
|
||||
deps.update-%: init
|
||||
docker-compose run -e WITH_FORKS=0 web mix deps.update $*
|
||||
|
||||
dev: init docker-stop-web ## Run the app with Docker
|
||||
docker-compose --verbose run --name bonfire_web --service-ports web
|
||||
#docker-compose run --name bonfire_web --service-ports web
|
||||
|
||||
dev-bg: init docker-stop-web ## Run the app in dev mode, in the background
|
||||
docker-compose run --detach --name bonfire_web --service-ports web elixir -S mix phx.server
|
||||
|
||||
docker-stop-web:
|
||||
@docker stop bonfire_web 2> /dev/null || true
|
||||
@docker rm bonfire_web 2> /dev/null || true
|
||||
|
||||
git-forks-add: ## Run a git command on each fork
|
||||
find $(LIBS_PATH) -mindepth 1 -maxdepth 1 -type d -exec echo add {} \; -exec git -C '{}' add . \;
|
||||
|
||||
git-forks-%: ## Run a git command on each fork
|
||||
find $(LIBS_PATH) -mindepth 1 -maxdepth 1 -type d -exec echo $* {} \; -exec git -C '{}' $* \;
|
||||
|
||||
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 \;
|
||||
|
||||
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 $(LIBS_PATH) -mindepth 1 -maxdepth 1 -type d -exec echo add {} \; -exec git -C '{}' diff --name-only --diff-filter=U \;
|
||||
|
||||
test: init ## Run tests
|
||||
docker-compose run web mix test $(args)
|
||||
|
||||
test-remote: init ## Run tests (ignoring local forks)
|
||||
docker-compose run -e WITH_FORKS=0 web mix test $(args)
|
||||
|
||||
licenses: init
|
||||
docker-compose run -e WITH_FORKS=0 web mix licenses
|
||||
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"
|
||||
|
||||
cmd-%: init ## Run a specific command in the container, eg: `make cmd-messclt` or `make cmd-"messctl help"` or `make cmd-messctl args="help"`
|
||||
docker-compose run web $* $(args)
|
||||
update.dep~%: ## Update a specify dep (eg. `make update.dep~pointers`)
|
||||
@make --no-print-directory mix.remote~"deps.update $*"
|
||||
|
||||
update.forks: git.forks~pull ## Pull the latest commits from all ./forks
|
||||
|
||||
deps.get: mix.remote~deps.get mix~deps.get ## Fetch locked version of non-forked deps
|
||||
|
||||
#### DEPENDENCY & EXTENSION RELATED COMMANDS ####
|
||||
|
||||
|
||||
assets-prepare:
|
||||
cp lib/*/*/overlay/* rel/overlays/ 2> /dev/null || true
|
||||
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)
|
||||
|
||||
config-prepare: # copy current flavour's config, without using symlinks
|
||||
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) config/deps.hex"
|
||||
|
||||
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"
|
||||
|
||||
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"
|
||||
|
||||
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 contrib.app.up ## 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 ../../../../ alpha
|
||||
|
||||
contrib.forks.publish:
|
||||
@chmod +x git-publish.sh
|
||||
find $(FORKS_PATH) -mindepth 1 -maxdepth 1 -type d -exec ./git-publish.sh {} \;
|
||||
|
||||
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~%: ## 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 '{}' $* \;
|
||||
|
||||
#### TESTING RELATED COMMANDS ####
|
||||
|
||||
test: init ## 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 ## Run only stale tests
|
||||
ifeq ($(WITH_DOCKER), total)
|
||||
docker-compose run web mix test $(only) --stale
|
||||
else
|
||||
mix test $(only) --stale
|
||||
endif
|
||||
|
||||
test.remote: ## Run tests (ignoring changes in local forks)
|
||||
@make --no-print-directory mix.remote~"test $(only)"
|
||||
|
||||
test.watch: init ## 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
|
||||
|
||||
# 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.config.prepare: # copy current flavour's config, without using symlinks
|
||||
cp -rfL $(BONFIRE_FLAVOUR)/config ./data/config
|
||||
|
||||
rel-build-no-cache: init config-prepare assets-prepare ## Build the Docker image
|
||||
rel.build.no-cache: init rel.config.prepare assets.prepare ## Build the Docker image
|
||||
docker build \
|
||||
--no-cache \
|
||||
--build-arg BONFIRE_FLAVOUR=config \
|
||||
|
@ -259,7 +258,7 @@ rel-build-no-cache: init config-prepare assets-prepare ## Build the Docker image
|
|||
-f $(APP_REL_DOCKERFILE) .
|
||||
@echo Build complete: $(APP_DOCKER_REPO):$(APP_VSN)-release-$(APP_BUILD)
|
||||
|
||||
rel-build: init config-prepare assets-prepare ## Build the Docker image using previous cache
|
||||
rel.build: init rel.config.prepare assets.prepare ## Build the Docker image using previous cache
|
||||
docker build \
|
||||
--build-arg BONFIRE_FLAVOUR=config \
|
||||
--build-arg APP_NAME=$(APP_NAME) \
|
||||
|
@ -270,26 +269,95 @@ rel-build: init config-prepare assets-prepare ## Build the Docker image using pr
|
|||
@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: init ## Add latest tag to last build
|
||||
rel.tag.latest: init ## Add latest tag to last build
|
||||
@docker tag $(APP_DOCKER_REPO):$(APP_VSN)-release-$(APP_BUILD) $(APP_DOCKER_REPO):latest
|
||||
|
||||
rel-push: init ## Add latest tag to last build and push to Docker Hub
|
||||
rel.push: init ## Add latest tag to last build and push to Docker Hub
|
||||
@docker push $(APP_DOCKER_REPO):latest
|
||||
|
||||
rel-run: init docker-stop-web ## Run the app in Docker & starts a new `iex` console
|
||||
rel.run: 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 bonfire_web --service-ports --rm backend bin/bonfire start_iex
|
||||
|
||||
rel-run-bg: init docker-stop-web ## Run the app in Docker, and keep running in the background
|
||||
rel.run.bg: 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: ## Run the app in Docker, and keep running in the background
|
||||
rel.stop: init ## Run the app in Docker, and keep running in the background
|
||||
@docker-compose -p $(APP_REL_CONTAINER) -f $(APP_REL_DOCKERCOMPOSE) stop
|
||||
|
||||
rel-shell: docker-stop-web ## Runs a simple shell inside of the container, useful to explore the image
|
||||
rel.shell: init docker.stop.web ## Runs a simple shell inside of the container, useful to explore the image
|
||||
@docker-compose -p $(APP_REL_CONTAINER) -f $(APP_REL_DOCKERCOMPOSE) run --name bonfire_web --service-ports --rm backend /bin/bash
|
||||
|
||||
fire: init db
|
||||
iex -S mix phx.server
|
||||
|
||||
sparks: init db
|
||||
mix test $(only)
|
||||
#### DOCKER-SPECIFIC COMMANDS ####
|
||||
|
||||
services: ## Start background docker services (eg. db and search backends). This is automatically done for you if using Docker.
|
||||
ifeq ($(WITH_DOCKER), no)
|
||||
@echo ....
|
||||
else
|
||||
docker-compose up -d db search
|
||||
endif
|
||||
|
||||
build: init ## Build the docker image
|
||||
ifeq ($(WITH_DOCKER), total)
|
||||
docker-compose build
|
||||
else
|
||||
@echo Skip building container...
|
||||
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 bonfire_web 2> /dev/null || true
|
||||
@docker rm bonfire_web 2> /dev/null || true
|
||||
|
||||
#### MISC COMMANDS ####
|
||||
|
||||
mix~%: init ## Run a specific mix command, eg: `make mix~deps.get` or `make mix~deps.update args=pointers`
|
||||
ifeq ($(WITH_DOCKER), total)
|
||||
docker-compose run web mix $* $(args)
|
||||
else
|
||||
mix $* $(args)
|
||||
endif
|
||||
|
||||
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
|
||||
|
||||
licenses: init
|
||||
@make --no-print-directory mix.remote~licenses
|
||||
|
||||
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"
|
||||
|
||||
git-publish:
|
||||
chmod +x git-publish.sh
|
||||
./git-publish.sh
|
||||
|
||||
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 \;
|
||||
|
||||
pull:
|
||||
git pull
|
134
docs/GRAPHQL.md
Normal file
134
docs/GRAPHQL.md
Normal file
|
@ -0,0 +1,134 @@
|
|||
# Bonfire GraphQL Guide
|
||||
|
||||
## GraphQL Introduction
|
||||
|
||||
Go to http://your-app-url/api/ to start playing with the GraphQL API. The GraphiQL UI should autocomplete types, queries and mutations for you, and you can also explore the schema there.
|
||||
|
||||
Let's start with a simple GraphQL thoeretical query:
|
||||
|
||||
```graphql
|
||||
query {
|
||||
greetings(limit: 10) {
|
||||
greeting
|
||||
to {
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Let's break this apart:
|
||||
|
||||
- `query {}` is how you retrieve information from GraphQL.
|
||||
- `greetings` is a `field` within the query.
|
||||
- `greetings` takes a `limit` argument, a positive integer.
|
||||
- `greetings` has two fields, `greeting` and `to`.
|
||||
- `to` has one `field`, `name`.
|
||||
|
||||
This query is asking for a list of (up to) 10 greetings and the people
|
||||
they are for. Notice that the result of both `greetings` and `to` are
|
||||
map/object structures with their own fields and that if the type has
|
||||
multiple fields, we can select more than one field.
|
||||
|
||||
Here is some possible data we could get returned
|
||||
|
||||
```elixir
|
||||
%{greetings: [
|
||||
%{greeting: "hello", to: %{ name: "dear reader"}}, # english
|
||||
%{greeting: "hallo", to: %{ name: "beste lezer"}}, # dutch
|
||||
]}
|
||||
```
|
||||
|
||||
Where is the magic? Typically an object type will reside in its own
|
||||
table in the database, so this query is actually querying two tables
|
||||
in one go. In fact, given a supporting schema, you can nest queries
|
||||
arbitrarily and the backend will figure out how to run them.
|
||||
|
||||
The fact that you can represent arbitrarily complex queries puts quite
|
||||
a lot of pressure on the backend to make it all efficient. This is
|
||||
still a work in progress at this time.
|
||||
|
||||
## Absinthe Introduction
|
||||
|
||||
Every `field` is filled by a resolver. Let's take our existing query
|
||||
and define a schema for it in Absinthe's query DSL:
|
||||
|
||||
```elixir
|
||||
defmodule MyApp.Schema do
|
||||
# the schema macro language
|
||||
use Absinthe.Schema.Notation
|
||||
# where we will actually resolve the fields
|
||||
alias MyApp.Resolver
|
||||
|
||||
# Our user object is pretty simple, just a name
|
||||
object :user do
|
||||
field :name, non_null(:string)
|
||||
end
|
||||
|
||||
# This one is slightly more complicated, we have that nested `to`
|
||||
object :greeting do
|
||||
# the easy one
|
||||
field :greeting, non_null(:string)
|
||||
# the hard one. `edge` is the term for when we cross an object boundary.
|
||||
field :to, non_null(:user), do: resolve(&Resolver.to_edge/3)
|
||||
end
|
||||
|
||||
# something to put our top level queries in, because they're just fields too!
|
||||
object :queries do
|
||||
field :greetings, non_null(list_of(non_null(:string))) do
|
||||
arg :limit, :integer # optional
|
||||
resolve &Resolver.greetings/2 # we need to manually process this one
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
```
|
||||
|
||||
There are a couple of interesting things about this:
|
||||
|
||||
- Sprinklings of `not_null` to require that values be present (if you
|
||||
don't return them, absinthe will get upset).
|
||||
- Only two fields have explicit resolvers. Anything else will default
|
||||
to a map key lookup (which is more often than not what you want).
|
||||
- `greeting.to_edge` has a `/3` resolver and `queries.greetings` a
|
||||
`/2` resolver.
|
||||
|
||||
To understand the last one (and partially the middle one), we must
|
||||
understand how resolution works and what a parent is. The best way of
|
||||
doing that is probably to look at the resolver code:
|
||||
|
||||
```elixir
|
||||
defmodule MyApp.Resolver do
|
||||
|
||||
# For purposes of this, we will just fake the data out
|
||||
defp greetings_data() do
|
||||
[ %{greeting: "hello", to: %{ name: "dear reader"}}, # english
|
||||
%{greeting: "hallo", to: %{ name: "beste lezer"}}, # dutch
|
||||
]
|
||||
end
|
||||
|
||||
# the /2 resolver takes only arguments (which in this case is just limit)
|
||||
# and an info (which we'll explain later)
|
||||
def greetings(%{limit: limit}, _info) when is_integer(limit) and limit > 0 do
|
||||
{:ok, Enum.take(greetings_data(), limit)} # absinthe expects an ok/error tuple
|
||||
end
|
||||
def greetings(_args, _info), do: {:ok, greetings_data()} # no limit
|
||||
|
||||
# the /3 resolver takes an additional parent argument in first position.
|
||||
# `parent` here will be the `greeting` we are resolving `to` for.
|
||||
def to_edge(parent, args, info), do: Map.get(parent, :to)
|
||||
|
||||
end
|
||||
```
|
||||
|
||||
The keen-eyed amongst you may have noticed I said the default resolver
|
||||
is a map lookup and our `to_edge/3` is a map lookup too, so
|
||||
technically we didn't need to write it. But then you wouldn't have an
|
||||
example of a `/3` resolver! In most of the app, these will be querying
|
||||
from the database, not looking up in a constant.
|
||||
|
||||
So for every field, a resolver function is run. It defaults to a map
|
||||
lookup, but you can override it with `resolve/1`. It may or may not
|
||||
have arguments. And all absinthe resolvers return an ok/error tuple.
|
||||
|
||||
## Patterns
|
206
docs/HACKING.md
Normal file
206
docs/HACKING.md
Normal file
|
@ -0,0 +1,206 @@
|
|||
# Development guide
|
||||
|
||||
_These instructions are for hacking on Bonfire. If you wish to deploy in production, please refer to our [Deployment Guide](./DEPLOY.md)!_
|
||||
|
||||
Hello, potential contributor! :-)
|
||||
|
||||
This is a work in progress guide to getting up and running as a developer. Please ask questions in the issue tracker if something is not clear.
|
||||
|
||||
Happy hacking!
|
||||
|
||||
|
||||
## Getting set up
|
||||
|
||||
There are three main options depending on your needs and preferences.
|
||||
|
||||
You first need to set set some configuration regardless of which option you choose.
|
||||
|
||||
### Configuration
|
||||
|
||||
- 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) in these files:
|
||||
- `config/dev/secrets.env`
|
||||
- `config/dev/public.env`
|
||||
|
||||
|
||||
### Option A - the entry way (fully managed via docker-compose, recommended when you're first exploring)
|
||||
|
||||
- Dependencies:
|
||||
- `make`
|
||||
- Docker
|
||||
- Docker Compose (recent version)
|
||||
|
||||
- Make sure you've edited your .env files (see above) before getting started and proceed to Hello world!
|
||||
|
||||
|
||||
### Option B - the easy way (with docker-managed database & search index, recommended for active development)
|
||||
|
||||
- Dependencies:
|
||||
- `make`
|
||||
- Recent versions of elixir (1.11+) and OTP/erlang (23+)
|
||||
- Docker
|
||||
- Docker Compose (recent version)
|
||||
|
||||
- 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!
|
||||
|
||||
|
||||
### Option C - the bare metal (if you don't use docker)
|
||||
|
||||
- Dependencies:
|
||||
- `make`
|
||||
- Recent versions of elixir (1.11+) and OTP/erlang (23+)
|
||||
- Postgres 12+ (or Postgis if using the bonfire_geolocate extension)
|
||||
- Meili Search (optional)
|
||||
|
||||
- You will need to set the relevant environment variables in the .env files (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.
|
||||
|
||||
- Set an environment variable to indicate your choice: `export WITH_DOCKER=no` and proceed to Hello world!
|
||||
|
||||
|
||||
## Hello world!
|
||||
|
||||
- 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
|
||||
```
|
||||
|
||||
- You should then be able to run the app with:
|
||||
|
||||
```
|
||||
make dev
|
||||
```
|
||||
|
||||
- See the `make` commands bellow for more things you may want to do.
|
||||
|
||||
|
||||
## Onboarding
|
||||
|
||||
By default, the back-end listens on port 4000 (TCP), so you can access it on http://localhost:4000/
|
||||
|
||||
If you haven't set up transactional emails, while in development, you will see a signup confirmation path appear in the iex console.
|
||||
|
||||
Note that the first account to be registered is automatically an instance admin.
|
||||
|
||||
|
||||
## Documentation
|
||||
|
||||
The code is somewhat documented inline. You can generate HTML docs (using `Exdoc`) by running `mix docs`.
|
||||
|
||||
|
||||
## Make 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.
|
||||
|
||||
You can first set the env variable DOCKER to control which mode these commands will assume you're using. Here are your options:
|
||||
- `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
|
||||
|
||||
make help Makefile commands help **(run this to get more up-to-date commands and help information than available in this document)**
|
||||
make env.exports Display the vars from dotenv files that you need to load in your environment
|
||||
|
||||
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
|
||||
|
||||
|
||||
## What happens when I get this error?
|
||||
|
||||
### (Mix) Package fetch failed
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
** (Mix) Package fetch failed and no cached copy available (https://repo.hex.pm/tarballs/distillery-2.0.12.tar)
|
||||
```
|
||||
|
||||
In this case, distillery (as an example of a dependency) made a new release and retired the old release from hex. The new version (`2.0.14`) is quite close to the version we were depending on (`2.0.12`), so we chose to upgrade:
|
||||
|
||||
```shell
|
||||
mix deps.update distillery
|
||||
```
|
||||
|
||||
This respects the version bounds in `mix.exs` (`~> 2.0`), so increment that if required.
|
||||
|
||||
|
||||
### `(DBConnection.ConnectionError) tcp recv: closed`
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
** (DBConnection.ConnectionError) tcp recv: closed (the connection was closed by the pool, possibly due to a timeout or because the pool has been terminated)
|
||||
```
|
||||
|
||||
In this case, the seeds were unable to complete because a query took too long to execute on your machine. You can configure the timeout to be larger in the `dev` environment:
|
||||
|
||||
1. Open `config/dev.exs` in your editor.
|
||||
2. Find the database configuration (search for `Bonfire.Repo`).
|
||||
3. Add `timeout: 60_000` to the list of options:
|
||||
|
||||
```
|
||||
config :bonfire, Bonfire.Repo,
|
||||
timeout: 60_000,
|
||||
[...]
|
||||
```
|
110
docs/MRF.md
Normal file
110
docs/MRF.md
Normal file
|
@ -0,0 +1,110 @@
|
|||
# Message Rewrite Facility
|
||||
|
||||
**WARNING: Due to how this app currently handles its configuration, MRF is only usable if you're building your own docker image.**
|
||||
|
||||
The Message Rewrite Facility (MRF) is a subsystem that is implemented as a series of hooks that allows the administrator to rewrite or discard messages.
|
||||
|
||||
Possible uses include:
|
||||
|
||||
- marking incoming messages with media from a given account or instance as sensitive
|
||||
- rejecting messages from a specific instance
|
||||
- rejecting reports (flags) from a specific instance
|
||||
- removing/unlisting messages from the public timelines
|
||||
- removing media from messages
|
||||
- sending only public messages to a specific instance
|
||||
|
||||
The MRF provides user-configurable policies. The default policy is `NoOpPolicy`, which disables the MRF functionality. Bonfire also includes an easy to use policy called `SimplePolicy` which maps messages matching certain pre-defined criterion to actions built into the policy module.
|
||||
It is possible to use multiple, active MRF policies at the same time.
|
||||
|
||||
## Using `SimplePolicy`
|
||||
|
||||
`SimplePolicy` is capable of handling most common admin tasks.
|
||||
|
||||
To use `SimplePolicy`, you must enable it. Do so by adding the following to your `:instance` config object, so that it looks like this:
|
||||
|
||||
```
|
||||
config :bonfire, :instance,
|
||||
[...]
|
||||
rewrite_policy: ActivityPub.MRF.SimplePolicy
|
||||
```
|
||||
|
||||
Once `SimplePolicy` is enabled, you can configure various groups in the `:mrf_simple` config object. These groups are:
|
||||
|
||||
- `media_removal`: Servers in this group will have media stripped from incoming messages.
|
||||
- `media_nsfw`: Servers in this group will have the #nsfw tag and sensitive setting injected into incoming messages which contain media.
|
||||
- `reject`: Servers in this group will have their messages rejected.
|
||||
- `report_removal`: Servers in this group will have their reports (flags) rejected.
|
||||
|
||||
Servers should be configured as lists.
|
||||
|
||||
### Example
|
||||
|
||||
This example will enable `SimplePolicy`, block media from `illegalporn.biz`, mark media as NSFW from `porn.biz` and `porn.business`, reject messages from `spam.com`and block reports (flags) from `whiny.whiner`:
|
||||
|
||||
```
|
||||
config :bonfire, :instance,
|
||||
rewrite_policy: [ActivityPub.MRF.SimplePolicy]
|
||||
|
||||
config :bonfire, :mrf_simple,
|
||||
media_removal: ["illegalporn.biz"],
|
||||
media_nsfw: ["porn.biz", "porn.business"],
|
||||
reject: ["spam.com"],
|
||||
report_removal: ["whiny.whiner"]
|
||||
|
||||
```
|
||||
|
||||
### Use with Care
|
||||
|
||||
The effects of MRF policies can be very drastic. It is important to use this functionality carefully. Always try to talk to an admin before writing an MRF policy concerning their instance.
|
||||
|
||||
## Writing your own MRF Policy
|
||||
|
||||
As discussed above, the MRF system is a modular system that supports pluggable policies. This means that an admin may write a custom MRF policy in Elixir or any other language that runs on the Erlang VM, by specifying the module name in the `rewrite_policy` config setting.
|
||||
|
||||
For example, here is a sample policy module which rewrites all messages to "new message content":
|
||||
|
||||
```elixir
|
||||
# This is a sample MRF policy which rewrites all Notes to have "new message
|
||||
# content."
|
||||
defmodule Site.RewritePolicy do
|
||||
@behavior ActivityPub.MRF
|
||||
|
||||
# Catch messages which contain Note objects with actual data to filter.
|
||||
# Capture the object as `object`, the message content as `content` and the
|
||||
# message itself as `message`.
|
||||
@impl true
|
||||
def filter(%{"type" => Create", "object" => {"type" => "Note", "content" => content} = object} = message)
|
||||
when is_binary(content) do
|
||||
# Subject / CW is stored as summary instead of `name` like other AS2 objects
|
||||
# because of Mastodon doing it that way.
|
||||
summary = object["summary"]
|
||||
|
||||
# Message edits go here.
|
||||
content = "new message content"
|
||||
|
||||
# Assemble the mutated object.
|
||||
object =
|
||||
object
|
||||
|> Map.put("content", content)
|
||||
|> Map.put("summary", summary)
|
||||
|
||||
# Assemble the mutated message.
|
||||
message = Map.put(message, "object", object)
|
||||
{:ok, message}
|
||||
end
|
||||
|
||||
# Let all other messages through without modifying them.
|
||||
@impl true
|
||||
def filter(message), do: {:ok, message}
|
||||
end
|
||||
```
|
||||
|
||||
If you save this file as `lib/site/mrf/rewrite_policy.ex`, it will be included when you next rebuild Bonfire. You can enable it in the configuration like so:
|
||||
|
||||
```
|
||||
config :bonfire, :instance,
|
||||
rewrite_policy: [
|
||||
ActivityPub.MRF.SimplePolicy,
|
||||
Site.RewritePolicy
|
||||
]
|
||||
```
|
9
docs/index.html
Normal file
9
docs/index.html
Normal file
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Bonfire Documentation</title>
|
||||
<meta http-equiv="refresh" content="0; url=./exdoc/readme.html" />
|
||||
</head>
|
||||
<body></body>
|
||||
</html>
|
|
@ -13,7 +13,7 @@ SEARCH_MEILI_INSTANCE=http://search:7700
|
|||
# require an email address to be invited before being able to sign up
|
||||
INVITE_ONLY=true
|
||||
# a name and tagline for your instance
|
||||
INSTANCE_DESCRIPTION=An instance of Bonfire, a federated app ecosystem for open and cooperative networks
|
||||
INSTANCE_DESCRIPTION="An instance of Bonfire, a federated app ecosystem for open and cooperative networks"
|
||||
# uncomment in order to NOT automatically change the database schema when you upgrade the app
|
||||
# DISABLE_DB_AUTOMIGRATION=true
|
||||
# max file upload size (default is 20 meg)
|
||||
|
|
|
@ -13,7 +13,7 @@ SEARCH_MEILI_INSTANCE=http://search:7700
|
|||
# require an email address to be invited before being able to sign up
|
||||
INVITE_ONLY=true
|
||||
# a name and tagline for your instance
|
||||
INSTANCE_DESCRIPTION=An instance of Bonfire, a federated app ecosystem for open and cooperative networks
|
||||
INSTANCE_DESCRIPTION="An instance of Bonfire, a federated app ecosystem for open and cooperative networks"
|
||||
# uncomment in order to NOT automatically change the database schema when you upgrade the app
|
||||
# DISABLE_DB_AUTOMIGRATION=true
|
||||
# max file upload size (default is 20 meg)
|
||||
|
|
|
@ -13,7 +13,7 @@ SEARCH_MEILI_INSTANCE=http://search:7700
|
|||
# require an email address to be invited before being able to sign up
|
||||
INVITE_ONLY=true
|
||||
# a name and tagline for your instance
|
||||
INSTANCE_DESCRIPTION=An instance of Bonfire, a federated app ecosystem for open and cooperative networks
|
||||
INSTANCE_DESCRIPTION="An instance of Bonfire, a federated app ecosystem for open and cooperative networks"
|
||||
# uncomment in order to NOT automatically change the database schema when you upgrade the app
|
||||
# DISABLE_DB_AUTOMIGRATION=true
|
||||
# max file upload size (default is 20 meg)
|
||||
|
|
1
mix.exs
1
mix.exs
|
@ -82,6 +82,7 @@ defmodule Bonfire.MixProject do
|
|||
{:zest, "~> 0.1"},
|
||||
{:grumble, "~> 0.1.3", only: [:test], override: true},
|
||||
{:bonfire_api_graphql, git: "https://github.com/bonfire-networks/bonfire_api_graphql", branch: "main", only: [:test]},
|
||||
{:mix_test_watch, "~> 1.0", only: :dev, runtime: false},
|
||||
|
||||
# list dependencies & licenses
|
||||
{:licensir, only: :dev, runtime: false,
|
||||
|
|
3
mix.lock
3
mix.lock
|
@ -27,7 +27,7 @@
|
|||
"bonfire_search": {:git, "https://github.com/bonfire-networks/bonfire_search", "8ff913fb0248b591d364e21d81b83171fccf8a2d", [branch: "main"]},
|
||||
"bonfire_social": {:git, "https://github.com/bonfire-networks/bonfire_social", "8a6180b0b205315985036b54430a446f66508bdc", [branch: "main"]},
|
||||
"bonfire_tag": {:git, "https://github.com/bonfire-networks/bonfire_tag", "bd7d97ad2d6e41e196f4e2afb232fe07f24b4fd3", [branch: "main"]},
|
||||
"bonfire_ui_coordination": {:git, "https://github.com/bonfire-networks/bonfire_ui_coordination", "b1714237882293f6fe0f19ac61111bc0871403e5", [branch: "main"]},
|
||||
"bonfire_ui_coordination": {:git, "https://github.com/bonfire-networks/bonfire_ui_coordination", "bb928613c868c505eb6bdb69c66155aa7dd92e6a", [branch: "main"]},
|
||||
"bonfire_ui_reflow": {:git, "https://github.com/bonfire-networks/bonfire_ui_reflow", "6400d1858e1686ac9c2e21471df3876839ec18e0", [branch: "main"]},
|
||||
"bonfire_ui_social": {:git, "https://github.com/bonfire-networks/bonfire_ui_social", "32085859421dcb49c790cc72a0678629ba210d51", [branch: "main"]},
|
||||
"bonfire_ui_valueflows": {:git, "https://github.com/bonfire-networks/bonfire_ui_valueflows", "8a153fd601190f063f131158732d283b7c09eab1", [branch: "main"]},
|
||||
|
@ -88,6 +88,7 @@
|
|||
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
|
||||
"mime": {:hex, :mime, "1.6.0", "dabde576a497cef4bbdd60aceee8160e02a6c89250d6c0b29e56c0dfb00db3d2", [:mix], [], "hexpm", "31a1a8613f8321143dde1dafc36006a17d28d02bdfecb9e95a880fa7aabd19a7"},
|
||||
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
|
||||
"mix_test_watch": {:hex, :mix_test_watch, "1.0.2", "34900184cbbbc6b6ed616ed3a8ea9b791f9fd2088419352a6d3200525637f785", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}], "hexpm", "47ac558d8b06f684773972c6d04fcc15590abdb97aeb7666da19fcbfdc441a07"},
|
||||
"mock": {:hex, :mock, "0.3.7", "75b3bbf1466d7e486ea2052a73c6e062c6256fb429d6797999ab02fa32f29e03", [:mix], [{:meck, "~> 0.9.2", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "4da49a4609e41fd99b7836945c26f373623ea968cfb6282742bcb94440cf7e5c"},
|
||||
"neuron": {:hex, :neuron, "5.0.0", "64c6b14138e4f6e61a55abb0bb95659aa193145ed9baf80b4e760d4c189f6c6f", [:mix], [{:httpoison, "~> 1.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "7597308e22e34f77acaadbae3da63974edc9e4041ef7f7154d45ce80c0e33d00"},
|
||||
"nimble_parsec": {:hex, :nimble_parsec, "1.1.0", "3a6fca1550363552e54c216debb6a9e95bd8d32348938e13de5eda962c0d7f89", [:mix], [], "hexpm", "08eb32d66b706e913ff748f11694b17981c0b04a33ef470e33e11b3d3ac8f54b"},
|
||||
|
|
Loading…
Reference in a new issue