mirror of
https://0xacab.org/sutty/sutty
synced 2025-03-16 11:38:18 +00:00
Merge branch 'rails' into staging
This commit is contained in:
commit
05a38f5b7e
18 changed files with 380 additions and 24 deletions
|
@ -29,3 +29,6 @@ TIENDA=tienda.sutty.local
|
||||||
PANEL_URL=https://panel.sutty.nl
|
PANEL_URL=https://panel.sutty.nl
|
||||||
AIRBRAKE_SITE_ID=1
|
AIRBRAKE_SITE_ID=1
|
||||||
AIRBRAKE_API_KEY=
|
AIRBRAKE_API_KEY=
|
||||||
|
GITLAB_URI=https://0xacab.org
|
||||||
|
GITLAB_PROJECT=
|
||||||
|
GITLAB_TOKEN=
|
||||||
|
|
|
@ -53,7 +53,7 @@ RUN cd ../checkout && git checkout $BRANCH
|
||||||
|
|
||||||
WORKDIR /home/app/checkout
|
WORKDIR /home/app/checkout
|
||||||
# Traer las gemas:
|
# Traer las gemas:
|
||||||
RUN rm -r ./vendor
|
RUN rm -rf ./vendor
|
||||||
RUN mv ../sutty/vendor ./vendor
|
RUN mv ../sutty/vendor ./vendor
|
||||||
RUN mv ../sutty/.bundle ./.bundle
|
RUN mv ../sutty/.bundle ./.bundle
|
||||||
|
|
||||||
|
|
3
Gemfile
3
Gemfile
|
@ -41,13 +41,14 @@ gem 'hiredis'
|
||||||
gem 'image_processing'
|
gem 'image_processing'
|
||||||
gem 'icalendar'
|
gem 'icalendar'
|
||||||
gem 'inline_svg'
|
gem 'inline_svg'
|
||||||
|
gem 'httparty'
|
||||||
gem 'safe_yaml', source: 'https://gems.sutty.nl'
|
gem 'safe_yaml', source: 'https://gems.sutty.nl'
|
||||||
gem 'jekyll', '~> 4.2'
|
gem 'jekyll', '~> 4.2'
|
||||||
gem 'jekyll-data', source: 'https://gems.sutty.nl'
|
gem 'jekyll-data', source: 'https://gems.sutty.nl'
|
||||||
gem 'jekyll-commonmark'
|
gem 'jekyll-commonmark'
|
||||||
gem 'jekyll-images'
|
gem 'jekyll-images'
|
||||||
gem 'jekyll-include-cache'
|
gem 'jekyll-include-cache'
|
||||||
gem 'sutty-liquid'
|
gem 'sutty-liquid', '>= 0.7.3'
|
||||||
gem 'loaf'
|
gem 'loaf'
|
||||||
gem 'lockbox'
|
gem 'lockbox'
|
||||||
gem 'mini_magick'
|
gem 'mini_magick'
|
||||||
|
|
|
@ -574,7 +574,7 @@ GEM
|
||||||
jekyll-include-cache (~> 0)
|
jekyll-include-cache (~> 0)
|
||||||
jekyll-relative-urls (~> 0.0)
|
jekyll-relative-urls (~> 0.0)
|
||||||
jekyll-seo-tag (~> 2.1)
|
jekyll-seo-tag (~> 2.1)
|
||||||
sutty-liquid (0.7.2)
|
sutty-liquid (0.7.3)
|
||||||
fast_blank (~> 1.0)
|
fast_blank (~> 1.0)
|
||||||
jekyll (~> 4)
|
jekyll (~> 4)
|
||||||
sutty-minima (2.5.0)
|
sutty-minima (2.5.0)
|
||||||
|
@ -657,6 +657,7 @@ DEPENDENCIES
|
||||||
haml-lint
|
haml-lint
|
||||||
hamlit-rails
|
hamlit-rails
|
||||||
hiredis
|
hiredis
|
||||||
|
httparty
|
||||||
icalendar
|
icalendar
|
||||||
image_processing
|
image_processing
|
||||||
inline_svg
|
inline_svg
|
||||||
|
@ -706,7 +707,7 @@ DEPENDENCIES
|
||||||
sucker_punch
|
sucker_punch
|
||||||
sutty-donaciones-jekyll-theme
|
sutty-donaciones-jekyll-theme
|
||||||
sutty-jekyll-theme
|
sutty-jekyll-theme
|
||||||
sutty-liquid
|
sutty-liquid (>= 0.7.3)
|
||||||
sutty-minima
|
sutty-minima
|
||||||
symbol-fstring
|
symbol-fstring
|
||||||
terminal-table
|
terminal-table
|
||||||
|
|
15
Makefile
15
Makefile
|
@ -32,7 +32,8 @@ public/packs/manifest.json.br: $(assets)
|
||||||
|
|
||||||
assets: public/packs/manifest.json.br
|
assets: public/packs/manifest.json.br
|
||||||
|
|
||||||
test/%_test.rb: always
|
tests := $(shell find test/ -name "*_test.rb")
|
||||||
|
$(tests): always
|
||||||
$(hain) 'cd /Sutty/sutty; bundle exec rake test TEST="$@" RAILS_ENV=test'
|
$(hain) 'cd /Sutty/sutty; bundle exec rake test TEST="$@" RAILS_ENV=test'
|
||||||
|
|
||||||
test: always
|
test: always
|
||||||
|
@ -54,6 +55,9 @@ rake:
|
||||||
bundle:
|
bundle:
|
||||||
$(hain) 'cd /Sutty/sutty; bundle $(args)'
|
$(hain) 'cd /Sutty/sutty; bundle $(args)'
|
||||||
|
|
||||||
|
yarn:
|
||||||
|
$(hain) 'yarn $(args)'
|
||||||
|
|
||||||
# Servir JS con el dev server.
|
# Servir JS con el dev server.
|
||||||
# Esto acelera la compilación del javascript, tiene que correrse por separado
|
# Esto acelera la compilación del javascript, tiene que correrse por separado
|
||||||
# de serve.
|
# de serve.
|
||||||
|
@ -122,10 +126,19 @@ ota: assets
|
||||||
ssh $(delegate) docker exec $(container) sh -c "cat /srv/http/tmp/puma.pid | xargs -r kill -USR2"
|
ssh $(delegate) docker exec $(container) sh -c "cat /srv/http/tmp/puma.pid | xargs -r kill -USR2"
|
||||||
|
|
||||||
# Hotfixes
|
# Hotfixes
|
||||||
|
#
|
||||||
|
# TODO: Reemplazar esto por git pull en el contenedor
|
||||||
commit ?= origin/rails
|
commit ?= origin/rails
|
||||||
ota-rb:
|
ota-rb:
|
||||||
umask 022; git format-patch $(commit)
|
umask 022; git format-patch $(commit)
|
||||||
scp ./0*.patch $(delegate):/tmp/
|
scp ./0*.patch $(delegate):/tmp/
|
||||||
|
ssh $(delegate) mkdir -p /tmp/patches-$(commit)/
|
||||||
|
scp ./0*.patch $(delegate):/tmp/patches-$(commit)/
|
||||||
|
scp ./ota.sh $(delegate):/tmp/
|
||||||
|
ssh $(delegate) docker cp /tmp/patches-$(commit) $(container):/tmp/
|
||||||
|
ssh $(delegate) docker cp /tmp/ota.sh $(container):/usr/local/bin/ota
|
||||||
|
ssh $(delegate) docker exec $(container) apk add --no-cache patch
|
||||||
|
ssh $(delegate) docker exec $(container) ota $(commit)
|
||||||
rm ./0*.patch
|
rm ./0*.patch
|
||||||
|
|
||||||
/etc/hosts: always
|
/etc/hosts: always
|
||||||
|
|
|
@ -40,7 +40,7 @@ class BacktraceJob < ApplicationJob
|
||||||
begin
|
begin
|
||||||
raise BacktraceException, "#{origin}: #{message}"
|
raise BacktraceException, "#{origin}: #{message}"
|
||||||
rescue BacktraceException => e
|
rescue BacktraceException => e
|
||||||
ExceptionNotifier.notify_exception(e, data: { site: site.name, params: params, _backtrace: true })
|
ExceptionNotifier.notify_exception(e, data: { site: site.name, params: params, javascript_backtrace: true })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
260
app/jobs/gitlab_notifier_job.rb
Normal file
260
app/jobs/gitlab_notifier_job.rb
Normal file
|
@ -0,0 +1,260 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# Notifica excepciones a una instancia de Gitlab, como incidencias
|
||||||
|
# nuevas o como comentarios a las incidencias pre-existentes.
|
||||||
|
class GitlabNotifierJob < ApplicationJob
|
||||||
|
include ExceptionNotifier::BacktraceCleaner
|
||||||
|
|
||||||
|
# Variables que vamos a acceder luego
|
||||||
|
attr_reader :exception, :options, :issue_data, :cached
|
||||||
|
|
||||||
|
queue_as :low_priority
|
||||||
|
|
||||||
|
# @param [Exception] la excepción lanzada
|
||||||
|
# @param [Hash] opciones de ExceptionNotifier
|
||||||
|
def perform(exception, **options)
|
||||||
|
@exception = exception
|
||||||
|
@options = options
|
||||||
|
@issue_data = { count: 1 }
|
||||||
|
# Necesitamos saber si el issue ya existía
|
||||||
|
@cached = false
|
||||||
|
|
||||||
|
# Traemos los datos desde la caché si existen, sino generamos un
|
||||||
|
# issue nuevo e inicializamos la caché
|
||||||
|
@issue_data = Rails.cache.fetch(cache_key) do
|
||||||
|
issue = client.new_issue confidential: true, title: title, description: description, issue_type: 'incident'
|
||||||
|
@cached = true
|
||||||
|
|
||||||
|
{
|
||||||
|
count: 1,
|
||||||
|
issue: issue['iid'],
|
||||||
|
user_agents: [user_agent].compact,
|
||||||
|
params: [request&.filtered_parameters].compact,
|
||||||
|
urls: [url].compact
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
# No seguimos actualizando si acabamos de generar el issue
|
||||||
|
return if cached
|
||||||
|
|
||||||
|
# Incrementar la cuenta de veces que ocurrió
|
||||||
|
issue_data[:count] += 1
|
||||||
|
# Guardar información útil
|
||||||
|
issue_data[:urls] << url unless issue_data[:urls].include? url
|
||||||
|
issue_data[:user_agents] << user_agent unless issue_data[:user_agents].include? user_agent
|
||||||
|
|
||||||
|
# Editar el título para que incluya la cuenta de eventos
|
||||||
|
client.edit_issue(iid: issue_data[:issue], title: title, state_event: 'reopen')
|
||||||
|
|
||||||
|
# Agregar un comentario con la información posiblemente nueva
|
||||||
|
client.new_note(iid: issue_data[:issue], body: body)
|
||||||
|
|
||||||
|
# Guardar para después
|
||||||
|
Rails.cache.write(cache_key, issue_data)
|
||||||
|
# Si este trabajo genera una excepción va a entrar en un loop, así que
|
||||||
|
# la notificamos por correo
|
||||||
|
rescue Exception => e
|
||||||
|
email_notification.call(e)
|
||||||
|
email_notification.call(exception, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
# Notificar por correo
|
||||||
|
#
|
||||||
|
# @return [ExceptionNotifier::EmailNotifier]
|
||||||
|
def email_notification
|
||||||
|
@email_notification ||= ExceptionNotifier::EmailNotifier.new(email_prefix: '[ERROR] ', sender_address: ENV['DEFAULT_FROM'], exception_recipients: ENV['EXCEPTION_TO'])
|
||||||
|
end
|
||||||
|
|
||||||
|
# La llave en la cache tiene en cuenta la excepción, el mensaje, la
|
||||||
|
# ruta del backtrace y los errores de JS
|
||||||
|
#
|
||||||
|
# @return [String]
|
||||||
|
def cache_key
|
||||||
|
@cache_key ||= [
|
||||||
|
exception.class.name,
|
||||||
|
Digest::SHA1.hexdigest(exception.message),
|
||||||
|
Digest::SHA1.hexdigest(backtrace&.first.to_s),
|
||||||
|
Digest::SHA1.hexdigest(options.dig(:data, :params, 'errors').to_s)
|
||||||
|
].join('/')
|
||||||
|
end
|
||||||
|
|
||||||
|
# Define si es una excepción de javascript o local
|
||||||
|
#
|
||||||
|
# @see BacktraceJob
|
||||||
|
# @return [Boolean]
|
||||||
|
def javascript?
|
||||||
|
@javascript ||= options.dig(:data, :javascript_backtrace).present?
|
||||||
|
end
|
||||||
|
|
||||||
|
# Título
|
||||||
|
#
|
||||||
|
# @return [String]
|
||||||
|
def title
|
||||||
|
@title ||= ''.dup.tap do |t|
|
||||||
|
t << "[#{exception.class}] " unless javascript?
|
||||||
|
t << exception.message
|
||||||
|
t << " [#{issue_data[:count]}]"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Descripción
|
||||||
|
#
|
||||||
|
# @return [String]
|
||||||
|
def description
|
||||||
|
@description ||= ''.dup.tap do |d|
|
||||||
|
d << request_section
|
||||||
|
d << javascript_section
|
||||||
|
d << javascript_footer
|
||||||
|
d << backtrace_section
|
||||||
|
d << data_section
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Comentario
|
||||||
|
#
|
||||||
|
# @return [String]
|
||||||
|
def body
|
||||||
|
@body ||= ''.dup.tap do |b|
|
||||||
|
b << request_section
|
||||||
|
b << javascript_footer
|
||||||
|
b << data_section
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Cadena de archivos donde se produjo el error
|
||||||
|
#
|
||||||
|
# @return [Array,Nil]
|
||||||
|
def backtrace
|
||||||
|
@backtrace ||= exception.backtrace ? clean_backtrace(exception) : nil
|
||||||
|
end
|
||||||
|
|
||||||
|
# Entorno del error
|
||||||
|
#
|
||||||
|
# @return [Hash]
|
||||||
|
def env
|
||||||
|
options[:env]
|
||||||
|
end
|
||||||
|
|
||||||
|
# Genera una petición a partir del entorno
|
||||||
|
#
|
||||||
|
# @return [ActionDispatch::Request]
|
||||||
|
def request
|
||||||
|
@request ||= ActionDispatch::Request.new(env) if env.present?
|
||||||
|
end
|
||||||
|
|
||||||
|
# Cliente de la API de Gitlab
|
||||||
|
#
|
||||||
|
# @return [GitlabApiClient]
|
||||||
|
def client
|
||||||
|
@client ||= GitlabApiClient.new
|
||||||
|
end
|
||||||
|
|
||||||
|
# Muestra información de la petición
|
||||||
|
#
|
||||||
|
# @return [String]
|
||||||
|
def request_section
|
||||||
|
return '' unless request
|
||||||
|
|
||||||
|
<<~REQUEST
|
||||||
|
|
||||||
|
# Request
|
||||||
|
|
||||||
|
```
|
||||||
|
#{request.request_method} #{url}
|
||||||
|
|
||||||
|
#{pp request.filtered_parameters}
|
||||||
|
```
|
||||||
|
|
||||||
|
REQUEST
|
||||||
|
end
|
||||||
|
|
||||||
|
# Muestra información de JavaScript
|
||||||
|
#
|
||||||
|
# @return [String]
|
||||||
|
def javascript_section
|
||||||
|
return '' unless javascript?
|
||||||
|
|
||||||
|
options.dig(:data, :params, 'errors')&.map do |error|
|
||||||
|
# Algunos errores no son excepciones (?)
|
||||||
|
error['type'] = 'undefined' if error['type'].blank?
|
||||||
|
|
||||||
|
<<~JAVASCRIPT
|
||||||
|
|
||||||
|
## #{error['type']}: #{error['message']}
|
||||||
|
|
||||||
|
```
|
||||||
|
#{Terminal::Table.new headings: error['backtrace'].first.keys, rows: error['backtrace'].map(&:values)}
|
||||||
|
```
|
||||||
|
|
||||||
|
JAVASCRIPT
|
||||||
|
end&.join
|
||||||
|
end
|
||||||
|
|
||||||
|
# Muestra información de la visita que generó el error en JS
|
||||||
|
#
|
||||||
|
# @return [String]
|
||||||
|
def javascript_footer
|
||||||
|
return '' unless javascript?
|
||||||
|
|
||||||
|
<<~JAVASCRIPT
|
||||||
|
|
||||||
|
#{user_agent}
|
||||||
|
|
||||||
|
<#{url}>
|
||||||
|
|
||||||
|
JAVASCRIPT
|
||||||
|
end
|
||||||
|
|
||||||
|
# Muestra el historial del error en Ruby
|
||||||
|
#
|
||||||
|
# @return [String]
|
||||||
|
def backtrace_section
|
||||||
|
return '' if javascript?
|
||||||
|
return '' unless backtrace
|
||||||
|
|
||||||
|
<<~BACKTRACE
|
||||||
|
|
||||||
|
## Backtrace
|
||||||
|
|
||||||
|
```
|
||||||
|
#{backtrace.join("\n")}
|
||||||
|
```
|
||||||
|
|
||||||
|
BACKTRACE
|
||||||
|
end
|
||||||
|
|
||||||
|
# Muestra datos extra de la visita
|
||||||
|
#
|
||||||
|
# @return [String]
|
||||||
|
def data_section
|
||||||
|
return '' unless options[:data]
|
||||||
|
|
||||||
|
<<~DATA
|
||||||
|
|
||||||
|
## Data
|
||||||
|
|
||||||
|
```
|
||||||
|
#{pp options[:data]}
|
||||||
|
```
|
||||||
|
|
||||||
|
DATA
|
||||||
|
end
|
||||||
|
|
||||||
|
# Obtiene el UA de este error
|
||||||
|
#
|
||||||
|
# @return [String]
|
||||||
|
def user_agent
|
||||||
|
@user_agent ||= options.dig(:data, :params, 'context', 'userAgent') if javascript?
|
||||||
|
@user_agent ||= request.headers['user-agent'] if request
|
||||||
|
@user_agent
|
||||||
|
end
|
||||||
|
|
||||||
|
# Obtiene la URL actual
|
||||||
|
#
|
||||||
|
# @return [String]
|
||||||
|
def url
|
||||||
|
@url ||= request&.url || options.dig(:data, :params, 'context', 'url')
|
||||||
|
end
|
||||||
|
end
|
17
app/lib/exception_notifier/gitlab_notifier.rb
Normal file
17
app/lib/exception_notifier/gitlab_notifier.rb
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module ExceptionNotifier
|
||||||
|
# Notifica las excepciones como incidencias en Gitlab
|
||||||
|
class GitlabNotifier
|
||||||
|
def initialize(_); end
|
||||||
|
|
||||||
|
# Recibe la excepción y empieza la tarea de notificación en segundo
|
||||||
|
# plano.
|
||||||
|
#
|
||||||
|
# @param [Exception]
|
||||||
|
# @param [Hash]
|
||||||
|
def call(exception, **options)
|
||||||
|
GitlabNotifierJob.perform_async(exception, **options)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
59
app/lib/gitlab_api_client.rb
Normal file
59
app/lib/gitlab_api_client.rb
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'httparty'
|
||||||
|
|
||||||
|
class GitlabApiClient
|
||||||
|
include HTTParty
|
||||||
|
|
||||||
|
# TODO: Hacer configurable por sitio
|
||||||
|
base_uri ENV.fetch('GITLAB_URI', 'https://0xacab.org')
|
||||||
|
# No seguir redirecciones. Si nos olvidamos https:// en la dirección,
|
||||||
|
# las redirecciones nos pueden llevar a cualquier lado y obtener
|
||||||
|
# resultados diferentes.
|
||||||
|
no_follow true
|
||||||
|
|
||||||
|
# Trae todos los proyectos. Como estamos usando un Project Token,
|
||||||
|
# siempre va a traer uno solo.
|
||||||
|
#
|
||||||
|
# @return [HTTParty::Response]
|
||||||
|
def projects
|
||||||
|
self.class.get('/api/v4/projects', { query: { membership: true }, headers: headers })
|
||||||
|
end
|
||||||
|
|
||||||
|
# Obtiene el identificador del proyecto
|
||||||
|
#
|
||||||
|
# @return [Integer]
|
||||||
|
def project_id
|
||||||
|
@project_id ||= ENV['GITLAB_PROJECT'] || projects&.first&.dig('id')
|
||||||
|
end
|
||||||
|
|
||||||
|
# Crea un issue
|
||||||
|
#
|
||||||
|
# @see https://docs.gitlab.com/ee/api/issues.html#new-issue
|
||||||
|
# @return [HTTParty::Response]
|
||||||
|
def new_issue(**args)
|
||||||
|
self.class.post("/api/v4/projects/#{project_id}/issues", { body: args, headers: headers })
|
||||||
|
end
|
||||||
|
|
||||||
|
# Modifica un issue
|
||||||
|
#
|
||||||
|
# @see https://docs.gitlab.com/ee/api/issues.html#edit-issue
|
||||||
|
# @return [HTTParty::Response]
|
||||||
|
def edit_issue(iid:, **args)
|
||||||
|
self.class.put("/api/v4/projects/#{project_id}/issues/#{iid}", { body: args, headers: headers })
|
||||||
|
end
|
||||||
|
|
||||||
|
# Crea un comentario
|
||||||
|
#
|
||||||
|
# @see https://docs.gitlab.com/ee/api/notes.html#create-new-issue-note
|
||||||
|
# @return [HTTParty::Response]
|
||||||
|
def new_note(iid:, **args)
|
||||||
|
self.class.post("/api/v4/projects/#{project_id}/issues/#{iid}/notes", { body: args, headers: headers })
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def headers(extra = {})
|
||||||
|
{ 'Authorization' => "Bearer #{ENV['GITLAB_TOKEN']}" }.merge(extra)
|
||||||
|
end
|
||||||
|
end
|
|
@ -28,7 +28,7 @@ class MetadataArray < MetadataTemplate
|
||||||
#
|
#
|
||||||
# @return [Array]
|
# @return [Array]
|
||||||
def document_value
|
def document_value
|
||||||
[super].flatten(1)
|
[super].flatten(1).compact
|
||||||
end
|
end
|
||||||
|
|
||||||
alias indexable_values value
|
alias indexable_values value
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<% unless @data[:_backtrace] %>
|
<% unless @data[:javascript_backtrace] %>
|
||||||
```
|
```
|
||||||
<%= raw @backtrace.join("\n") %>
|
<%= raw @backtrace.join("\n") %>
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<% if @data[:_backtrace] %>
|
<% if @data[:javascript_backtrace] %>
|
||||||
<% @data.dig(:params, 'errors')&.each do |error| %>
|
<% @data.dig(:params, 'errors')&.each do |error| %>
|
||||||
# <%= error['type'] %>: <%= error['message'] %>
|
# <%= error['type'] %>: <%= error['message'] %>
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
.form-group.markdown-content
|
.form-group.markdown-content
|
||||||
= label_tag "#{base}_#{attribute}", post_label_t(attribute, post: post)
|
= label_tag "#{base}_#{attribute}", post_label_t(attribute, post: post)
|
||||||
|
= render 'posts/attribute_feedback',
|
||||||
|
post: post, attribute: attribute, metadata: metadata
|
||||||
= text_area_tag "#{base}[#{attribute}]", metadata.value,
|
= text_area_tag "#{base}[#{attribute}]", metadata.value,
|
||||||
dir: dir, lang: locale,
|
dir: dir, lang: locale,
|
||||||
**field_options(attribute, metadata, class: 'content')
|
**field_options(attribute, metadata, class: 'content')
|
||||||
.editor.mt-1
|
.markdown-editor.mt-1
|
||||||
= render 'posts/attribute_feedback',
|
|
||||||
post: post, attribute: attribute, metadata: metadata
|
|
||||||
|
|
|
@ -147,14 +147,7 @@ Rails.application.configure do
|
||||||
}
|
}
|
||||||
config.action_mailer.default_options = { from: ENV.fetch('DEFAULT_FROM', "noreply@sutty.nl") }
|
config.action_mailer.default_options = { from: ENV.fetch('DEFAULT_FROM', "noreply@sutty.nl") }
|
||||||
|
|
||||||
config.middleware.use ExceptionNotification::Rack,
|
config.middleware.use ExceptionNotification::Rack, gitlab: {}
|
||||||
error_grouping: true,
|
|
||||||
email: {
|
|
||||||
email_prefix: '',
|
|
||||||
sender_address: ENV.fetch('DEFAULT_FROM', "noreply@sutty.nl"),
|
|
||||||
exception_recipients: ENV.fetch('EXCEPTION_TO', "errors@sutty.nl"),
|
|
||||||
normalize_subject: true
|
|
||||||
}
|
|
||||||
|
|
||||||
Rails.application.routes.default_url_options[:host] = "panel.#{ENV.fetch('SUTTY', 'sutty.nl')}"
|
Rails.application.routes.default_url_options[:host] = "panel.#{ENV.fetch('SUTTY', 'sutty.nl')}"
|
||||||
Rails.application.routes.default_url_options[:protocol] = 'https'
|
Rails.application.routes.default_url_options[:protocol] = 'https'
|
||||||
|
|
|
@ -26,7 +26,7 @@ if ENV['RAILS_ENV'] == 'production'
|
||||||
bind 'tcp://[::]:3100'
|
bind 'tcp://[::]:3100'
|
||||||
else
|
else
|
||||||
sutty = ENV.fetch('SUTTY', 'sutty.local')
|
sutty = ENV.fetch('SUTTY', 'sutty.local')
|
||||||
bind "ssl://[::]:3000?key=../sutty.local/domain/#{sutty}.key&cert=../sutty.local/domain/#{sutty}.crt"
|
bind "ssl://[::]:3000?key=/etc/ssl/private/#{sutty}.key&cert=/etc/ssl/certs/#{sutty}.crt"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Specifies the `environment` that Puma will run in.
|
# Specifies the `environment` that Puma will run in.
|
||||||
|
|
|
@ -56,8 +56,8 @@ development:
|
||||||
# Reference: https://webpack.js.org/configuration/dev-server/
|
# Reference: https://webpack.js.org/configuration/dev-server/
|
||||||
dev_server:
|
dev_server:
|
||||||
https:
|
https:
|
||||||
key: '../sutty.local/domain/sutty.local.key'
|
key: '/etc/ssl/private/sutty.local.key'
|
||||||
cert: '../sutty.local/domain/sutty.local.crt'
|
cert: '/etc/ssl/certs/sutty.local.crt'
|
||||||
# XXX: esto está hardcodeado, debería conseguirlo del ENV
|
# XXX: esto está hardcodeado, debería conseguirlo del ENV
|
||||||
host: sutty.local
|
host: sutty.local
|
||||||
port: 3035
|
port: 3035
|
||||||
|
|
10
ota.sh
Executable file
10
ota.sh
Executable file
|
@ -0,0 +1,10 @@
|
||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
|
||||||
|
cd /srv/http
|
||||||
|
|
||||||
|
for patch in /tmp/patches-${1}/*.patch; do
|
||||||
|
su -c "patch -Np 1 -i ${patch}" app && rm $patch
|
||||||
|
done
|
||||||
|
|
||||||
|
cat tmp/puma.pid | xargs -r kill -USR2
|
|
@ -110,7 +110,6 @@ class PostTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
test 'se puede cambiar la fecha' do
|
test 'se puede cambiar la fecha' do
|
||||||
assert_not @post.date.changed?
|
|
||||||
assert @post.date.valid?
|
assert @post.date.valid?
|
||||||
|
|
||||||
ex_date = @post.date.value
|
ex_date = @post.date.value
|
||||||
|
|
Loading…
Reference in a new issue