Merge branch 'main' into main

This commit is contained in:
Raphael Megzari 2021-07-02 15:10:28 +09:00 committed by GitHub
commit 21a9bf2e4e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
103 changed files with 3591 additions and 22511 deletions

View file

@ -17,7 +17,7 @@ config/prod
*.env*
Docker*
docker*
Makefile
# Makefile
README*
priv/static
assets/node_modules

View file

@ -1,5 +1,5 @@
[
import_deps: [:ecto, :phoenix, :ecto_sql, :surface],
import_deps: [:phoenix, :ecto_sql, :surface],
inputs: ["*.{ex,exs,sface}", "priv/*/seeds.exs", "{config,lib,test}/**/*.{ex,exs,sface}", "forks/*/{config,lib,test}/**/*.{ex,exs,sface}"],
subdirectories: ["priv/*/migrations"]
surface_inputs: ["{lib,test}/**/*.{ex,exs,sface}", "forks/*/{lib,test}/**/*.{ex,exs,sface}"],
]

View file

@ -3,23 +3,28 @@ on:
push:
branches:
- main
- with-valueflows-api
pull_request:
branches:
- main
- with-valueflows-api
jobs:
build:
test:
name: Build and test
runs-on: ubuntu-latest
container: elixir:alpine
env:
POSTGRES_HOST: postgres
POSTGRES_PASSWORD: postgres
CI: true
services:
postgres:
image: postgres
# image: postgis/postgis:12-3.0-alpine
# image: postgres
image: postgis/postgis:12-3.0-alpine
env:
POSTGRES_DB: bonfire_test
POSTGRES_PASSWORD: postgres
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
@ -32,8 +37,8 @@ jobs:
with:
access_token: ${{ github.token }}
-
name: Install git (needed for checkout) and tar (needed for cache)
run: apk add git tar
name: Install git (needed for checkout), tar (needed for cache), file (needed for bonfire_files)
run: apk add git tar file
-
name: Checkout repo
uses: actions/checkout@v2
@ -72,16 +77,11 @@ jobs:
run: MIX_ENV=test mix
- name: Set up database
run: MIX_ENV=test mix ecto.setup
env:
POSTGRES_HOST: postgres
- name: Run tests
run: mix test
env:
POSTGRES_HOST: postgres
- name: Check that database migrations can rollback
run: MIX_ENV=test mix ecto.rollback --all # && mix ecto.reset
env:
POSTGRES_HOST: postgres
# - name: Maybe tag/release new version
# uses: salsify/action-detect-and-tag-new-version@v2
# with:

View file

@ -3,9 +3,8 @@ on:
push:
branches:
- main
# - with-valueflows-api
jobs:
# release:
# elixir_release:
# runs-on: ubuntu-latest
# container: elixir:alpine
# steps:
@ -19,11 +18,11 @@ jobs:
# - name: Install Elixir dependencies
# run: mix deps.get --only prod
# - name: Install JS dependencies
# run: mix js.deps.get
# run: make js.deps.get
# - name: Prepare release
# run: |
# mix compile
# mix js.release
# mix assets.release
# mix phx.digest
# mix release
# env:
@ -33,14 +32,14 @@ jobs:
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# RELEASE_PATH: _build/prod/rel
# RELEASING: 1
docker_release_build_push:
name: Maybe tag version & release Docker image
# CI: 1
coordination_flavour_docker_release_build_push:
name: Coordination flavour - Maybe tag version & release Docker image
runs-on: ubuntu-latest
env:
FLAVOUR: coordination
BONFIRE_FLAVOUR: flavours/coordination
DOCKER_REPO: bonfire-with-valueflows-api
FLAVOUR_PATH: flavours/coordination
DOCKER_REPO: bonfire
steps:
-
name: Checkout
@ -81,13 +80,82 @@ jobs:
access_token: ${{ github.token }}
-
name: Pre-build prep
run: mkdir forks/ && mkdir -p data/uploads/ && make rel.config.prepare && touch data/config/deps.path
run: mkdir forks/ && mkdir -p data/uploads/ && make rel.config.prepare && touch data/current_flavour/config/deps.path
-
name: Build and push
id: docker_build
uses: docker/build-push-action@v2
env:
BONFIRE_FLAVOUR: config
FLAVOUR: coordination
FLAVOUR_PATH: data/current_flavour
with:
context: .
file: Dockerfile.release
platforms: linux/amd64 #,linux/arm64,linux/arm/v7
push: true
tags: |
bonfirenetworks/${{ env.DOCKER_REPO }}:latest-${{ env.FLAVOUR }}
bonfirenetworks/${{ env.DOCKER_REPO }}:${{steps.version.outputs.current-version}}-${{ env.FLAVOUR }}
-
name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}
reflow_flavour_docker_release_build_push:
name: Reflow flavour - Maybe release Docker image
runs-on: ubuntu-latest
env:
FLAVOUR: reflow
FLAVOUR_PATH: flavours/reflow
DOCKER_REPO: reflow
APP_NAME: reflow
steps:
-
name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 2 # needed for action-detect-and-tag-new-version
-
name: Maybe tag/release new version
id: version
uses: salsify/action-detect-and-tag-new-version@v2
with:
create-tag: false # tag already created in first job
version-command: |
grep -m 1 'version:' mix.exs | cut -d '"' -f2
-
if: steps.version.outputs.current-version == steps.version.outputs.previous-version
name: Cancel workflow if the version has not changed
uses: andymckay/cancel-action@0.2
# -
# name: Get branch names
# id: branch-name
# uses: tj-actions/branch-names@v4
-
name: Set up QEMU
uses: docker/setup-qemu-action@v1
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
-
name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Cancel any already running releases workflows
uses: styfle/cancel-workflow-action@0.9.0
with:
access_token: ${{ github.token }}
-
name: Pre-build prep
run: mkdir forks/ && mkdir -p data/uploads/ && make rel.config.prepare && touch data/current_flavour/config/deps.path
-
name: Build and push
id: docker_build
uses: docker/build-push-action@v2
env:
FLAVOUR: reflow
FLAVOUR_PATH: data/current_flavour
with:
context: .
file: Dockerfile.release
@ -95,7 +163,7 @@ jobs:
push: true
tags: |
bonfirenetworks/${{ env.DOCKER_REPO }}:latest
bonfirenetworks/${{ env.DOCKER_REPO }}:${{steps.version.outputs.tag}}
bonfirenetworks/${{ env.DOCKER_REPO }}:${{steps.version.outputs.current-version}}
-
name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}

8
.gitignore vendored
View file

