diff --git a/.env.example b/.env.example index a1348593..a62e2b0a 100644 --- a/.env.example +++ b/.env.example @@ -1,3 +1,5 @@ +DELEGATE=athshe.sutty.nl +HAINISH=../haini.sh/haini.sh DATABASE= RAILS_ENV= IMAP_SERVER= diff --git a/Makefile b/Makefile index c083ddf8..a4480476 100644 --- a/Makefile +++ b/Makefile @@ -1,134 +1,111 @@ -.SHELL := /bin/bash -# Incluir las variables de entorno -mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST))) -root_dir := $(patsubst %/,%,$(dir $(mkfile_path))) -include $(root_dir)/.env +SHELL := /bin/bash +.DEFAULT_GOAL := help -delegate := athshe +# Copiar el archivo de configuración y avisar cuando hay que +# actualizarlo. +.env: .env.example + @test -f $@ || cp -v $< $@ + @test -f $@ && echo "Revisa $@ para actualizarlo con respecto a $<" + @test -f $@ && diff -auN --color $@ $< -assets := package.json yarn.lock $(shell find app/assets/ app/javascript/ -type f) +include .env -alpine_version := 3.13 -hain ?= ../haini.sh/haini.sh +export -env ?= staging +args ?= ## Argumentos para Hain +commit ?= origin/rails ## Commit desde el que actualizar +env ?= staging ## Entorno del nodo delegado +sutty ?= $(SUTTY) ## Dirección local +delegate ?= $(DELEGATE) ## Cambia el nodo delegado +hain ?= $(HAINISH) ## Ubicación de Hainish +# El nodo delegado tiene dos entornos, production y staging. +# Dependiendo del entorno que elijamos, se van a generar los assets y el +# contenedor y subirse a un servidor u otro. No utilizamos CI/CD (aún). +# +# Production es el entorno de panel.sutty.nl ifeq ($(env),production) container ?= sutty +## TODO: Cambiar a otra cosa branch ?= rails public ?= public endif +# Staging es el entorno de panel.staging.sutty.nl ifeq ($(env),staging) container := staging branch := staging public := staging endif -export +help: always ## Ayuda + @echo -e "Sutty\n" | sed -re "s/^.*/\x1B[38;5;197m&\x1B[0m/" + @echo -e "Servidor: https://panel.$(SUTTY_WITH_PORT)/\n" + @echo -e "Uso: make TAREA args=\"ARGUMENTOS\"\n" + @echo -e "Tareas:\n" + @grep -E "^[a-z\-]+:.*##" Makefile | sed -re "s/(.*):.*##(.*)/\1;\2/" | column -s ";" -t | sed -re "s/^([^ ]+) /\x1B[38;5;197m\1\x1B[0m/" + @echo -e "\nArgumentos:\n" + @grep -E "^[a-z\-]+ \?=.*##" Makefile | sed -re "s/(.*) \?=.*##(.*)/\1;\2/" | column -s ";" -t | sed -re "s/^([^ ]+) /\x1B[38;5;197m\1\x1B[0m/" -public/packs/manifest.json.br: $(assets) - $(hain) 'cd /Sutty/sutty; PANEL_URL=https://panel.sutty.nl RAILS_ENV=production NODE_ENV=production bundle exec rake assets:precompile assets:clean' +assets: node_modules public/packs/manifest.json.br ## Compilar los assets -assets: public/packs/manifest.json.br +test: always ## Ejecutar los tests + $(MAKE) rake args="test RAILS_ENV=test $(args)" -tests := $(shell find test/ -name "*_test.rb") -$(tests): always - $(hain) 'cd /Sutty/sutty; bundle exec rake test TEST="$@" RAILS_ENV=test' - -test: always - $(hain) 'cd /Sutty/sutty; RAILS_ENV=test bundle exec rake test' - -postgresql: /etc/hosts +postgresql: /etc/hosts ## Iniciar la base de datos pgrep postgres >/dev/null || $(hain) postgresql -serve: /etc/hosts postgresql +serve-js: /etc/hosts node_modules ## Iniciar el servidor de desarrollo de Javascript + $(hain) 'bundle exec ./bin/webpack-dev-server' + +serve: /etc/hosts postgresql Gemfile.lock ## Iniciar el servidor de desarrollo de Rails $(MAKE) rails args=server -# make rails args="db:migrate" -rails: +rails: ## Tareas de Rails $(MAKE) bundle args="exec rails $(args)" -rake: +rake: ## Tareas de Rake $(MAKE) bundle args="exec rake $(args)" -bundle: - $(hain) 'cd /Sutty/sutty; bundle $(args)' +bundle: ## Tareas de bundler + $(hain) 'bundle $(args)' -yarn: +rubocop: ## Yutea el código que está por ser commiteado + git status --porcelain \ + | grep -E "^(A|M)" \ + | sed "s/^...//" \ + | grep ".rb$$" \ + | ../haini.sh/haini.sh "xargs -r ./bin/rubocop --auto-correct" + +audit: ## Encuentra dependencias con vulnerabilidades + $(hain) 'gem install bundler-audit' + $(hain) 'bundle audit --update' + +brakeman: ## Busca posibles vulnerabilidades en Sutty + $(MAKE) bundle args='exec brakeman' + +yarn: ## Tareas de yarn $(hain) 'yarn $(args)' -# Servir JS con el dev server. -# Esto acelera la compilación del javascript, tiene que correrse por separado -# de serve. -serve-js: /etc/hosts - $(hain) 'cd /Sutty/sutty; bundle exec ./bin/webpack-dev-server' +clean: ## Limpieza + rm -rf _sites/test-* _deploy/test-* log/*.log tmp/cache tmp/letter_opener tmp/miniprofiler tmp/storage -# Limpiar los archivos de testeo -clean: - rm -rf _sites/test-* _deploy/test-* - -# Generar la imagen Docker -build: assets +build: Gemfile.lock ## Generar la imagen Docker time docker build --build-arg="BRANCH=$(branch)" --build-arg="RAILS_MASTER_KEY=`cat config/master.key`" -t sutty/$(container) . docker tag sutty/$(container):latest sutty:keep + @echo -e "\a" -save: - time docker save sutty/$(container):latest | ssh root@$(delegate).sutty.nl docker load +save: ## Subir la imagen Docker al nodo delegado + time docker save sutty/$(container):latest | ssh root@$(delegate) docker load date +%F | xargs -I {} git tag -f $(container)-{} @echo -e "\a" -# proyectos. -../gems/: - mkdir -p $@ - -# Crear el directorio donde se almacenan las gemas binarias -# TODO: Mover a un proyecto propio, porque lo utilizamos en todos los -gem_dir := $(shell readlink -f ../gems) -gem_cache_dir := $(gem_dir)/cache -gem_binary_dir := $(gem_dir)/$(alpine_version) -ifeq ($(MAKECMDGOALS),build-gems) -gems := $(shell bundle show --paths | xargs -I {} sh -c 'find {}/ext/ -name extconf.rb &>/dev/null && basename {}') -gems := $(patsubst %-x86_64-linux,%,$(gems)) -gems := $(patsubst %,$(gem_cache_dir)/%.gem,$(gems)) -gems_musl := $(patsubst $(gem_cache_dir)/%.gem,$(gem_binary_dir)/%-x86_64-linux-musl.gem,$(gems)) -endif - -$(gem_binary_dir)/%-x86_64-linux-musl.gem: - @docker run \ - -v $(gem_dir):/srv/gems \ - -v `readlink -f ~/.ccache`:/home/builder/.ccache \ - -e HTTP_BASIC_USER=$(HTTP_BASIC_USER) \ - -e HTTP_BASIC_PASSWORD=$(HTTP_BASIC_PASSWORD) \ - -e GEM=`echo $(notdir $*) | sed -re "s/-[^-]+$$//"` \ - -e VERSION=`echo $(notdir $*) | sed -re "s/.*-([^-]+)$$/\1/"` \ - -e JOBS=2 \ - --rm -it \ - sutty/gem-compiler:latest || echo "No se pudo compilar $*" - -# Compilar todas las gemas binarias y subirlas a gems.sutty.nl para que -# al crear el contenedor no tengamos que compilarlas cada vez -build-gems: $(gems_musl) - -cached_gems = $(wildcard $(gem_dir)/cache/*.gem) -rebuild_gems = $(patsubst $(gem_dir)/cache/%.gem,$(gem_dir)/$(alpine_version)/%-x86_64-linux-musl.gem,$(cached_gems)) -rebuild-gems: $(rebuild_gems) - -dirs := $(patsubst %,root/%,data sites deploy public) - -$(dirs): - mkdir -p $@ - -ota: assets +ota-js: assets ## Actualizar Javascript en el nodo delegado sudo chgrp -R 82 public/ - rsync -avi --delete-after public/ $(delegate):/srv/sutty/srv/http/data/_$(public)/ - ssh $(delegate) docker exec $(container) sh -c "cat /srv/http/tmp/puma.pid | xargs -r kill -USR2" + rsync -avi --delete-after public/ root@$(delegate):/srv/sutty/srv/http/data/_$(public)/ + ssh root@$(delegate) docker exec $(container) sh -c "cat /srv/http/tmp/puma.pid | xargs -r kill -USR2" -# Hotfixes -# -# TODO: Reemplazar esto por git pull en el contenedor -commit ?= origin/rails -ota-rb: +ota: ## Actualizar Rails en el nodo delegado umask 022; git format-patch $(commit) scp ./0*.patch $(delegate):/tmp/ ssh $(delegate) mkdir -p /tmp/patches-$(commit)/ @@ -140,6 +117,19 @@ ota-rb: ssh $(delegate) docker exec $(container) ota $(commit) rm ./0*.patch +# Todos los archivos de assets. Si alguno cambia, se van a recompilar +# los assets que luego se suben al nodo delegado. +assets := package.json yarn.lock $(shell find app/assets/ app/javascript/ -type f) +public/packs/manifest.json.br: $(assets) + $(hain) 'PANEL_URL=https://panel.sutty.nl RAILS_ENV=production NODE_ENV=production bundle exec rake assets:precompile assets:clean' + +# Correr un test en particular por ejemplo +# `make test/models/usuarie_test.rb` +tests := $(shell find test/ -name "*_test.rb") +$(tests): always + $(MAKE) test args="TEST=$@" + +# Agrega las direcciones locales al sistema /etc/hosts: always @echo "Chequeando si es necesario agregar el dominio local $(SUTTY)" @grep -q " $(SUTTY)$$" $@ || echo -e "127.0.0.1 $(SUTTY)\n::1 $(SUTTY)" | sudo tee -a $@ @@ -147,4 +137,12 @@ ota-rb: @grep -q " panel.$(SUTTY)$$" $@ || echo -e "127.0.0.1 panel.$(SUTTY)\n::1 panel.$(SUTTY)" | sudo tee -a $@ @grep -q " postgresql.$(SUTTY)$$" $@ || echo -e "127.0.0.1 postgresql.$(SUTTY)\n::1 postgresql.$(SUTTY)" | sudo tee -a $@ +# Instala las dependencias de Javascript +node_modules: package.json + $(MAKE) yarn + +# Instala las dependencias de Rails +Gemfile.lock: Gemfile + $(MAKE) bundle args=install + .PHONY: always diff --git a/README.md b/README.md index ef889f9b..25d0d31c 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,17 @@ Este repositorio es la plataforma _Ruby on Rails_ para alojar el Para más información visita el [sitio de Sutty](https://sutty.nl/). +### Desarrollar + +Todas las tareas se gestionan con `make`, por favor instala GNU Make +antes de comenzar. + +```bash +make help +``` + +[Leer la documentación](https://docs.sutty.nl/) + ## English Sutty is a platform for hosting safer, faster and more resilient @@ -25,3 +36,13 @@ This repository is the Ruby on Rails platform that hosts the self-managed [panel](https://panel.sutty.nl/). For more information, visit [Sutty's website](https://sutty.nl/en/). + +### Development + +Every task is run via `make`, please install GNU Make before developing. + +```bash +make help +``` + +[Read the documentation](https://docs.sutty.nl/en/)