@ -64,3 +64,11 @@ deps.path*
.direnv/
.bash_history
result
schema.graphql
deploy
.pnpm-debug.log
# we use pnpm, so ignore others
assets/package-lock.json
assets/yarn.lock
priv/localisation/*

View file

@ -32,6 +32,9 @@ RUN cd $FORKS/messctl && cp -r origin/* . && cargo build --release && cargo inst
# install
RUN cp /opt/app/.cargo/bin/* /bin/
# JS package manager
RUN curl -L https://unpkg.com/@pnpm/self-installer | node
EXPOSE 4000/tcp
EXPOSE 4004/tcp

View file

@ -17,13 +17,13 @@ ARG ALPINE_VERSION=3.13
ARG APP_NAME
# The version of the application we are building (required)
ARG APP_VSN
ARG BONFIRE_FLAVOUR
ARG FLAVOUR
ARG FLAVOUR_PATH
# Step 1 - Build our app
FROM elixir:${ELIXIR_VERSION}-alpine as builder
ENV HOME=/opt/app/ TERM=xterm MIX_ENV=prod BONFIRE_FLAVOUR=$BONFIRE_FLAVOUR APP_NAME=$APP_NAME
ENV HOME=/opt/app/ TERM=xterm MIX_ENV=prod APP_NAME=$APP_NAME FLAVOUR=$FLAVOUR FLAVOUR_PATH=./
WORKDIR $HOME
# useful deps
@ -34,9 +34,11 @@ RUN apk add --no-cache make gcc libc-dev
# Cache elixir deps
COPY mix.exs mess.exs mix.lock ./
COPY data/config/deps.hex ./config/
# sometimes mix tries to read the config
RUN mkdir -p ./config && touch ./config/config.exs
# get deps from hex.pm
COPY data/current_flavour/config/deps.hex ./config/
RUN mix do local.hex --force, local.rebar --force
RUN mix do deps.get --only prod
@ -44,13 +46,14 @@ RUN mix do deps.get --only prod
# RUN MIX_ENV=prod mix do deps.compile
# git deps (i.e. Bonfire extensions)
COPY data/config/deps.git ./config
COPY data/current_flavour/config/deps.git ./config/
RUN mix do deps.get --only prod
# we need config before compiling Bonfire extensions
COPY data/config/ ./config
# Comment this line only if you want to include locally-forked deps in the release
RUN rm config/deps.path
COPY data/current_flavour/config/* ./config/
RUN rm ./config/deps.path
# Comment the line above and uncomment the ones below only if you want to include locally-forked deps in the release
# RUN ls -la ./config
# RUN MIX_ENV=prod mix do deps.compile
@ -58,29 +61,41 @@ RUN rm config/deps.path
RUN mix do bonfire.deps.update
# Uncomment these lines only if you want to include locally-forked deps in the release
# COPY data/config/deps.path ./config
# COPY data/current_flavour/config/deps.path ./config
# COPY forks/ ./
# RUN mix do deps.get --only prod
# JS package manager
RUN curl -L https://unpkg.com/@pnpm/self-installer | node
# install JS deps
COPY assets/package* ./assets/
RUN mix js.deps.get
COPY assets/package.json assets/pnpm-lock.yaml ./assets/
COPY Makefile ./
RUN make js.deps.get
# Compile Bonfire extensions
RUN MIX_ENV=prod mix do deps.compile
# COPY lib/ assets/ priv/ rel/ ./ # causes a webpack error
COPY . .
# migrations
COPY data/current_flavour/repo priv/repo
# bonfire-app code & assets
COPY lib lib
COPY assets assets
# RUN ls -la .
# RUN ls -la assets/
# RUN ls -la priv/
# RUN ls -la priv/repo/
# COPY . .
# In case some dep lockfile has a different version
RUN mix do deps.get --only prod
# prepare static assets
RUN mix js.release
RUN MIX_ENV=prod RELEASING=1 mix phx.digest
RUN mix assets.release
RUN MIX_ENV=prod CI=1 mix phx.digest
# build final OTP release
RUN MIX_ENV=prod RELEASING=1 mix release
RUN MIX_ENV=prod CI=1 mix release
# Step 2 - Prepare the server image
# From this line onwards, we're in a new image, which will be the image used in production

148
Makefile
View file

@ -5,7 +5,7 @@ BASH := $(shell which bash)
# what flavour do we want?
FLAVOUR ?= classic
BONFIRE_FLAVOUR ?= flavours/$(FLAVOUR)
FLAVOUR_PATH ?= flavours/$(FLAVOUR)
# do we want to use Docker? set as env var:
# - WITH_DOCKER=total : use docker for everything (default)
@ -18,15 +18,15 @@ WITH_DOCKER ?= total
FORKS_PATH ?= ./forks/
MIX_ENV ?= dev
ORG_NAME ?= bonfirenetworks
APP_NAME ?= bonfire-$(FLAVOUR)
APP_NAME ?= bonfire
UID := $(shell id -u)
GID := $(shell id -g)
APP_REL_CONTAINER="$(ORG_NAME)_$(APP_NAME)_release"
APP_REL_CONTAINER="$(APP_NAME)_release"
APP_REL_DOCKERFILE=Dockerfile.release
APP_REL_DOCKERCOMPOSE=docker-compose.release.yml
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)"
APP_DOCKER_REPO="$(ORG_NAME)/$(APP_NAME)-$(FLAVOUR)"
#### GENERAL SETUP RELATED COMMANDS ####
@ -34,23 +34,23 @@ export UID
export GID
define setup_env
$(eval ENV_DIR := $(BONFIRE_FLAVOUR)/config/$(1))
$(eval ENV_DIR := config/$(1))
@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)"
@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/dev/secrets.env, config/dev/public.env and ./config/ more generally."
@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:
@ln -sfn $(BONFIRE_FLAVOUR)/config ./config
@ln -sfn $(FLAVOUR_PATH)/config ./config
@mkdir -p config/prod
@mkdir -p config/dev
@touch config/deps.path
@ -66,22 +66,25 @@ pre-run:
init: pre-init pre-run
@$(call setup_env,$(MIX_ENV))
@echo "Light that fire... $(APP_NAME) with $(FLAVOUR) flavour in $(MIX_ENV) - $(APP_VSN) - $(APP_BUILD)"
@echo "Light that fire... $(APP_NAME) with $(FLAVOUR) flavour in $(MIX_ENV) - $(APP_VSN) - $(APP_BUILD) - $(FLAVOUR_PATH)"
@make --no-print-directory pre-init
@make --no-print-directory services
help: init ## Makefile commands help
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 }}' $(BONFIRE_FLAVOUR)/config/dev/*.env
@awk 'NF { if( $$1 != "#" ){ print "export " $$0 }}' $(FLAVOUR_PATH)/config/dev/*.env
#### COMMON COMMANDS ####
setup: build mix~setup ## First run - prepare environment and dependencies
setup: build mix~setup js.deps.get ## First run - prepare environment and dependencies
dev: init ## Run the app in development
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 bonfire_web --service-ports web
@ -90,6 +93,8 @@ else
iex -S mix phx.server
endif
dev.test: init test.env 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
@ -109,13 +114,15 @@ db.rollback.all: mix~"ecto.rollback --all" ## Rollback ALL DB migrations (cautio
#### UPDATE COMMANDS ####
update: init update.app build update.forks mix~deps.get mix~ecto.migrate ## Update the app and all dependencies/extensions/forks, and run migrations
update: init update.app build update.forks mix~deps.get mix~ecto.migrate js.deps.get ## Update the dev app and all dependencies/extensions/forks, and run migrations
update.app: ## Update the app and Bonfire extensions in ./deps
update.app: update.repo ## Update the app and Bonfire extensions in ./deps
@make --no-print-directory mix.remote~updates
update.repo:
git add --all .
git diff-index --quiet HEAD || git commit --all --verbose
git pull --rebase
@make --no-print-directory mix.remote~updates
update.deps.bonfire: init mix.remote~bonfire.deps ## Update to the latest Bonfire extensions in ./deps
@ -124,13 +131,25 @@ update.deps.all: ## Update evey single dependency (use with caution)
update.dep~%: ## Update a specify dep (eg. `make update.dep~pointers`)
@make --no-print-directory mix.remote~"deps.update $*"
@chmod +x git-publish.sh
./git-publish.sh $(FORKS_PATH)/$* pull
update.forks: git.forks~pull ## Pull the latest commits from all ./forks
#update.forks: git.forks~pull ## Pull the latest commits from all ./forks
update.forks: ## Pull the latest commits from all ./forks
@chmod +x git-publish.sh
find $(FORKS_PATH) -mindepth 1 -maxdepth 1 -type d -exec ./git-publish.sh {} pull \;
deps.get: mix.remote~deps.get mix~deps.get ## Fetch locked version of non-forked deps
#### DEPENDENCY & EXTENSION RELATED COMMANDS ####
js.deps.get:
# FIXME: make generic to apply to all extensions that bundle JS
(cd forks/bonfire_geolocate/assets && pnpm install) || (cd deps/bonfire_geolocate/assets && pnpm install)
cd ./assets && pnpm install
dep.clean~%:
@make mix~"deps.clean $* --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)
@ -161,7 +180,7 @@ dep.go.hex: ## Switch to using a library from hex.pm, eg: make dep.go.hex dep="p
@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"
@make --no-print-directory messctl args="$* $(dep) $(version)
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"
@ -203,35 +222,49 @@ contrib.forks.publish:
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
@find $(FORKS_PATH) -mindepth 1 -maxdepth 1 -type d -exec echo {} \; -exec git -C '{}' status -s \;
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 '{}' $* \;
@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`
test.env:
$(eval export MIX_ENV=test)
$(eval export)
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 ## Run only stale tests
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: ## Run tests (ignoring changes in local forks)
test.remote: test.env ## 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
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
@ -244,14 +277,17 @@ endif
#### RELEASE RELATED COMMANDS (Docker-specific for now) ####
rel.env:
$(eval export MIX_ENV=prod)
$(eval export)
rel.config.prepare: # copy current flavour's config, without using symlinks
cp -rfL $(BONFIRE_FLAVOUR)/config ./data/config
rel.config.prepare: rel.env # copy current flavour's config, without using symlinks
@cp -rfL $(FLAVOUR_PATH) ./data/current_flavour
rel.build.no-cache: init rel.config.prepare assets.prepare ## Build the Docker image
rel.build.no-cache: rel.env init rel.config.prepare assets.prepare ## Build the Docker image
docker build \
--no-cache \
--build-arg BONFIRE_FLAVOUR=config \
--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) \
@ -259,44 +295,67 @@ rel.build.no-cache: init rel.config.prepare assets.prepare ## Build the Docker i
-f $(APP_REL_DOCKERFILE) .
@echo Build complete: $(APP_DOCKER_REPO):$(APP_VSN)-release-$(APP_BUILD)
rel.build: init rel.config.prepare assets.prepare ## Build the Docker image using previous cache
rel.build: rel.env init rel.config.prepare assets.prepare ## Build the Docker image using previous cache
@echo "Building $(APP_NAME) with flavour $(FLAVOUR)"
docker build \
--build-arg BONFIRE_FLAVOUR=config \
--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"
@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: rel.env ## 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: rel.env ## 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
@docker-compose -p $(APP_REL_CONTAINER) -f $(APP_REL_DOCKERCOMPOSE) run --name bonfire_web --service-ports --rm backend bin/bonfire start_iex
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 bonfire_web --service-ports --rm web 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: 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: init ## Stop the running release
rel.stop: rel.env ## Stop the running release
@docker-compose -p $(APP_REL_CONTAINER) -f $(APP_REL_DOCKERCOMPOSE) stop
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
rel.update: rel.env update.repo
@docker-compose -p $(APP_REL_CONTAINER) -f $(APP_REL_DOCKERCOMPOSE) pull
@echo Remember to run migrations on your DB...
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 bonfire_web --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). This is automatically done for you if using Docker.
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), total)
@ -338,14 +397,21 @@ endif
licenses: init
@make --no-print-directory mix.remote~licenses
localise.extract:
@make --no-print-directory mix~"bonfire.localise.extract --merge"
assets.prepare:
cp lib/*/*/overlay/* rel/overlays/ 2> /dev/null || true
@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
git.publish:
chmod +x git-publish.sh
./git-publish.sh
@ -361,4 +427,4 @@ 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
git pull

View file

@ -2,7 +2,7 @@
[Bonfire](https://bonfirenetworks.org/) - a federated social network for individuals and communities to design, operate and control their own digital lives.
### Flavours
This repo includes configurations to run different [flavours of Bonfire](https://bonfirenetworks.org/apps.html), currently that is:
This repo includes configurations to run different [flavours of Bonfire](https://bonfirenetworks.org/apps), currently that is:
* [Classic](flavours/classic)
* [Coordination](flavours/coordination)
* [Reflow](flavours/reflow)

View file

@ -1,5 +0,0 @@
{
"presets": [
"@babel/preset-env"
]
}

View file

@ -211,11 +211,11 @@ iframe {
.comment_lined:before {
position: absolute;
content: "";
top: 46px;
bottom: 0px;
top: 36px;
bottom: 10px;
width: 2px;
left: 26px;
@apply bg-blueGray-200;
left: 19px;
@apply bg-blueGray-500;
}
.shadow-tick {

View file

@ -1,17 +0,0 @@
// We may need to import the CSS so that webpack will load it.
// The MiniCssExtractPlugin is used to separate it out into its own CSS file.
import "../css/app.scss" // no longer used in favour of Tailwind
// webpack automatically bundles all modules in your
// entry points. Those entry points can be configured
// in "webpack.config.js".
//
// Import deps with the dep name or local files with a relative path, for example:
//
// import {Socket} from "phoenix"
// import socket from "./socket"
import "phoenix_html"
// lightweight JS toolkit
import 'alpinejs'

6
assets/js/common.js Normal file
View file

@ -0,0 +1,6 @@
// import "../css/app.scss" // no longer used in favour of Tailwind
import "phoenix_html"
// lightweight JS toolkit
import 'alpinejs'

View file

@ -1,5 +1,5 @@
// JS shared with non_live pages
import "./both"
import "./common"
// for JS features & extensions to hook into LiveView
let Hooks = {};
@ -32,10 +32,10 @@ liveSocket.connect()
// >> liveSocket.enableDebug()
// >> liveSocket.enableLatencySim(1000) // enabled for duration of browser session
// >> liveSocket.disableLatencySim()
window.liveSocket = liveSocket
// Extensions... # TODO: make this more modular/configurable
import { ExtensionHooks } from "../../deps/bonfire_geolocate/assets/js/extension"
Object.assign(liveSocket.hooks, ExtensionHooks);

View file

@ -1 +1 @@
import "./both"
import "./common"

21229
assets/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,42 +1,38 @@
{
"repository": {},
"description": " ",
"license": "MIT",
"version": "0.0.0",
"scripts": {
"deploy": "webpack --mode production",
"watch": "webpack --mode development --watch"
"preinstall": "npx -y only-allow pnpm",
"watch.js": "esbuild ./js/live.js ./js/non_live.js --target=es2015 --bundle --sourcemap --outdir=../priv/static/js --watch",
"build.js": "esbuild ./js/live.js ./js/non_live.js --target=es2015 --bundle --sourcemap --outdir=../priv/static/js",
"watch.postcss": "TAILWIND_MODE=watch NODE_ENV=development postcss ./css/app.scss -o ../priv/static/css/app.css -w",
"build.postcss": "TAILWIND_MODE=build NODE_ENV=production postcss ./css/app.scss -o ../priv/static/css/app.css",
"watch.tw": "TAILWIND_MODE=build NODE_ENV=production npx tailwindcss@canary -i ./css/app.scss -o ../priv/static/css/app.css --files ../{lib,forks,deps}/**/*{.leex,.sface} --jit -w",
"build.tw": "TAILWIND_MODE=build NODE_ENV=production npx tailwindcss@canary -i ./css/app.scss -o ../priv/static/css/app.css --files ../{lib,forks,deps}/**/*{.leex,.sface} --jit",
"watch.assets": "cpx 'static/**/*' ../priv/static --watch",
"build": "pnpm build.postcss && pnpm build.js"
},
"dependencies": {
"@github/details-dialog-element": "^3.1.2",
"@github/details-menu-element": "^1.0.9",
"@tailwindcss/forms": "^0.1.4",
"@tailwindcss/line-clamp": "^0.2.0",
"@tailwindcss/typography": "^0.4.0",
"alpinejs": "^2.8.1",
"leaflet": "^1.7.1",
"@tailwindcss/forms": "^0.3.3",
"@tailwindcss/line-clamp": "^0.2.1",
"@tailwindcss/typography": "^0.4.1",
"alpinejs": "^2.8.2",
"nprogress": "^0.2.0",
"phoenix": "file:../deps/phoenix",
"phoenix_html": "file:../deps/phoenix_html",
"phoenix_live_view": "file:../deps/phoenix_live_view",
"tailwindcss": "^2.1"
"phoenix": "link:../deps/phoenix",
"phoenix_html": "link:../deps/phoenix_html",
"phoenix_live_view": "link:../deps/phoenix_live_view",
"tailwindcss": "~2.1.4"
},
"devDependencies": {
"@babel/core": "^7.12.10",
"@babel/preset-env": "^7.12.11",
"autoprefixer": "^10.1.0",
"babel-loader": "^8.2.2",
"copy-webpack-plugin": "^5.1.1",
"css-loader": "^3.4.2",
"file-loader": "^6.2.0",
"hard-source-webpack-plugin": "^0.13.1",
"mini-css-extract-plugin": "^0.9.0",
"optimize-css-assets-webpack-plugin": "^5.0.1",
"postcss": "^8.2.1",
"@tailwindcss/jit": "^0.1.18",
"autoprefixer": "^10.2.6",
"cpx": "^1.5.0",
"esbuild": "^0.12.8",
"only-allow": "^1.0.0",
"pnpm": "^6.7.6",
"postcss": "^8.3.2",
"postcss-cli": "^8.3.1",
"postcss-loader": "^4.1.0",
"tailwindcss-debug-screens": "^2.0.0",
"terser-webpack-plugin": "^2.3.2",
"webpack": "4.41.5",
"webpack-cli": "^3.3.2"
"tailwindcss-debug-screens": "^2.0.0"
}
}
}

2201
assets/pnpm-lock.yaml Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,8 +1,6 @@
module.exports = {
plugins: [
// ...
require('tailwindcss'),
require('autoprefixer'),
// ...
]
}
plugins: {
'@tailwindcss/jit': {},
autoprefixer: {},
},
};

1
assets/static/data/uploads Symbolic link
View file

@ -0,0 +1 @@
../../../data/uploads

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View file

@ -2,6 +2,7 @@ const colors = require('tailwindcss/colors')
module.exports = {
mode: 'jit',
future: {
removeDeprecatedGapUtilities: true,
purgeLayersByDefault: true,
@ -9,20 +10,7 @@ module.exports = {
purge: {
enabled: true,
content: [
'../forks/**/lib/**/*.leex',
'../forks/**/lib/**/**/*.leex',
'../forks/**/lib/**/**/**/*.leex',
'../deps/bonfire_**/lib/**/*.leex',
'../deps/bonfire_**/lib/**/**/*.leex',
'../deps/bonfire_**/lib/**/**/**/*.leex',
'../lib/web/**/*.leex',
'../forks/**/lib/**/*.sface',
'../forks/**/lib/**/**/*.sface',
'../forks/**/lib/**/**/**/*.sface',
'../deps/bonfire_**/lib/**/*.sface',
'../deps/bonfire_**/lib/**/**/*.sface',
'../deps/bonfire_**/lib/**/**/**/*.sface',
'../lib/web/**/*.sface',
'../{lib,forks,deps}/**/*{.leex,.sface,_live.ex}'
]
},
darkMode: 'class',
@ -50,15 +38,16 @@ module.exports = {
spacing: {
'72': '18rem',
'84': '21rem',
'90': '22rem',
'96': '26rem',
},
typography: (theme) => ({
light: {
css: [
{
color: theme('colors.gray.400'),
color: theme('colors.gray.100'),
'[class~="lead"]': {
color: theme('colors.gray.300'),
color: theme('colors.gray.100'),
},
a: {
color: theme('colors.white'),
@ -119,6 +108,7 @@ module.exports = {
},
variants: {
extend: {
divideColor: ['dark'],
ringWidth:['hover'],
divideColor: ['dark'],
ringColor: ['group-hover', 'hover'],

View file

@ -1,79 +0,0 @@
const path = require('path');
const glob = require('glob');
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = (env, options) => {
const devMode = options.mode !== 'production';
return {
optimization: {
minimizer: [
new TerserPlugin({ cache: true, parallel: true, sourceMap: devMode }),
new OptimizeCSSAssetsPlugin({})
]
},
entry: {
'non_live': glob.sync('./vendor/**/*.js').concat(['./js/non_live.js']),
'live': glob.sync('./vendor/**/*.js').concat(['./js/live.js'])
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, '../priv/static/js'),
publicPath: '/js/'
},
devtool: devMode ? 'eval-cheap-module-source-map' : undefined,
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader',
],
},
{
// fonts
test: /\.(woff(2)?|ttf|otf|eot)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: "file-loader",
options: {
name: "[name].[ext]",
outputPath: "../fonts",
},
},
]
},
{
test: /\.[s]?css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
// 'sass-loader',
'postcss-loader',
],
},
{
// images assets
test: /\.(gif|png|svg|jpg|jpeg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
use: ['file-loader'],
},
]
},
plugins: [
new MiniCssExtractPlugin({ filename: '../css/app.css' }),
new CopyWebpackPlugin([{ from: 'static/', to: '../' }])
]
.concat(devMode ? [new HardSourceWebpackPlugin()] : [])
}
};

View file

@ -1,11 +1,11 @@
version: "3.5"
services:
backend:
web:
# You can build your own image from the source running:
# $ make rel-build
# $ make rel-tag-latest
image: "bonfirenetworks/bonfire-main:latest"
image: "bonfirenetworks/bonfire:latest-${FLAVOUR}"
container_name: "bonfire_web"
restart: always
ports:
@ -13,13 +13,16 @@ services:
env_file:
- config/prod/public.env
- config/prod/secrets.env
environment:
- POSTGRES_HOST=db
- SEARCH_MEILI_INSTANCE=http://search:7700
depends_on:
- db
volumes:
- type: bind
source: ./data/uploads
target: /opt/app/data/uploads
frontend:
proxy:
image: "caddy:alpine"
restart: always
ports:

View file

@ -15,6 +15,7 @@ services:
- config/dev/secrets.env
environment:
- POSTGRES_HOST=db
- SEARCH_MEILI_INSTANCE=http://search:7700
depends_on:
- db
# - condition: service_healthy
@ -34,15 +35,15 @@ services:
# user: $UID:$GID
db:
image: postgis/postgis:12-3.1-alpine
volumes:
- ./data/postgres/dev:/var/lib/postgresql/data:z
- /etc/passwd:/etc/passwd:ro
# volumes:
# - ./data/postgres/dev:/var/lib/postgresql/data:z
# - /etc/passwd:/etc/passwd:ro
ports:
- "5432:5432"
env_file:
- config/dev/public.env
- config/dev/secrets.env
user: $UID:$GID
# user: $UID:$GID
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
@ -52,8 +53,8 @@ services:
image: getmeili/meilisearch:latest
ports:
- "7700:7700"
volumes:
- "./data/search/dev:/data.ms"
# volumes:
# - "./data/search/dev:/data.ms"
# - /etc/passwd:/etc/passwd:ro
env_file:
- config/dev/public.env

View file

@ -16,18 +16,55 @@ If you are running in a restricted environment such as Amazon RDS, you will need
CREATE EXTENSION IF NOT EXISTS citext;
```
## Step 1 - Configure the backend
## Step 1 - Download and configure the app
The app needs some environment variables to be configured in order to work.
1. Clone this repository and change into the directory:
In the `flavours/${FLAVOUR}/config/` directory of the codebase, there are following default config files:
```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.
For example if you want to run the `coordination` flavour (you may want to use direnv or something similar to persist this):
`export FLAVOUR=coordination MIX_ENV=prod`
3. Once you've picked a flavour, run this command to initialise some default config (.env files which won't be checked into git):
`make pre-config`
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:
- SECRET_KEY_BASE
- SIGNING_SALT
- ENCRYPTION_SALT
- POSTGRES_PASSWORD
- MEILI_MASTER_KEY
You can use `make secrets` to generate some secrets keys to use.
And in public.env:
- HOSTNAME
- PUBLIC_PORT
### 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.
In the `${FLAVOUR_PATH}/config/` (depending on which flavour you choose to run) directory of the codebase, there are following default 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}/config/prod/public.env` and `flavours/${FLAVOUR}/config/prod/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 (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).
`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.
@ -40,11 +77,11 @@ You should NOT have to modify the files above. Instead, overload any settings fr
### Option A - Install using Docker containers (recommended)
The easiest way to launch the docker image is using the make 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. You may want to add a webserver / reverse proxy yourself.
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
1. 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:
A-1. 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:
```sh
$ docker version
@ -58,50 +95,47 @@ GNU Make 4.2.1
...
```
2. Clone the `release` branch of repository and change into the directory:
A-2. Edit the `image` entry in `docker-compose.release.yml` to reflect the image on Docker Hub which corresponds to your chosen flavour. (If your flavour does not have a prebuilt image on Docker Hub you can build one yourself, see the section on Building a Docker image below, or set up a CI workflow.)
```sh
$ git clone --branch release https://github.com/bonfire-networks/bonfire-app.git bonfire
$ cd bonfire
A-3. Start the docker containers with docker-compose:
```
make rel.run
```
3. 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.
The backend should now be running at [http://localhost:4000/](http://localhost:4000/).
For example if you want to run the `coordination` flavour:
A-4. If that worked, start the app as a daemon next time:
`export FLAVOUR=coordination` and edit the `image` entry in `docker-compose.yml` to reflect the corresponding image on Docker Hub.
4. Once you've picked a flavour, run this command to initialise some default config (.env files which won't be checked into git):
`make pre-config`
5. Edit the config (especially the secrets) for the current flavour in these files:
- `config/dev/secrets.env`
- `config/dev/public.env`
6. Start the docker containers with docker-compose:
```sh
$ make rel.run
```
make rel.run.bg
```
7. The backend should now be running at [http://localhost:4000/](http://localhost:4000/).
#### Docker-related handy commands
8. If that worked, start the app as a daemon next time:
- `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
```sh
$ make rel.run.bg
```
Once in the shell, you can run `bin/bonfire` with the following commands:
Usage: `bonfire COMMAND [ARGS]`
#### Docker commands
The known commands are:
- `start` Starts the system
- `start_iex` Starts the system with IEx attached
- `daemon` Starts the system as a daemon
- `daemon_iex` Starts the system as a daemon with IEx attached
- `eval "EXPR"` Executes the given expression on a new, non-booted system
- `rpc "EXPR"` Executes the given expression remotely on the running system
- `remote` Connects to the running system via a IEx remote shell
- `restart` Restarts the running system via a remote command
- `stop` Stops the running system via a remote command
- `pid` Prints the operating system PID of the running system via a remote command
- `version` Prints the release name and version to be booted
- `docker-compose pull` to update to the latest release of Bonfire and other services (Postgres & Meili)
- `docker-compose run --rm web bin/bonfire` returns all the possible commands
- `docker-compose run --rm web /bin/sh` runs a simple shell inside of the container, useful to explore the image
- `docker-compose run --rm web bin/bonfire start_iex` starts a new `iex` console
- `docker-compose run web bin/bonfire remote` runs an `iex` console when the service is already running.
There are some useful database-related release tasks under `Bonfire.Repo.ReleaseTasks.` that can be run in an `iex` console:
There are some useful database-related release tasks under `Bonfire.Repo.ReleaseTasks.` 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):
- `migrate` runs all up migrations
- `rollback(step)` roll back to step X
@ -115,12 +149,11 @@ For example:
The Dockerfile uses the [multistage build](https://docs.docker.com/develop/develop-images/multistage-build/) feature to make the image as small as possible. It is a very common release using OTP releases. It generates the release which is later copied into the final image.
There is a `Makefile` with relevant commands:
There is a `Makefile` with relevant commands (make sure you set the `MIX_ENV=prod` env first):
- `make rel.build` which builds the docker image in `bonfire/bonfire:latest` and `bonfire/bonfire:$VERSION-$BUILD`
- `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.run` which can be used to run the "latest" tagged image instead of using `docker-compose`
- `make rel.run.bg` which runs it as a background service
- `make rel.push` add latest tag to last build and push to Docker Hub
---
@ -134,19 +167,11 @@ There is a `Makefile` with relevant commands:
#### B-1. Building the release
- Clone the `main` branch of this repo.
- Set your environment: `export MIX_ENV=prod && export FLAVOUR=classic`
- You will need to load the required environment variables for the release to run properly. See`flavours/$(FLAVOUR)/config/runtime.exs`](config/runtime.exs) and `flavours/$(FLAVOUR)/config/prod/*.env` for all env variables which you can set.
- Make sure you have erlang and elixir installed (check `Dockerfile` for what version we're currently using)
- From here on out, you may want to consider what your `MIX_ENV` is set to. For production, ensure that you either export `MIX_ENV=prod` or use it for each command. Continuing, we are assuming `MIX_ENV=prod`.
- Run `mix deps.get --only prod` to install elixir dependencies.
- Prepare assets with `mix js.deps.get`, `mix js.release` and `mix phx.digest`
- Prepare assets with `make js.deps.get`, `make 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.
@ -161,11 +186,6 @@ There is a `Makefile` with relevant commands:
* To run the instance as a daemon, use `bin/bonfire start daemon`.
#### B-3. Adding HTTPS
The common and convenient way for adding HTTPS is by using Nginx or Caddyserver as a reverse proxy.
Caddyserver and other servers can handle generating and setting up HTTPS certificates automatically, but if you need TLS/SSL certificates for nginx, you can look get some for free with [letsencrypt](https://letsencrypt.org/). The simplest way to obtain and install a certificate is to use [Certbot.](https://certbot.eff.org). Depending on your specific setup, certbot may be able to get a certificate and configure your web server automatically.
---
@ -245,3 +265,11 @@ TODO: add the caddy config
By default, the backend listens on port 4000 (TCP), so you can access it on http://localhost:4000/ (if you are on the same machine). In case of an error it will restart automatically.
Once you've signed up, you will automatically be an instance admin if you were the first to register.
---
#### Step 4 - Adding HTTPS
The common and convenient way for adding HTTPS is by using a reverse proxy like Nginx or Caddyserver (the latter of which is bundled as part of the docker-compose setup).
Caddyserver and other servers can handle generating and setting up HTTPS certificates automatically, but if you need TLS/SSL certificates for nginx, you can look get some for free with [letsencrypt](https://letsencrypt.org/). The simplest way to obtain and install a certificate is to use [Certbot.](https://certbot.eff.org). Depending on your specific setup, certbot may be able to get a certificate and configure your web server automatically.

View file

@ -1,4 +1,9 @@
import Config
schema = Bonfire.GraphQL.Schema
config :bonfire_api_graphql,
graphql_schema_module: Bonfire.GraphQL.Schema
graphql_schema_module: schema
config :absinthe,
schema: schema

View file

@ -8,14 +8,14 @@ config :bonfire,
read: "0EAD1NGSVTTER1YFVNDAMENTA1",
see: "0BSERV1NG11ST1NGSEX1STENCE",
create: "4REATE0RP0STBRANDNEW0BJECT",
edit: "CHANG1NGVA1VES0FPR0PERT1ES",
delete: "MAKESTVFFG0AWAYPERMANENT1Y",
follow: "T0SVBSCR1BET0THE0VTPVT0F1T",
edit: "4HANG1NGVA1VES0FPR0PERT1ES",
delete: "4AKESTVFFG0AWAYPERMANENT1Y",
follow: "20SVBSCR1BET0THE0VTPVT0F1T",
like: "11KES1ND1CATEAM11DAPPR0VA1",
boost: "B00ST0R0RANN0VCEANACT1V1TY",
flag: "F1AGSPAM0RVNACCEPTAB1E1TEM",
mention: "REFERENC1NGTH1NGSE1SEWHERE",
tag: "CATEG0R1S1NGNGR0VP1NGSTVFF",
boost: "300ST0R0RANN0VCEANACT1V1TY",
flag: "71AGSPAM0RVNACCEPTAB1E1TEM",
mention: "0EFERENC1NGTH1NGSE1SEWHERE",
tag: "4ATEG0R1S1NGNGR0VP1NGSTVFF",
},
default_circles: %{
guest: "0AND0MSTRANGERS0FF1NTERNET",

View file

@ -11,18 +11,12 @@ config :bonfire_data_identity, Bonfire.Data.Identity.Credential,
#### Sentinel Data Services
# Search these apps for Pointable schemas to index
config :pointers,
search_path: [
# Search these apps/extensions for Pointable ecto schema definitions to index
pointable_schema_extensions = [
:bonfire_data_access_control,
:bonfire_data_activity_pub,
:bonfire_data_identity,
:bonfire_data_social,
:cpub_activities,
:cpub_comments,
:cpub_communities,
:cpub_threads,
:bonfire,
:bonfire_quantify,
:bonfire_geolocate,
@ -30,18 +24,41 @@ config :pointers,
:bonfire_tag,
:bonfire_classify,
:bonfire_data_shared_users,
:bonfire_files
]
config :pointers, :search_path, pointable_schema_extensions
# Search these apps for Verbs to index
# Search these apps/extensions for context or queries modules to index (i.e. they contain modules with a queries_module/0 or context_modules/0 function)
context_and_queries_extensions = pointable_schema_extensions ++ [
:bonfire_common,
:bonfire_me,
:bonfire_social,
:bonfire_valueflows
]
config :bonfire, :query_modules_search_path, context_and_queries_extensions
config :bonfire, :context_modules_search_path, context_and_queries_extensions
# Search these apps/extensions for Verbs to index (i.e. they contain modules with a declare_verbs/0 function)
config :bonfire_data_access_control,
search_path: [
:bonfire_me,
# :bonfire_me,
:bonfire_boundaries,
:bonfire_social,
:bonfire,
# :bonfire_social,
# :bonfire,
]
#### Alias modules for readability
alias Pointers.{Pointer, Table}
alias Bonfire.Data.AccessControl.{
Access, Acl, Controlled, InstanceAdmin, Grant, Interact, Verb
}
alias Bonfire.Data.ActivityPub.{Actor, Peer, Peered}
alias Bonfire.Data.Identity.{
Account, Accounted, Caretaker, Character, Credential, Email, Self, User, Named
}
alias Bonfire.Data.Social.{
Activity, Article, Block, Bookmark, Circle, Created, Encircle, Feed, FeedPublish, Inbox, Message, Follow, FollowCount, Boost, BoostCount, Like, LikeCount, Flag, FlagCount, Mention, Post, PostContent, Profile, Replied
}
#### Flexto Stitching
@ -56,7 +73,6 @@ config :bonfire_data_access_control,
# first up, pointers could have all the mixins we're using. TODO
alias Pointers.{Pointer, Table}
config :pointers, Pointer,
has_one: [controlled: {Controlled, foreign_key: :id}],
@ -87,17 +103,6 @@ config :pointers, Table, []
# now let's weave everything else together for convenience
alias Bonfire.Data.AccessControl.{
Access, Acl, Controlled, InstanceAdmin, Grant, Interact, Verb
}
alias Bonfire.Data.ActivityPub.{Actor, Peer, Peered}
alias Bonfire.Data.Identity.{
Account, Accounted, Caretaker, Character, Credential, Email, Self, User, Named
}
alias Bonfire.Data.Social.{
Activity, Article, Block, Bookmark, Circle, Created, Encircle, Feed, FeedPublish, Inbox, Message, Follow, FollowCount, Boost, BoostCount, Like, LikeCount, Flag, FlagCount, Mention, Post, PostContent, Profile, Replied
}
# bonfire_data_access_control
config :bonfire_data_access_control, Access,
@ -121,6 +126,8 @@ config :bonfire_data_access_control, Verb, []
# bonfire_data_activity_pub
config :bonfire_data_activity_pub, Actor,
belongs_to: [character: {Character, foreign_key: :id, define_field: false}],
has_one: [peered: {Peered, references: :id, foreign_key: :id}],
belongs_to: [user: {User, foreign_key: :id, define_field: false}]
config :bonfire_data_activity_pub, Peer, []
@ -141,6 +148,7 @@ config :bonfire_data_identity, Accounted,
config :bonfire_data_identity, Caretaker, []
config :bonfire_data_identity, Character,
has_one: [peered: {Peered, references: :id, foreign_key: :id}],
has_one: [actor: {Actor, foreign_key: :id}],
has_one: [profile: {Profile, foreign_key: :id}],
has_one: [user: {User, foreign_key: :id}],
@ -168,7 +176,7 @@ config :bonfire_data_identity, User,
has_one: [instance_admin: {InstanceAdmin, foreign_key: :id}],
has_many: [likes: {Like, foreign_key: :liker_id, references: :id}],
has_one: [self: {Self, foreign_key: :id}],
has_one: [peered: {Peered, foreign_key: :id}],
has_one: [peered: {Peered, references: :id, foreign_key: :id}],
has_many: [encircles: {Encircle, foreign_key: :subject_id}],
has_one: [shared_user: {Bonfire.Data.SharedUser, foreign_key: :id}],
many_to_many: [caretaker_accounts: {Account, join_through: "bonfire_data_shared_user_accounts", join_keys: [shared_user_id: :id, account_id: :id]}]
@ -181,8 +189,9 @@ config :bonfire_data_social, Activity,
belongs_to: [subject_user: {User, foreign_key: :subject_id, define_field: false}],
belongs_to: [subject_character: {Character, foreign_key: :subject_id, define_field: false}],
belongs_to: [subject_profile: {Profile, foreign_key: :subject_id, define_field: false}],
belongs_to: [object_peered: {Peered, foreign_key: :object_id, define_field: false}],
belongs_to: [object_post: {Post, foreign_key: :object_id, define_field: false}],
belongs_to: [object_post_content: {PostContent, foreign_key: :object_id, define_field: false}],
# belongs_to: [object_post_content: {PostContent, foreign_key: :object_id, define_field: false}],
belongs_to: [object_message: {Message, foreign_key: :object_id, define_field: false}],
has_one: [boost_count: {BoostCount, foreign_key: :id, references: :object_id}],
has_one: [like_count: {LikeCount, foreign_key: :id, references: :object_id}],
@ -237,15 +246,18 @@ config :bonfire_data_social, Follow,
config :bonfire_data_social, FollowCount, []
config :bonfire_data_social, Block, []
config :bonfire_data_social, Like, []
config :bonfire_data_social, LikeCount, []
config :bonfire_data_social, Like,
has_one: [activity: {Activity, foreign_key: :object_id, references: :liked_id}] # requires an ON clause
config :bonfire_data_social, LikeCount, []
config :bonfire_data_social, Bookmark, []
config :bonfire_data_social, Message,
has_one: [post_content: {PostContent, foreign_key: :id}],
has_one: [created: {Created, foreign_key: :id}],
has_one: [peered: {Peered, references: :id, foreign_key: :id}],
has_many: [activities: {Activity, foreign_key: :object_id, references: :id}],
has_one: [activity: {Activity, foreign_key: :object_id, references: :id}], # needs on clause
has_one: [activity: {Activity, foreign_key: :object_id, references: :id}], # requires an ON clause
has_one: [like_count: {LikeCount, foreign_key: :id}],
has_many: [likes: {Like, foreign_key: :liked_id, references: :id}],
has_one: [my_like: {Like, foreign_key: :liked_id, references: :id}],
@ -260,11 +272,12 @@ config :bonfire_data_social, Named, []
config :bonfire_data_social, Post,
has_one: [post_content: {PostContent, foreign_key: :id}],
has_one: [created: {Created, foreign_key: :id}],
has_one: [peered: {Peered, references: :id, foreign_key: :id}],
# has_one: [creator_user: {[through: [:created, :creator_user]]}],
# has_one: [creator_character: {[through: [:created, :creator_character]]}],
# has_one: [creator_profile: {[through: [:created, :creator_profile]]}],
has_many: [activities: {Activity, foreign_key: :object_id, references: :id}],
has_one: [activity: {Activity, foreign_key: :object_id, references: :id}], # needs on clause
has_one: [activity: {Activity, foreign_key: :object_id, references: :id}], # requires an ON clause
has_one: [like_count: {LikeCount, foreign_key: :id}],
has_many: [likes: {Like, foreign_key: :liked_id, references: :id}],
has_one: [my_like: {Like, foreign_key: :liked_id, references: :id}],
@ -302,6 +315,7 @@ config :bonfire_data_social, Replied,
has_one: [controlled: {Controlled, foreign_key: :id, references: :id}]
config :bonfire_data_social, Created,
has_one: [peered: {Peered, references: :id, foreign_key: :id}],
belongs_to: [creator_user: {User, foreign_key: :creator_id, define_field: false}],
belongs_to: [creator_character: {Character, foreign_key: :creator_id, define_field: false}],
belongs_to: [creator_profile: {Profile, foreign_key: :creator_id, define_field: false}]
@ -316,6 +330,7 @@ config :bonfire_data_social, Profile,
config :bonfire_tag, Bonfire.Tag,
# for objects that are follow-able and can federate activities
has_one: [character: {Bonfire.Data.Identity.Character, references: :id, foreign_key: :id}],
has_one: [peered: {Peered, references: :id, foreign_key: :id}],
# has_one: [actor: {Bonfire.Data.ActivityPub.Actor, references: :id, foreign_key: :id}],
has_one: [follow_count: {Bonfire.Data.Social.FollowCount, references: :id, foreign_key: :id}],
# for likeable objects
@ -357,9 +372,6 @@ config :bonfire_geolocate, Bonfire.Geolocate.Geolocation,
# all data types included in federation
config :bonfire, :all_types, [User, Post]
# Model - Context module mappings
config :bonfire_data_social, :context_modules,
follow: Bonfire.Social.Follows
config :bonfire_files, Bonfire.Files.Media,
field: [

View file

@ -1,134 +1,21 @@
import Config
alias Bonfire.Federate.ActivityPub.Adapter
alias Bonfire.Data.AccessControl.{
Access, Acl, Controlled, InstanceAdmin, Grant, Interact, Verb
}
alias Bonfire.Data.ActivityPub.{Actor, Peer, Peered}
alias Bonfire.Data.Identity.{
Account, Accounted, Caretaker, Character, Credential, Email, Self, User
}
alias Bonfire.Data.Social.{
Activity, Article, Block, Bookmark, Circle, Created, Encircle, Feed, FeedPublish,
Follow, FollowCount, Like, LikeCount, Mention, Named, Post, PostContent, Profile, Replied
}
alias Bonfire.Me.{Users, Characters}
actor_types = ["Person", "Group", "Application", "Service", "Organization"]
alias Bonfire.Social.Follows
types_agents = [
User,
# Organisation
]
types_characters =
types_agents ++
[
# Community,
# Collection,
Bonfire.Geolocate.Geolocation,
Bonfire.Classify.Category
]
types_inventory = [
Post,
# Resources.Resource,
Bonfire.Quantify.Unit,
Bonfire.Classify.Category,
ValueFlows.Planning.Intent,
ValueFlows.Proposal,
ValueFlows.Observation.EconomicEvent,
ValueFlows.Observation.EconomicResource,
ValueFlows.Observation.Process,
ValueFlows.Knowledge.ProcessSpecification,
ValueFlows.Knowledge.ResourceSpecification
]
types_actions = [
Like,
Block,
Flag,
Follow,
]
types_others = [
# Instance,
# Uploads.Upload, # FIXME
Bonfire.Quantify.Measure,
Bonfire.Tag,
Activity,
Feed,
Peer,
]
types_all_contexts = types_characters ++ types_inventory
types_all = types_all_contexts ++ types_actions ++ types_others
# configure which modules will receive which ActivityPub activities/objects
actor_modules = %{
"Person" => Users.ActivityPub,
"Group" => Communities,
"MN:Collection" => Collections,
"Organization" => Organisations,
"Application" => Characters,
"Service" => Characters,
fallback: Characters
}
activity_modules = %{
"Follow" => Follows,
"Like" => Likes,
"Flag" => Flags,
"Block" => Blocks,
"Delete" => Contexts.Deletion,
fallback: Activities
}
inventory_modules = %{
"Note" => Posts,
"Article" => Posts,
"Question" => Posts,
"Answer" => Posts,
# "Document" => Resources,
# "Page" => Resources,
# "Video" => Resources,
fallback: Posts
}
object_modules =
Map.merge(inventory_modules, %{
"Follow" => Follows,
"Like" => Likes,
"Flag" => Flags,
"Block" => Blocks
})
actor_types = Map.keys(actor_modules)
activity_types = Map.keys(activity_modules) ++ ["Create", "Update", "Accept", "Announce", "Undo"]
inventory_types = Map.keys(inventory_modules)
object_types = Map.keys(object_modules)
all_types = Enum.dedup(actor_types ++ activity_types ++ inventory_types ++ object_types)
config :bonfire, :all_types, all_types
config :bonfire,
federation_search_path: [
:bonfire_common,
:bonfire_me,
:bonfire_social,
:bonfire_valueflows
],
log_federation: true # enable/disable logging of federation logic
config :bonfire, Adapter,
actor_modules: actor_modules,
actor_types: actor_types,
activity_modules: activity_modules,
activity_types: activity_types,
object_modules: object_modules,
inventory_types: inventory_types,
object_types: object_types,
all_types: all_types
actor_types: actor_types
config :bonfire, Instance,
# config :bonfire, Bonfire.Instance,
# hostname: hostname,
# description: desc,
# what to show or exclude in Instance Timeline
default_outbox_query_contexts: List.delete(types_all_contexts, Like),
types_characters: types_characters,
types_inventory: types_inventory,
types_actions: types_actions,
types_all: types_all
# description: desc

View file

@ -1,6 +1,10 @@
import Config
config :bonfire_mailer,
from_address: "noreply@bonfire.local",
check_mx: true,
check_format: true
config :bonfire, Bonfire.Mailer,
# what service you want to use to send emails, from these: https://github.com/thoughtbot/bamboo#available-adapters
# we recommend leaving LocalAdapter (which is just a fallback which won't actually send emails) and setting the actual adapter in runtime.exs
adapter: Bamboo.LocalAdapter

View file

@ -5,9 +5,9 @@ config :bonfire_me,
config :bonfire_me, Bonfire.Me.Identity.Mails,
confirm_email: [subject: "Confirm your email - Bonfire"],
reset_password: [subject: "Reset your password - Bonfire"]
forgot_password: [subject: "Reset your password - Bonfire"]
#### Pointer class configuration
config :bonfire_me, Bonfire.Me.Users.Follows,
config :bonfire_me, Bonfire.Me.Follows,
followable_types: [Bonfire.Data.Identity.User]

View file

@ -2,6 +2,12 @@ import Config
config :bonfire, :ui,
theme: [
instance_name: "Bonfire",
instance_logo: "https://bonfirenetworks.org/img/bonfire.png",
instance_image: "https://bonfirenetworks.org/img/logo.png",
instance_description: "This is a bonfire demo instance for testing purpose"
],
sidebar_components: [
{Bonfire.UI.Social.SidebarNavigationLive, []},
],
@ -16,8 +22,8 @@ config :bonfire, :ui,
private: Bonfire.UI.Social.PrivateLive,
posts: Bonfire.UI.Social.ProfilePostsLive,
boosts: Bonfire.UI.Social.ProfileBoostsLive,
followers: Bonfire.UI.Social.ProfileFollowersLive,
followed: Bonfire.UI.Social.ProfileFollowersLive,
followers: Bonfire.UI.Social.ProfileFollowsLive,
followed: Bonfire.UI.Social.ProfileFollowsLive,
],
navigation: [
timeline: "timeline",

View file

@ -1,67 +1,19 @@
import Config
flavour = System.get_env("BONFIRE_FLAVOUR", "flavours/classic")
# You will almost certainly want to change at least some of these
# include all used Bonfire extensions
for config <- "bonfire_*.exs" |> Path.expand(__DIR__) |> Path.wildcard() do
# IO.inspect(include_config: config)
import_config config
end
import_config "activity_pub.exs"
# import_config "bonfire_boundaries.exs"
# import_config "bonfire_mailer.exs"
# import_config "bonfire_federate_activitypub.exs"
# import_config "bonfire_files.exs"
# import_config "bonfire_me.exs"
# import_config "bonfire_social.exs"
# import_config "bonfire_tag.exs"
# import_config "bonfire_classify.exs"
# # import_config "bonfire_publisher_thesis.exs"
# import_config "bonfire_fail.exs"
# import_config "bonfire_quantify.exs"
# import_config "bonfire_geolocate.exs"
# # import_config "bonfire_valueflows.exs"
# import_config "bonfire_api_graphql.exs"
# import_config "bonfire_search.exs"
# # include common modules
# import_config "bonfire_common.exs"
# # include DB schemas
# import_config "bonfire_data.exs"
# # include hooks (for extensions to hook into each other)
# import_config "bonfire_hooks.exs"
# # include UI settings
# import_config "bonfire_ui.exs"
default_flavour = "classic"
flavour = System.get_env("FLAVOUR", default_flavour)
flavour_path = System.get_env("FLAVOUR_PATH", "flavours/"<>flavour)
#### Basic configuration
config :bonfire, Bonfire.Repo, priv: flavour <> "/repo"
# You probably won't want to touch these. You might override some in
# other config files.
config :bonfire, :github_token, System.get_env("GITHUB_TOKEN")
signing_salt = System.get_env("SIGNING_SALT", "CqAoopA2")
encryption_salt = System.get_env("ENCRYPTION_SALT", "g7K25as98msad0qlSxhNDwnnzTqklK10")
secret_key_base = System.get_env("SECRET_KEY_BASE", "g7K250qlSxhNDt5qnV6f4HFnyoD7fGUuZ8tbBF69aJCOvUIF8P0U7wnnzTqklK10")
config :bonfire, :signing_salt, signing_salt
config :bonfire, :encryption_salt, encryption_salt
config :bonfire,
otp_app: :bonfire,
env: config_env(),
flavour: flavour,
flavour_path: flavour_path,
app_name: System.get_env("APP_NAME", "Bonfire"),
repo_module: Bonfire.Repo,
web_module: Bonfire.Web,
@ -72,21 +24,26 @@ config :bonfire,
user_schema: Bonfire.Data.Identity.User,
org_schema: Bonfire.Data.Identity.User,
home_page: Bonfire.Web.HomeLive,
ap_base_path: System.get_env("AP_BASE_PATH", "/pub")
localisation_path: "priv/localisation",
ap_base_path: System.get_env("AP_BASE_PATH", "/pub"),
signing_salt: "this-will-be-overriden-by-a-secure-string-in-runtime.exs",
encryption_salt: "this-will-be-overriden-by-a-secure-string-in-runtime.exs"
config :bonfire, Bonfire.Web.Endpoint,
url: [host: "localhost"],
secret_key_base: secret_key_base,
http: [
port: String.to_integer(System.get_env("SERVER_PORT", "4000")), # this gets overriden in runtime.exs
transport_options: [socket_opts: [:inet6]]
],
render_errors: [view: Bonfire.Web.ErrorView, accepts: ~w(html json), layout: false],
pubsub_server: Bonfire.PubSub,
live_view: [signing_salt: signing_salt]
pubsub_server: Bonfire.PubSub
config :phoenix, :json_library, Jason
config :bonfire, Bonfire.Repo, types: Bonfire.PostgresTypes
config :bonfire,
ecto_repos: [Bonfire.Repo]
config :bonfire, :ecto_repos, [Bonfire.Repo]
config :bonfire, Bonfire.Repo,
types: Bonfire.PostgresTypes,
priv: flavour_path <> "/repo"
# ecto query filtering
# config :query_elf, :id_types, [:id, :binary_id, Pointers.ULID]
@ -95,7 +52,6 @@ config :logger, :console,
format: "$time $metadata[$level] $message\n",
metadata: [:request_id]
config :bonfire, Oban,
repo: Bonfire.Repo,
plugins: [Oban.Plugins.Pruner],
@ -110,4 +66,16 @@ config :mime, :types, %{
"application/activity+json" => ["activity+json"]
}
# include config for all used Bonfire extensions
for config <- "bonfire_*.exs" |> Path.expand(__DIR__) |> Path.wildcard() do
# IO.inspect(include_config: config)
import_config config
end
import_config "activity_pub.exs"
# finally, append/override config based on env, which will override any config set above (including from imported files)
import_config "#{config_env()}.exs"

View file

@ -1,11 +1,11 @@
# web
phoenix_live_view = "~> 0.14"
phoenix_html = "~> 2.11"
phoenix_live_dashboard = "~> 0.2.0"
phoenix_live_dashboard = "~> 0.4"
plug_cowboy = "~> 2.0"
phoenix = "~> 1.5.3"
phoenix_ecto = "~> 4.1"
gettext = "~> 0.11"
gettext = "~> 0.18"
jason = "~> 1.0"
# poison = "~> 4.0"
# db

View file

@ -1,55 +1,10 @@
import Config
config :bonfire, Bonfire.Mailer,
adapter: Bamboo.LocalAdapter
config :bonfire, Bonfire.Repo,
username: System.get_env("POSTGRES_USER", "postgres"),
password: System.get_env("POSTGRES_PASSWORD", "postgres"),
database: System.get_env("POSTGRES_DB", "bonfire_dev"),
hostname: System.get_env("POSTGRES_HOST", "localhost"),
# show_sensitive_data_on_connection_error: true,
pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10")
config :bonfire, Bonfire.Web.Endpoint,
http: [port: 4000],
debug_errors: true,
code_reloader: true,
check_origin: false,
watchers: [
node: [
"node_modules/webpack/bin/webpack.js",
"--mode",
"development",
"--watch-stdin",
cd: Path.expand("assets", File.cwd!())
]
]
# ## SSL Support
#
# In order to use HTTPS in development, a self-signed
# certificate can be generated by running the following
# Mix task:
#
# mix phx.gen.cert
#
# Note that this task requires Erlang/OTP 20 or later.
# Run `mix help phx.gen.cert` for more information.
#
# The `http:` config above can be replaced with:
#
# https: [
# port: 4001,
# cipher_suite: :strong,
# keyfile: "priv/cert/selfsigned_key.pem",
# certfile: "priv/cert/selfsigned.pem"
# ],
#
# If desired, both `http:` and `https:` keys can be
# configured to run both http and https servers on
# different ports.
path_dep_dirs =
Mess.deps([path: "deps.path"], [])
|> Enum.map(&(Keyword.fetch!(elem(&1, 1), :path) <> "/lib"))
@ -62,7 +17,27 @@ path_dep_patterns = path_dep_patterns ++ path_dep_dirs |> Enum.map(&(String.slic
# Watch static and templates for browser reloading.
config :bonfire, Bonfire.Web.Endpoint,
server: true,
debug_errors: true,
check_origin: false,
code_reloader: true,
watchers: [
# node: [
# "node_modules/webpack/bin/webpack.js",
# "--mode",
# "development",
# "--watch-stdin",
# cd: Path.expand("assets", File.cwd!())
# ]
pnpm: [
"watch.js",
cd: Path.expand("assets", File.cwd!())
],
pnpm: [
"watch.postcss",
cd: Path.expand("assets", File.cwd!())
]
],
live_reload: [
patterns: [
# ~r"^priv/static/.*(js|css|png|jpeg|jpg|gif|svg)$",

View file

@ -1,59 +1,18 @@
import Config
config :bonfire, Bonfire.Mailer,
# set what service you want to use to send emails, from these: https://github.com/thoughtbot/bamboo#available-adapters
adapter: Bamboo.LocalAdapter
# For production, don't forget to configure the url host
# to something meaningful, Phoenix uses this information
# when generating URLs.
#
# Note we also include the path to a cache manifest
# We include the path to a cache manifest
# containing the digested version of static files. This
# manifest is generated by the `mix phx.digest` task,
# which you should run after static files are built and
# before starting your production server.
config :bonfire, Bonfire.Web.Endpoint,
url: [host: "localhost", port: 4000],
cache_static_manifest: "priv/static/cache_manifest.json"
# Do not print debug messages in production
config :logger, level: :info
# ## SSL Support
#
# To get SSL working, you will need to add the `https` key
# to the previous section and set your `:url` port to 443:
#
# config :bonfire, Bonfire.Web.Endpoint,
# ...
# url: [host: "example.com", port: 443],
# https: [
# port: 443,
# cipher_suite: :strong,
# keyfile: System.get_env("SOME_APP_SSL_KEY_PATH"),
# certfile: System.get_env("SOME_APP_SSL_CERT_PATH"),
# transport_options: [socket_opts: [:inet6]]
# ]
#
# The `cipher_suite` is set to `:strong` to support only the
# latest and more secure SSL ciphers. This means old browsers
# and clients may not be supported. You can set it to
# `:compatible` for wider support.
#
# `:keyfile` and `:certfile` expect an absolute path to the key
# and cert in disk or a relative path inside priv, for example
# "priv/ssl/server.key". For all supported SSL configuration
# options, see https://hexdocs.pm/plug/Plug.SSL.html#configure/1
#
# We also recommend setting `force_ssl` in your endpoint, ensuring
# no data is ever sent via http, always redirecting to https:
#
# config :bonfire, Bonfire.Web.Endpoint,
# force_ssl: [hsts: true]
#
# Check `Plug.SSL` for all available options in `force_ssl`.
config :bonfire, Bonfire.Web.Endpoint, server: true
# Finally import the config/prod.secret.exs which loads secrets
# and configuration from environment variables.
# import_config "prod.secret.exs"
config :bonfire, Bonfire.Repo,
priv: "priv/repo" # in releases migrations are not in a flavour-specific directory

View file

@ -4,74 +4,192 @@
# remember to add this file to your .gitignore.
import Config
host = System.get_env("HOSTNAME", "localhost")
server_port = String.to_integer(System.get_env("SERVER_PORT", "4000"))
public_port = String.to_integer(System.get_env("PUBLIC_PORT", "4000"))
System.get_env("CI") || System.get_env("DATABASE_URL") || System.get_env("POSTGRES_PASSWORD") ||
raise """
Environment variables for database are missing.
For example: DATABASE_URL=ecto://USER:PASS@HOST/DATABASE
You can also set POSTGRES_PASSWORD (required),
and POSTGRES_USER (default: postgres) and POSTGRES_HOST (default: localhost)
"""
if System.get_env("DATABASE_URL") do
config :bonfire, Bonfire.Repo,
url: System.get_env("DATABASE_URL")
else
config :bonfire, Bonfire.Repo,
# ssl: true,
username: System.get_env("POSTGRES_USER", "postgres"),
password: System.get_env("POSTGRES_PASSWORD", "postgres"),
hostname: System.get_env("POSTGRES_HOST", "localhost")
end
secret_key_base =
System.get_env("CI") || System.get_env("SECRET_KEY_BASE") ||
raise """
environment variable SECRET_KEY_BASE is missing.
You can generate one by calling: mix phx.gen.secret
"""
signing_salt = System.get_env("CI") || System.get_env("SIGNING_SALT") ||
raise """
environment variable SIGNING_SALT is missing.
"""
encryption_salt = System.get_env("CI") || System.get_env("ENCRYPTION_SALT") ||
raise """
environment variable ENCRYPTION_SALT is missing.
"""
config :bonfire,
host: host,
app_name: System.get_env("APP_NAME", "Bonfire"),
ap_base_path: System.get_env("AP_BASE_PATH", "/pub"),
github_token: System.get_env("GITHUB_TOKEN"),
encryption_salt: encryption_salt,
signing_salt: signing_salt,
invite_only: System.get_env("INVITE_ONLY", "true") # enable signups?
config :bonfire, Bonfire.Web.Endpoint,
url: [
host: host,
port: public_port
],
http: [
port: server_port
],
secret_key_base: secret_key_base,
live_view: [signing_salt: signing_salt]
# start test-only config
if config_env() == :test do
config :bonfire,
invite_only: false
end
# start prod-only config
if config_env() == :prod do
host = System.get_env("HOSTNAME", "localhost")
port = String.to_integer(System.get_env("PORT", "4000"))
config :bonfire, Bonfire.Repo,
# ssl: true,
database: System.get_env("POSTGRES_DB", "bonfire"),
pool_size: String.to_integer(System.get_env("POOL_SIZE", "10")),
log: String.to_atom(System.get_env("DB_QUERIES_LOG_LEVEL", "debug"))
System.get_env("RELEASING") || System.get_env("DATABASE_URL") || (System.get_env("POSTGRES_DB") && System.get_env("POSTGRES_PASSWORD")) ||
raise """
Environment variables for database are missing.
For example: DATABASE_URL=ecto://USER:PASS@HOST/DATABASE
You can also set POSTGRES_DB and POSTGRES_PASSWORD (required),
and POSTGRES_USER (default: postgres) and POSTGRES_HOST (default: localhost)
"""
end # prod only config
if System.get_env("DATABASE_URL") do
config :bonfire, Bonfire.Repo,
url: System.get_env("DATABASE_URL"),
pool_size: String.to_integer(System.get_env("POOL_SIZE", "10"))
else
config :bonfire, Bonfire.Repo,
# ssl: true,
username: System.get_env("POSTGRES_USER", "postgres"),
password: System.get_env("POSTGRES_PASSWORD", "postgres"),
database: System.get_env("POSTGRES_DB", "bonfire"),
hostname: System.get_env("POSTGRES_HOST", "localhost"),
pool_size: String.to_integer(System.get_env("POOL_SIZE", "10"))
# start prod and dev only config
if config_env() != :test do
config :bonfire, Bonfire.Repo,
slow_query_ms: String.to_integer(System.get_env("SLOW_QUERY_MS", "100"))
# transactional emails
mail_blackhole = fn var ->
IO.puts(
"WARNING: The environment variable #{var} was not set or was set incorrectly, mail will NOT be sent."
)
config :bonfire, Bonfire.Mailer, adapter: Bamboo.LocalAdapter
end
secret_key_base =
System.get_env("RELEASING") || System.get_env("SECRET_KEY_BASE") ||
raise """
environment variable SECRET_KEY_BASE is missing.
You can generate one by calling: mix phx.gen.secret
"""
mail_mailgun = fn ->
# API URI depends on whether you're registered with Mailgun in EU, US, etc (defaults to EU)
base_uri = System.get_env("MAIL_BASE_URI", "https://api.eu.mailgun.net/v3")
signing_salt = System.get_env("RELEASING") || System.get_env("SIGNING_SALT") ||
raise """
environment variable SIGNING_SALT is missing.
"""
case System.get_env("MAIL_KEY") do
nil ->
mail_blackhole.("MAIL_KEY")
encryption_salt = System.get_env("RELEASING") || System.get_env("ENCRYPTION_SALT") ||
raise """
environment variable ENCRYPTION_SALT is missing.
"""
key ->
case System.get_env("MAIL_DOMAIN") do
nil ->
mail_blackhole.("MAIL_DOMAIN")
config :bonfire, :signing_salt, signing_salt
config :bonfire, :encryption_salt, encryption_salt
domain ->
case System.get_env("MAIL_FROM") do
nil ->
mail_blackhole.("MAIL_FROM")
config :bonfire, Bonfire.Web.Endpoint,
url: [
host: host,
port: port
],
http: [
port: port
],
secret_key_base: secret_key_base,
live_view: [signing_salt: signing_salt]
from ->
IO.puts("NOTE: Transactional emails will be sent through Mailgun.")
# ## Using releases (Elixir v1.9+)
#
# If you are doing OTP releases, you need to instruct Phoenix
# to start each relevant endpoint:
#
config :bonfire, Bonfire.Mailer,
adapter: Bamboo.MailgunAdapter,
api_key: key,
base_uri: base_uri,
domain: domain,
reply_to: from
end
end
end
end
config :bonfire, Bonfire.Web.Endpoint, server: true
mail_smtp = fn ->
case System.get_env("MAIL_SERVER") do
nil ->
mail_blackhole.("MAIL_SERVER")
#
# Then you can assemble a release by calling `mix release`.
# See `mix help release` for more information.
server ->
case System.get_env("MAIL_DOMAIN") do
nil ->
mail_blackhole.("MAIL_DOMAIN")
end # end prod-only config
domain ->
case System.get_env("MAIL_USER") do
nil ->
mail_blackhole.("MAIL_USER")
user ->
case System.get_env("MAIL_PASSWORD") do
nil ->
mail_blackhole.("MAIL_PASSWORD")
password ->
case System.get_env("MAIL_FROM") do
nil ->
mail_blackhole.("MAIL_FROM")
from ->
IO.puts("NOTE: Transactional emails will be sent through SMTP.")
config :bonfire, Bonfire.Mailer,
adapter: Bamboo.SMTPAdapter,
server: server,
hostname: domain,
port: String.to_integer(System.get_env("MAIL_PORT", "587")),
username: user,
password: password,
tls: :always,
allowed_tls_versions: [:"tlsv1.2"],
ssl: false,
retries: 1,
auth: :always,
reply_to: from
end
end
end
end
end
end
case System.get_env("MAIL_BACKEND") do
"mailgun" -> mail_mailgun.()
"smtp" -> mail_smtp.()
_ -> mail_blackhole.("MAIL_BACKEND")
end
end
# copy-paste Bonfire extension configs that need to read env at runtime
config :bonfire_search,
disable_indexing: System.get_env("SEARCH_INDEXING_DISABLED", "false"),
instance: System.get_env("SEARCH_MEILI_INSTANCE", "http://localhost:7700"), # protocol, hostname and port
api_key: System.get_env("MEILI_MASTER_KEY", "make-sure-to-change-me") # secret key

View file

@ -2,7 +2,7 @@
# make sure you change everything to your own secrets!
# and do not check this into git or any public host
# for sessions/cookies
# for sessions/cookies, you can generate strings for these by running: make secrets
SECRET_KEY_BASE="you-should-put-a-secure-string-here"
SIGNING_SALT="you-should-put-a-different-secure-string-here"
ENCRYPTION_SALT="you-should-put-yet-another-secure-string-here"
@ -13,8 +13,9 @@ POSTGRES_DB=bonfire_db
POSTGRES_PASSWORD=put_a_secure_db_pw_here
# signup to mailgun.com and edit with your domain and API key
MAIL_DOMAIN=mailg.mydomain.net
MAIL_DOMAIN=mailg.example.com
MAIL_KEY=123
MAIL_FROM=bonfire@example.com
# password for the search index
MEILI_MASTER_KEY=key-to-protect-search-indexing-here

View file

@ -1,15 +1,15 @@
FLAVOUR=classic
BONFIRE_FLAVOUR=flavours/classic
# COPY this file to /config/{dev|prod}/public.env and change any values as required
# server domain name:
HOSTNAME=localhost
# server port:
PORT=4000
# full backend URL - server protocol + domain name
# include the port if it isn't the default for protocol like 80 or 443
BASE_URL=http://localhost
SERVER_PORT=4000
# port your visitors will access (typically 80 or 443, will be different than SERVER_PORT only if using a reverse proxy)
PUBLIC_PORT=4000
# what service to use for sending out emails (eg. smtp, mailgun, none) NOTE: you should also set the corresponding keys in secrets.env
MAIL_BACKEND=none
# hostname and port of meili search index
SEARCH_MEILI_INSTANCE=http://search:7700
SEARCH_MEILI_INSTANCE=http://localhost:7700
# require an email address to be invited before being able to sign up
INVITE_ONLY=true
# a name and tagline for your instance
@ -20,10 +20,9 @@ INSTANCE_DESCRIPTION="An instance of Bonfire, a federated app ecosystem for open
UPLOAD_LIMIT=20000000
# ====================================
# You should not have to edit any of the following ones:
APP_NAME=Bonfire
POSTGRES_HOST=localhost
LANG=en_US.UTF-8
REPLACE_OS_VARS=true
LIVEVIEW_ENABLED=true
CI=false
ACME_AGREE=true

View file

@ -6,13 +6,16 @@ import_config "activity_pub_test.exs"
config :bonfire, Bonfire.Mailer, adapter: Bamboo.TestAdapter
config :bonfire_search, disable_indexing: true
config :bonfire_search,
disabled: true,
disable_indexing: true
## Other general test config
config :logger, level: :warn
# config :logger, level: :notice
# Configure your database
#
# The MIX_TEST_PARTITION environment variable can be used
@ -21,11 +24,9 @@ config :logger, level: :warn
config :bonfire, Bonfire.Repo,
pool: Ecto.Adapters.SQL.Sandbox,
pool_size: 60,
username: System.get_env("POSTGRES_USER", "postgres"),
password: System.get_env("POSTGRES_PASSWORD", "postgres"),
database: "bonfire_test#{System.get_env("MIX_TEST_PARTITION")}",
hostname: System.get_env("POSTGRES_HOST") || "localhost"
# show_sensitive_data_on_connection_error: true,
database: "bonfire_test#{System.get_env("MIX_TEST_PARTITION")}",
slow_query_ms: 500
# We don't run a server during test. If one is required,
# you can enable the server option below.
@ -39,3 +40,6 @@ config :bonfire, Oban,
queues: false
config :pbkdf2_elixir, :rounds, 1
config :mix_test_interactive,
clear: true

View file

@ -0,0 +1 @@
../../../coordination/repo/migrations/20201208094940_import_geolocation.exs

View file

@ -0,0 +1,13 @@
defmodule Bonfire.Social.Repo.Migrations.PeeredURI do
use Ecto.Migration
import Pointers.Migration
def up do
alter table("bonfire_data_activity_pub_peered") do
Ecto.Migration.add_if_not_exists :canonical_uri, :text, null: true
end
end
def down, do: nil
end

View file

@ -2,7 +2,14 @@ import Config
config :bonfire, :ui,
theme: [
instance_name: "Bonfire",
instance_logo: "https://bonfirenetworks.org/img/bonfire.png",
instance_image: "https://bonfirenetworks.org/img/brand2.png",
instance_description: "This is a bonfire demo instance for testing purpose"
],
sidebar_components: [
{Bonfire.UI.Social.SidebarNavigationLive, []},
{Bonfire.UI.Coordination.SidebarNavigationLive, []},
# {Bonfire.UI.ValueFlows.ProcessesListLive, [title: "Processes", process_url: "/process/"]},
{Bonfire.UI.ValueFlows.ProcessesListLive, [title: "Task Lists", process_url: "/list/"]}
@ -18,8 +25,8 @@ config :bonfire, :ui,
private: Bonfire.UI.Social.PrivateLive,
posts: Bonfire.UI.Social.ProfilePostsLive,
boosts: Bonfire.UI.Social.ProfileBoostsLive,
followers: Bonfire.UI.Social.ProfileFollowersLive,
followed: Bonfire.UI.Social.ProfileFollowersLive,
followers: Bonfire.UI.Social.ProfileFollowsLive,
followed: Bonfire.UI.Social.ProfileFollowsLive,
# inventory: Bonfire.UI.Reflow.ProfileInventoryLive,
],
navigation: [

View file

@ -1,9 +1,10 @@
# web
phoenix_live_view = "~> 0.14"
phoenix_html = "~> 2.11"
phoenix_live_dashboard = "~> 0.2.0"
phoenix_live_dashboard = "~> 0.4"
plug_cowboy = "~> 2.0"
phoenix = "~> 1.5.3"
surface = "~> 0.5.0"
phoenix_ecto = "~> 4.1"
gettext = "~> 0.11"
jason = "~> 1.0"
@ -29,4 +30,4 @@ ok = "~> 2.3.0"
# bonfire_data_activity_pub = "~> 0.1"
# bonfire_data_identity = "~> 0.1"
# bonfire_data_social = "~> 0.1"
# ecto_psql_extras = "~> 0.2"

View file

@ -2,7 +2,7 @@
# make sure you change everything to your own secrets!
# and do not check this into git or any public host
# for sessions/cookies
# for sessions/cookies, you can generate strings for these by running: make secrets
SECRET_KEY_BASE="you-should-put-a-secure-string-here"
SIGNING_SALT="you-should-put-a-different-secure-string-here"
ENCRYPTION_SALT="you-should-put-yet-another-secure-string-here"
@ -13,8 +13,9 @@ POSTGRES_DB=bonfire_db
POSTGRES_PASSWORD=put_a_secure_db_pw_here
# signup to mailgun.com and edit with your domain and API key
MAIL_DOMAIN=mailg.mydomain.net
MAIL_DOMAIN=mailg.example.com
MAIL_KEY=123
MAIL_FROM=bonfire@example.com
# password for the search index
MEILI_MASTER_KEY=key-to-protect-search-indexing-here

View file

@ -1,15 +1,15 @@
FLAVOUR=coordination
BONFIRE_FLAVOUR=flavours/coordination
# COPY this file to /config/{dev|prod}/public.env and change any values as required
# server domain name:
HOSTNAME=localhost
# server port:
PORT=4000
# full backend URL - server protocol + domain name
# include the port if it isn't the default for protocol like 80 or 443
BASE_URL=http://localhost
SERVER_PORT=4000
# port your visitors will access (typically 80 or 443, will be different than SERVER_PORT only if using a reverse proxy)
PUBLIC_PORT=4000
# what service to use for sending out emails (eg. smtp, mailgun, none) NOTE: you should also set the corresponding keys in secrets.env
MAIL_BACKEND=none
# hostname and port of meili search index
SEARCH_MEILI_INSTANCE=http://search:7700
SEARCH_MEILI_INSTANCE=http://localhost:7700
# require an email address to be invited before being able to sign up
INVITE_ONLY=true
# a name and tagline for your instance
@ -20,10 +20,9 @@ INSTANCE_DESCRIPTION="An instance of Bonfire, a federated app ecosystem for open
UPLOAD_LIMIT=20000000
# ====================================
# You should not have to edit any of the following ones:
APP_NAME=Bonfire
POSTGRES_HOST=localhost
LANG=en_US.UTF-8
REPLACE_OS_VARS=true
LIVEVIEW_ENABLED=true
CI=false
ACME_AGREE=true

View file

@ -0,0 +1 @@
../../../classic/repo/migrations/20210618094945_peered_uri.exs

View file

@ -2,6 +2,12 @@ import Config
config :bonfire, :ui,
theme: [
instance_name: "Amsterdam pilot",
instance_logo: "https://reflowproject.eu/wp-content/themes/reflow/images/logoBlue.svg",
instance_image: "https://reflowproject.eu/wp-content/uploads/2020/06/reflow-blog-1600x900.jpg",
instance_description: "This is a Reflow demo instance of the Amsterdam pilot"
],
sidebar_components: [
{Bonfire.UI.Reflow.SidebarNavigationLive, []},
{Bonfire.UI.ValueFlows.ProcessesListLive, [title: "Processes", process_url: "/process/"]},
@ -18,8 +24,8 @@ config :bonfire, :ui,
private: Bonfire.UI.Social.PrivateLive,
posts: Bonfire.UI.Social.ProfilePostsLive,
boosts: Bonfire.UI.Social.ProfileBoostsLive,
followers: Bonfire.UI.Social.ProfileFollowersLive,
followed: Bonfire.UI.Social.ProfileFollowersLive,
followers: Bonfire.UI.Social.ProfileFollowsLive,
followed: Bonfire.UI.Social.ProfileFollowsLive,
inventory: Bonfire.UI.Reflow.ProfileInventoryLive,
],
navigation: [
@ -53,14 +59,13 @@ config :bonfire, :ui,
],
resource: [
navigation: [
trace: "material passport",
track: "next events",
trace: "trace",
track: "track",
],
widgets: [
# Bonfire.UI.Social.SubscribeWidgetLive,
# Bonfire.UI.Social.SubscribeWidgetLive
Bonfire.UI.ValueFlows.LocationWidgetLive,
Bonfire.UI.ValueFlows.PrimaryAccountableWidgetLive,
Bonfire.UI.Social.HashtagsWidgetLive,
],
]
# process: [

View file

@ -1,7 +1,7 @@
# web
phoenix_live_view = "~> 0.14"
phoenix_html = "~> 2.11"
phoenix_live_dashboard = "~> 0.2.0"
phoenix_live_dashboard = "~> 0.4"
plug_cowboy = "~> 2.0"
phoenix = "~> 1.5.3"
phoenix_ecto = "~> 4.1"

View file

@ -2,7 +2,7 @@
# make sure you change everything to your own secrets!
# and do not check this into git or any public host
# for sessions/cookies
# for sessions/cookies, you can generate strings for these by running: make secrets
SECRET_KEY_BASE="you-should-put-a-secure-string-here"
SIGNING_SALT="you-should-put-a-different-secure-string-here"
ENCRYPTION_SALT="you-should-put-yet-another-secure-string-here"
@ -13,8 +13,9 @@ POSTGRES_DB=bonfire_db
POSTGRES_PASSWORD=put_a_secure_db_pw_here
# signup to mailgun.com and edit with your domain and API key
MAIL_DOMAIN=mailg.mydomain.net
MAIL_DOMAIN=mailg.example.com
MAIL_KEY=123
MAIL_FROM=bonfire@example.com
# password for the search index
MEILI_MASTER_KEY=key-to-protect-search-indexing-here

View file

@ -1,15 +1,15 @@
FLAVOUR=reflow
BONFIRE_FLAVOUR=flavours/reflow
# COPY this file to /config/{dev|prod}/public.env and change any values as required
# server domain name:
HOSTNAME=localhost
# server port:
PORT=4000
# full backend URL - server protocol + domain name
# include the port if it isn't the default for protocol like 80 or 443
BASE_URL=http://localhost
SERVER_PORT=4000
# port your visitors will access (typically 80 or 443, will be different than SERVER_PORT only if using a reverse proxy)
PUBLIC_PORT=4000
# what service to use for sending out emails (eg. smtp, mailgun, none) NOTE: you should also set the corresponding keys in secrets.env
MAIL_BACKEND=none
# hostname and port of meili search index
SEARCH_MEILI_INSTANCE=http://search:7700
SEARCH_MEILI_INSTANCE=http://localhost:7700
# require an email address to be invited before being able to sign up
INVITE_ONLY=true
# a name and tagline for your instance
@ -20,10 +20,10 @@ INSTANCE_DESCRIPTION="An instance of Bonfire, a federated app ecosystem for open
UPLOAD_LIMIT=20000000
# ====================================
# You should not have to edit any of the following ones:
APP_NAME=Reflow
APP_NAME=reflow
POSTGRES_HOST=localhost
LANG=en_US.UTF-8
REPLACE_OS_VARS=true
LIVEVIEW_ENABLED=true
CI=false
ACME_AGREE=true

View file

@ -1 +1 @@
../../../classic/repo/migrations/20200523081010_hello_world.exs
../../../coordination/repo/migrations/20200523081010_hello_world.exs

View file

@ -1 +1 @@
../../../classic/repo/migrations/20200523081012_init_pointers.exs
../../../coordination/repo/migrations/20200523081012_init_pointers.exs

View file

@ -1 +1 @@
../../../classic/repo/migrations/20200523081013_init_pointers_ulid.exs
../../../coordination/repo/migrations/20200523081013_init_pointers_ulid.exs

View file

@ -1 +1 @@
../../../classic/repo/migrations/20200805090401_create_ap_tables.exs
../../../coordination/repo/migrations/20200805090401_create_ap_tables.exs

View file

@ -1 +1 @@
../../../classic/repo/migrations/20200817072952_create_oban_tables.exs
../../../coordination/repo/migrations/20200817072952_create_oban_tables.exs

View file

@ -1 +1 @@
../../../classic/repo/migrations/20200818094943_import_ap.exs
../../../coordination/repo/migrations/20200818094943_import_ap.exs

View file

@ -1 +1 @@
../../../classic/repo/migrations/20200820094941_import_boundaries.exs
../../../coordination/repo/migrations/20200820094941_import_boundaries.exs

View file

@ -1 +1 @@
../../../classic/repo/migrations/20200828094943_add_files.exs
../../../coordination/repo/migrations/20200828094943_add_files.exs

View file

@ -1 +1 @@
../../../classic/repo/migrations/20200828094944_import_me.exs
../../../coordination/repo/migrations/20200828094944_import_me.exs

View file

@ -1 +1 @@
../../../classic/repo/migrations/20200828094945_import_social.exs
../../../coordination/repo/migrations/20200828094945_import_social.exs

View file

@ -1 +1 @@
../../../classic/repo/migrations/20200829004946_boundaries_fixtures.exs
../../../coordination/repo/migrations/20200829004946_boundaries_fixtures.exs

View file

@ -1,15 +0,0 @@
defmodule Bonfire.Repo.Migrations.TaxonomySeeder do
use Ecto.Migration
# def up do
# Bonfire.TaxonomySeeder.Migrations.up()
# Bonfire.TaxonomySeeder.Migrations.add_category()
# end
# def down do
# Bonfire.TaxonomySeeder.Migrations.down()
# end
def change, do: nil
end

View file

@ -0,0 +1 @@
../../../coordination/repo/migrations/20200902084500_taxonomy_seeder.exs

View file

@ -1 +1 @@
../../../classic/repo/migrations/20200924084501_tagged.exs
../../../coordination/repo/migrations/20200924084501_tagged.exs

View file

@ -1 +1 @@
../../../classic/repo/migrations/20201205094942_import_classify.exs
../../../coordination/repo/migrations/20201205094942_import_classify.exs

View file

@ -1,17 +0,0 @@
defmodule Bonfire.Repo.Migrations.ImportQuantify do
use Ecto.Migration
def up do
if Code.ensure_loaded?(Bonfire.Quantify.Migrations) do
Bonfire.Quantify.Migrations.change
Bonfire.Quantify.Migrations.change_measure
end
end
def down do
if Code.ensure_loaded?(Bonfire.Quantify.Migrations) do
Bonfire.Quantify.Migrations.change
Bonfire.Quantify.Migrations.change_measure
end
end
end

View file

@ -0,0 +1 @@
../../../coordination/repo/migrations/20201205094943_import_quantify.exs

View file

@ -1,15 +0,0 @@
defmodule Bonfire.Repo.Migrations.ImportGeolocation do
use Ecto.Migration
def up do
if Code.ensure_loaded?(Bonfire.Geolocate.Migrations) do
Bonfire.Geolocate.Migrations.change
end
end
def down do
if Code.ensure_loaded?(Bonfire.Geolocate.Migrations) do
Bonfire.Geolocate.Migrations.change
end
end
end

View file

@ -0,0 +1 @@
../../../coordination/repo/migrations/20201208094940_import_geolocation.exs

View file

@ -1,11 +0,0 @@
defmodule Bonfire.Repo.Migrations.ImportValueFlows do
use Ecto.Migration
def up do
if Code.ensure_loaded?(ValueFlows.AllMigrations), do: ValueFlows.AllMigrations.up
end
def down do
if Code.ensure_loaded?(ValueFlows.AllMigrations), do: ValueFlows.AllMigrations.down
end
end

View file

@ -0,0 +1 @@
../../../coordination/repo/migrations/20201212094942_import_valueflows.exs

View file

@ -1,10 +0,0 @@
defmodule Bonfire.Repo.Migrations.ImportSharedUser do
use Ecto.Migration
import Bonfire.Data.SharedUser.Migration
# accounts & users
def up, do: migrate_shared_user()
def down, do: migrate_shared_user()
end

View file

@ -0,0 +1 @@
../../../coordination/repo/migrations/20210102094944_import_shared_user.exs

View file

@ -1,13 +0,0 @@
defmodule Bonfire.Repo.Migrations.ImportValueFlowsObserve do
use Ecto.Migration
alias ValueFlows.Observe.Migrations
def up do
if Code.ensure_loaded?(Migrations), do: Migrations.up
end
def down do
if Code.ensure_loaded?(Migrations), do: Migrations.down
end
end

View file

@ -0,0 +1 @@
../../../coordination/repo/migrations/20210113094942_import_valueflows_observe.exs

View file

@ -1,11 +0,0 @@
defmodule Bonfire.Repo.Migrations.TaggedTimestamps do
use Ecto.Migration
def up do
Bonfire.Tag.Migrations.tagged_timestamps_up()
end
def down do
Bonfire.Tag.Migrations.tagged_timestamps_down()
end
end

View file

@ -0,0 +1 @@
../../../coordination/repo/migrations/20210124084501_tagged_timestamps.exs

View file

@ -1 +1 @@
../../../classic/repo/migrations/20210201094944_import_replied.exs
../../../coordination/repo/migrations/20210201094944_import_replied.exs

View file

@ -1 +1 @@
../../../classic/repo/migrations/20210302094944_import_boost.exs
../../../coordination/repo/migrations/20210302094944_import_boost.exs

View file

@ -1 +1 @@
../../../classic/repo/migrations/20210302094945_import_flag.exs
../../../coordination/repo/migrations/20210302094945_import_flag.exs

View file

@ -1 +1 @@
../../../classic/repo/migrations/20210302094946_import_inbox.exs
../../../coordination/repo/migrations/20210302094946_import_inbox.exs

View file

@ -1 +1 @@
../../../classic/repo/migrations/20210401094942_count_functions.exs
../../../coordination/repo/migrations/20210401094942_count_functions.exs

View file

@ -1 +1 @@
../../../classic/repo/migrations/20210402105128_ap_test_table.exs
../../../coordination/repo/migrations/20210402105128_ap_test_table.exs

View file

@ -1 +1 @@
../../../classic/repo/migrations/20210407094946_message.exs
../../../coordination/repo/migrations/20210407094946_message.exs

View file

@ -1 +1 @@
../../../classic/repo/migrations/20210410094945_profile_images.exs
../../../coordination/repo/migrations/20210410094945_profile_images.exs

View file

@ -1 +1 @@
../../../classic/repo/migrations/20210412094946_fp.exs
../../../coordination/repo/migrations/20210412094946_fp.exs

View file

@ -0,0 +1 @@
../../../classic/repo/migrations/20210618094945_peered_uri.exs

View file

@ -17,16 +17,20 @@ then
git config core.fileMode false
# if there are changes, commit them (needed before being able to rebase)
git diff-index --quiet HEAD || git commit --verbose --all
git diff-index --quiet HEAD || git commit --verbose --all || echo Skipped...
# fetch and rebase remote changes
git pull --rebase
# fetch and rebase remote changes, or fallback to regular pulling if we skipped commiting
git pull --rebase || git pull
echo Publishing changes!
git push
else
set -e
#echo No local changes since last run
git pull
if [[ $2 == 'pull' ]]
then
git pull
fi
fi

View file

@ -1,9 +0,0 @@
defmodule Bonfire.ActivityPub.Queries do
use Bonfire.Repo.Query,
schema: ActivityPub.Object,
searchable_fields: [:id, :data, :local, :public, :pointer_id],
sortable_fields: [:id, :pointer_id]
# TODO: test querying AP table
end

View file

@ -9,18 +9,35 @@ defmodule Bonfire.Application do
use Application
def start(_type, _args) do
Bonfire.Repo.LogSlow.setup()
applications() #|> IO.inspect
|> Supervisor.start_link(strategy: :one_for_one, name: @sup_name)
end
def applications(with_graphql \\ Code.ensure_loaded?(Bonfire.GraphQL.Schema)) # TODO better
def applications(true) do
[
{Absinthe.Schema, Bonfire.GraphQL.Schema} # use persistent_term backend for Absinthe
] ++ applications(false)
end
def applications(_) do
[ Bonfire.Web.Telemetry, # Metrics
Bonfire.Repo, # Database
{Phoenix.PubSub, name: Bonfire.PubSub}, # PubSub
# Persistent Data Services
Pointers.Tables,
Bonfire.Data.AccessControl.Accesses,
Bonfire.Common.ContextModules,
Bonfire.Common.QueryModules,
Bonfire.Federate.ActivityPub.FederationModules,
Bonfire.Data.AccessControl.Verbs,
Bonfire.Data.AccessControl.Accesses,
# Stuff that uses all the above
Bonfire.Web.Endpoint, # Webapp
{Oban, Application.get_env(:bonfire, Oban)} # Job Queue
Bonfire.Web.Endpoint, # Web app
{Oban, Application.fetch_env!(:bonfire, Oban)} # Job Queue
]
|> Supervisor.start_link(strategy: :one_for_one, name: @sup_name)
end
# Tell Phoenix to update the endpoint configuration

View file

@ -0,0 +1,231 @@
defmodule Mix.Tasks.Bonfire.Dep.Compile do
use Mix.Task
@shortdoc "Compiles dependencies"
@moduledoc """
Compiles dependencies.
By default, compile all dependencies. A list of dependencies
can be given compile multiple dependencies in order.
This task attempts to detect if the project contains one of
the following files and act accordingly:
* `mix.exs` - invokes `mix compile`
* otherwise skip
If a list of dependencies is given, Mix will attempt to compile
them as is. For example, if project `a` depends on `b`, calling
`mix deps.compile a` will compile `a` even if `b` is out of
date. This is to allow parts of the dependency tree to be
recompiled without propagating those changes upstream. To ensure
`b` is included in the compilation step, pass `--include-children`.
"""
import Mix.Dep, only: [available?: 1, mix?: 1]
@switches [include_children: :boolean, force: :boolean]
@spec run(OptionParser.argv) :: :ok
def run(args) do
unless "--no-archives-check" in args do
Mix.Task.run "archive.check", args
end
Mix.Project.get!
case OptionParser.parse(args, switches: @switches) do
{opts, [], _} ->
# Because this command may be invoked explicitly with
# deps.compile, we simply try to compile any available
# dependency.
compile(Enum.filter(loaded_deps(), &available?/1), opts)
{opts, tail, _} ->
compile(loaded_by_name(tail, [env: Mix.env] ++ opts), opts)
end
end
@doc false
def compile(deps, options \\ []) do
shell = Mix.shell
config = Mix.Project.deps_config
Mix.Task.run "deps.precompile"
compiled =
Enum.map(deps, fn %Mix.Dep{app: app, status: status, opts: opts, scm: scm} = dep ->
check_unavailable!(app, status)
compiled? = cond do
mix?(dep) ->
maybe_clean(dep, options)
do_mix dep, config
true ->
shell.error "Could not compile #{inspect app}, no \"mix.exs\" found " <>
"(pass :compile as an option to customize compilation, set it to \"false\" to do nothing)"
false
end
# We should touch fetchable dependencies even if they
# did not compile otherwise they will always be marked
# as stale, even when there is nothing to do.
fetchable? = touch_fetchable(scm, opts[:build])
compiled? and fetchable?
end)
if true in compiled, do: Mix.Task.run("will_recompile"), else: :ok
end
defp maybe_clean(dep, opts) do
# If a dependency was marked as fetched or with an out of date lock
# or missing the app file, we always compile it from scratch.
if Keyword.get(opts, :force, false) or Mix.Dep.compilable?(dep) do
File.rm_rf!(Path.join([Mix.Project.build_path(), "lib", Atom.to_string(dep.app)]))
end
end
defp touch_fetchable(scm, path) do
if scm.fetchable? do
File.mkdir_p!(path)
File.touch!(Path.join(path, ".compile.fetch"))
true
else
false
end
end
defp check_unavailable!(app, {:unavailable, _}) do
Mix.raise "Cannot compile dependency #{inspect app} because " <>
"it isn't available, run \"mix deps.get\" first"
end
defp check_unavailable!(_, _) do
:ok
end
defp do_mix(dep, _config) do
Mix.Dep.in_dependency dep, fn _ ->
if req = old_elixir_req(Mix.Project.config) do
Mix.shell.error "warning: the dependency #{inspect dep.app} requires Elixir #{inspect req} " <>
"but you are running on v#{System.version}"
end
Mix.shell.info "Recompiling extension #{inspect dep.app}"
try do
# If "compile" was never called, the reenabling is a no-op and
# "compile.elixir" is a no-op as well (because it wasn't reenabled after
# running "compile"). If "compile" was already called, then running
# "compile" is a no-op and running "compile.elixir" will work because we
# manually reenabled it.
Mix.Task.reenable("compile.elixir")
Mix.Task.reenable("compile.leex")
Mix.Task.reenable("compile.all")
Mix.Task.reenable("compile")
options = [
# "--force",
"--no-deps-loading",
"--no-apps-loading",
"--no-archives-check",
"--no-elixir-version-check",
"--no-warnings-as-errors"
]
res = Mix.Task.run("compile", options)
# Mix.shell.info(inspect res)
match?({:ok, _}, res)
catch
kind, reason ->
stacktrace = System.stacktrace
app = dep.app
Mix.shell.error "could not compile dependency #{inspect app}, \"mix compile\" failed. " <>
"You can recompile this dependency with \"mix deps.compile #{app}\", update it " <>
"with \"mix deps.update #{app}\" or clean it with \"mix deps.clean #{app}\""
:erlang.raise(kind, reason, stacktrace)
end
end
end
defp old_elixir_req(config) do
req = config[:elixir]
if req && not Version.match?(System.version, req) do
req
end
end
defp loaded_deps() do
if Keyword.has_key?(Mix.Dep.__info__(:functions), :cached) do
Mix.Dep.cached()
else
Mix.Dep.loaded()
end
end
@doc """
Receives a list of dependency names and returns loaded `Mix.Dep`s.
Logs a message if the dependency could not be found.
## Exceptions
This function raises an exception if any of the dependencies
provided in the project are in the wrong format.
"""
def loaded_by_name(given, all_deps \\ nil, opts) do
all_deps = all_deps || loaded_deps()
# Ensure all apps are atoms
apps = to_app_names(given)
deps =
if opts[:include_children] do
get_deps_with_children(all_deps, apps)
else
get_deps(all_deps, apps)
end
Enum.each apps, fn(app) ->
unless Enum.any?(all_deps, &(&1.app == app)) do
Mix.raise "Unknown dependency #{app} for environment #{Mix.env}"
end
end
deps
end
defp to_app_names(given) do
Enum.map given, fn(app) ->
if is_binary(app), do: String.to_atom(app), else: app
end
end
defp get_deps(all_deps, apps) do
Enum.filter(all_deps, &(&1.app in apps))
end
defp get_deps_with_children(all_deps, apps) do
deps = get_children(all_deps, apps)
apps = deps |> Enum.map(& &1.app) |> Enum.uniq
get_deps(all_deps, apps)
end
defp get_children(_all_deps, []), do: []
defp get_children(all_deps, apps) do
# Current deps
deps = get_deps(all_deps, apps)
# Children apps
apps = for %{deps: children} <- deps,
%{app: app} <- children,
do: app
# Current deps + children deps
deps ++ get_children(all_deps, apps)
end
end

View file

@ -0,0 +1,94 @@
defmodule Mix.Tasks.Bonfire.Localise.Extract do
use Mix.Task
@recursive true
@shortdoc "Extracts translations from source code"
@moduledoc """
Extracts translations by recompiling the Elixir source code.
mix gettext.extract [OPTIONS]
Translations are extracted into POT (Portable Object Template) files (with a
`.pot` extension). The location of these files is determined by the `:otp_app`
and `:priv` options given by Gettext modules when they call `use Gettext`. One
POT file is generated for each translation domain.
It is possible to give the `--merge` option to perform merging
for every Gettext backend updated during merge:
mix gettext.extract --merge
All other options passed to `gettext.extract` are forwarded to the
`gettext.merge` task (`Mix.Tasks.Gettext.Merge`), which is called internally
by this task. For example:
mix gettext.extract --merge --no-fuzzy
"""
@switches [merge: :boolean]
def run(args, app \\ :bonfire_common) do
Application.ensure_all_started(:gettext)
_ = Mix.Project.get!()
mix_config = Mix.Project.config()
{opts, _} = OptionParser.parse!(args, switches: @switches)
pot_files = extract(app || mix_config[:app], mix_config[:gettext] || []) #|> IO.inspect(label: "extracted")
for {path, contents} <- pot_files do
File.mkdir_p!(Path.dirname(path))
File.write!(path, contents)
Mix.shell().info("Extracted #{Path.relative_to_cwd(path)}")
end
if opts[:merge] do
run_merge(pot_files, args)
end
:ok
end
defp extract(app, gettext_config) do
Gettext.Extractor.enable()
force_compile()
Gettext.Extractor.pot_files(
app, # |> IO.inspect(label: "app"),
gettext_config # |> IO.inspect(label: "config")
)
after
Gettext.Extractor.disable()
end
defp force_compile do
Mix.Tasks.Compile.Elixir.manifests()
# ++ (Mix.Project.build_path<>"/lib/bonfire_*/.mix/compile.elixir" |> IO.inspect |> Path.wildcard(match_dot: true))
# ["forks/bonfire_common/lib/web/gettext.ex" |> Path.expand(File.cwd!)]
#|> IO.inspect(label: "recompile")
|> Enum.map(&make_old_if_exists/1)
(["--force"] ++ Bonfire.MixProject.deps_to_localise()) #|> IO.inspect
|> Mix.Tasks.Bonfire.Dep.Compile.run()
# If "compile" was never called, the reenabling is a no-op and
# "compile.elixir" is a no-op as well (because it wasn't reenabled after
# running "compile"). If "compile" was already called, then running
# "compile" is a no-op and running "compile.elixir" will work because we
# manually reenabled it.
Mix.Task.reenable("compile.elixir")
Mix.Task.run("compile")
Mix.Task.run("compile.elixir")
end
defp make_old_if_exists(path) do
:file.change_time(path, {{2000, 1, 1}, {0, 0, 0}})
end
defp run_merge(pot_files, argv) do
pot_files
|> Enum.map(fn {path, _} -> Path.dirname(path) end)
|> Enum.uniq()
|> Task.async_stream(&Mix.Tasks.Gettext.Merge.run([&1 | argv]), ordered: false)
|> Stream.run()
end
end

30
lib/mix/tasks/secrets/.gitignore vendored Normal file
View file

@ -0,0 +1,30 @@
# The directory Mix will write compiled artifacts to.
/_build/
# If you run "mix test --cover", coverage assets end up here.
/cover/
# The directory Mix downloads your dependencies sources to.
/deps/
# Where third-party dependencies like ExDoc output generated docs.
/doc/
# Ignore .fetch files in case you like to edit your project deps locally.
/.fetch
# If the VM crashes, it generates a dump, let's ignore it too.
erl_crash.dump
# Also ignore archive artifacts (built via "mix archive.build").
*.ez
# Ignore package tarball (built via "mix hex.build").
release-*.tar
# Temporary files for e.g. tests
/tmp
# The build
secrets

View file

@ -0,0 +1,37 @@
defmodule Mix.Tasks.Bonfire.Secrets do
@shortdoc "Generates some secrets"
@moduledoc """
Generates secrets and prints to the terminal.
mix secrets [length]
By default, it generates keys 64 characters long.
The minimum value for `length` is 32.
"""
use Mix.Task
def main(args) do # for running as escript
run(args)
end
@doc false
def run([]), do: run(["64"])
def run([int]), do: int |> parse!() |> random_string() |> Kernel.<>("\r\n") |> IO.puts()
def run([int, iterate]), do: for _ <- 1..parse!(iterate), do: run([int])
def run(args), do: invalid_args!(args)
defp parse!(int) do
case Integer.parse(int) do
{int, ""} -> int
_ -> invalid_args!(int)
end
end
defp random_string(length) when length > 31 do
:crypto.strong_rand_bytes(length) |> Base.encode64 |> binary_part(0, length)
end
defp random_string(_), do: raise "Secrets should be at least 32 characters long"
defp invalid_args!(args) do
raise "Expected a length as integer or no argument at all, got #{inspect args}"
end
end

View file

@ -0,0 +1,13 @@
defmodule Bonfire.Secrets do
use Mix.Project
def project do
[
app: :secrets,
version: "0.1.0-alpha.1",
elixir: "~> 1.11",
escript: [main_module: Mix.Tasks.Bonfire.Secrets]
]
end
end

View file

@ -27,7 +27,7 @@ defmodule Bonfire.Web.Endpoint do
at: "/",
from: :bonfire,
gzip: true,
only: ~w(data css fonts images js favicon.ico robots.txt)
only: ~w(data css fonts images js favicon.ico robots.txt cache_manifest.json)
# Code reloading can be explicitly enabled under the
# :code_reloader configuration of your endpoint.
@ -54,4 +54,18 @@ defmodule Bonfire.Web.Endpoint do
plug Plug.Head
plug Plug.Session, @session_options
plug Bonfire.Web.Router
def include_assets(conn) do
js = if Bonfire.Common.Utils.e(conn, :assigns, :current_account, nil) do
static_path("/js/live.js")
else
static_path("/js/non_live.js")
end
if Bonfire.Common.Config.get!(:env) == :dev do
"<link phx-track-static rel='stylesheet' href='"<> static_path("/css/app.css") <>"'/> <script defer phx-track-static crossorigin='anonymous' src='"<> js <>"'></script>"
else
"<link phx-track-static rel='stylesheet' href='"<> static_path("/css/app.css") <>"'/> <script defer phx-track-static crossorigin='anonymous' src='"<> js <>"'></script> "
end
end
end

View file

@ -3,16 +3,14 @@ if Bonfire.Common.Utils.module_enabled?(Bonfire.GraphQL) and Bonfire.Common.Util
defmodule Bonfire.GraphQL.Schema do
@moduledoc "Root GraphQL Schema"
use Absinthe.Schema
# import Bonfire.GraphQL.SchemaUtils
@schema_provider Absinthe.Schema.PersistentTerm
# @pipeline_modifier Bonfire.GraphQL.SchemaPipelines
require Logger
alias Bonfire.GraphQL.SchemaUtils
alias Bonfire.GraphQL.Middleware.CollapseErrors
alias Absinthe.Middleware.{Async, Batch}
# @pipeline_modifier OverridePhase
def plugins, do: [Async, Batch]

Some files were not shown because too many files have changed in this diff Show more