Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v1.0.1: 🐌 Mail #20

Merged
merged 5 commits into from
Jun 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ AWS_REGION=

# CDN for image uploads
IMAGES_CDN_HOST=

# Build notifications as part of CI
SLACK_WEBHOOK_URL=
3 changes: 0 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,3 @@ RUN bundle install --jobs 20 --retry 5

# Copy the main application.
COPY . ./

# Default command
ENTRYPOINT ['/app/robles/bin/robles']
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ gem 'concurrent-ruby', '~> 1.1'
# Interacting with github
gem 'octokit', '~> 4.18'

# Sending notifications to slack
gem 'slack-notifier', '~> 2.3', '>= 2.3.2'

group :development do
# For integration with VSCode
gem 'debase', '~> 0.2.4.1'
Expand Down
32 changes: 19 additions & 13 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,20 @@ GEM
public_suffix (>= 2.0.2, < 5.0)
ast (2.4.0)
aws-eventstream (1.1.0)
aws-partitions (1.313.0)
aws-sdk-core (3.95.0)
aws-partitions (1.325.0)
aws-sdk-core (3.97.1)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.239.0)
aws-sigv4 (~> 1.1)
jmespath (~> 1.0)
aws-sdk-kms (1.31.0)
aws-sdk-kms (1.33.0)
aws-sdk-core (~> 3, >= 3.71.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.64.0)
aws-sdk-core (~> 3, >= 3.83.0)
aws-sdk-s3 (1.67.1)
aws-sdk-core (~> 3, >= 3.96.1)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.1)
aws-sigv4 (1.1.3)
aws-sigv4 (1.1.4)
aws-eventstream (~> 1.0, >= 1.0.2)
backport (1.1.2)
benchmark (0.1.0)
Expand All @@ -40,7 +40,7 @@ GEM
multipart-post (>= 1.2, < 3)
git (1.7.0)
rchardet (~> 1.8)
i18n (1.8.2)
i18n (1.8.3)
concurrent-ruby (~> 1.0)
jaro_winkler (1.5.4)
jmespath (1.4.0)
Expand All @@ -55,31 +55,36 @@ GEM
faraday (>= 0.9)
sawyer (~> 0.8.0, >= 0.5.3)
parallel (1.19.1)
parser (2.7.1.2)
parser (2.7.1.3)
ast (~> 2.4.0)
public_suffix (4.0.5)
rainbow (3.0.0)
rake (13.0.1)
rchardet (1.8.0)
redcarpet (3.5.0)
reverse_markdown (1.4.0)
regexp_parser (1.7.0)
reverse_markdown (2.0.0)
nokogiri
rexml (3.2.4)
rubocop (0.81.0)
jaro_winkler (~> 1.5.1)
rubocop (0.85.0)
parallel (~> 1.10)
parser (>= 2.7.0.1)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.7)
rexml
rubocop-ast (>= 0.0.3)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 2.0)
rubocop-ast (0.0.3)
parser (>= 2.7.0.1)
ruby-debug-ide (0.7.2)
rake (>= 0.8.1)
ruby-progressbar (1.10.1)
sawyer (0.8.2)
addressable (>= 2.3.5)
faraday (> 0.8, < 2.0)
solargraph (0.39.7)
slack-notifier (2.3.2)
solargraph (0.39.8)
backport (~> 1.1)
benchmark
bundler (>= 1.17.2)
Expand All @@ -88,7 +93,7 @@ GEM
maruku (~> 0.7, >= 0.7.3)
nokogiri (~> 1.9, >= 1.9.1)
parser (~> 2.3)
reverse_markdown (~> 1.0, >= 1.0.5)
reverse_markdown (>= 1.0.5, < 3)
rubocop (~> 0.52)
thor (~> 1.0)
tilt (~> 2.0)
Expand Down Expand Up @@ -119,6 +124,7 @@ DEPENDENCIES
redcarpet (~> 3.5)
rubocop (~> 0.81)
ruby-debug-ide (~> 0.7.2)
slack-notifier (~> 2.3, >= 2.3.2)
solargraph (~> 0.39)
thor (~> 1.0, >= 1.0.1)
zeitwerk (~> 2.3)
Expand Down
5 changes: 5 additions & 0 deletions app/commands/robles_cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

# Overall CLI app for robles
class RoblesCli < Thor
# Ensures that invalid arguments etc result in a failure response to the shell
def self.exit_on_failure?
true
end

desc 'render', 'renders book'
option :'publish-file', type: :string, desc: 'Location of the publish.yaml file'
option :local, type: :boolean
Expand Down
1 change: 1 addition & 0 deletions app/lib/api/alexandria/book_uploader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ def conn
faraday.response(:logger, logger) do |logger|
logger.filter(/(Token token=\\\")(\w+)/, '\1[REMOVED]')
end
faraday.response(:raise_error)
faraday.token_auth(ALEXANDRIA_SERVICE_API_TOKEN)
faraday.adapter(Faraday.default_adapter)
end
Expand Down
1 change: 1 addition & 0 deletions app/lib/renderer/image_attributes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ def width_class(alt_text)
width_match = /width=(\d+)%/.match(alt_text)
return if width_match.blank?

# Convert width request to a class that's a multiple of 10
width = width_match[1].to_i.round(-1).clamp(0, 100)
"l-image-#{width}"
end
Expand Down
11 changes: 7 additions & 4 deletions app/lib/runner/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module Runner
# Base class with shared functionality
class Base
include Util::Logging
include Util::SlackNotifiable

def self.runner
return Runner::Ci.new if CI
Expand All @@ -23,16 +24,18 @@ def render(publish_file:, local: false)
book
end

def publish(publish_file:)
def publish(publish_file:) # rubocop:disable Metrics/MethodLength
publish_file ||= default_publish_file

parser = Parser::Publish.new(file: publish_file)
book = parser.parse
image_provider = ImageProvider::Provider.new(book: book)
image_provider.process
renderer = Renderer::Book.new(book: book, image_provider: image_provider)
renderer.render
Renderer::Book.new(book: book, image_provider: image_provider).render
Api::Alexandria::BookUploader.upload(book)
notify_success(book: book)
rescue StandardError => e
notify_failure(book: defined?(book) ? book : nil, details: e.full_message)
raise e
end

def lint(publish_file:, options: {})
Expand Down
119 changes: 119 additions & 0 deletions app/lib/util/slack_notifiable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# frozen_string_literal: true

module Util
# Adds methods that allow slack notifications
module SlackNotifiable # rubocop:disable Metrics/ModuleLength
extend ActiveSupport::Concern

SUCCESS_IMAGE_URL = 'https://wolverine.raywenderlich.com/v3-resources/razebot/images/object_textkit-book.png'
FAILURE_IMAGE_URL = 'https://wolverine.raywenderlich.com/v3-resources/razebot/images/object_errors.png'
ROBLES_CONTEXT_IMAGE_URL = 'https://wolverine.raywenderlich.com/v3-resources/razebot/images/object_box-of-books.png'

def notify_success(book:)
return unless notifiable?

notifier.post(blocks: success_blocks(book: book))
end

def notify_failure(book:, details: nil)
return unless notifiable?

notifier.post(blocks: failure_blocks(book: book, details: details || 'N/A'))
end

def notifiable?
SLACK_WEBHOOK_URL.present?
end

def notifier
@notifier ||= Slack::Notifier.new(SLACK_WEBHOOK_URL, channel: SLACK_CHANNEL, username: SLACK_USERNAME)
end

def success_blocks(book:)
[
intro_section(book: book,
message: ':white_check_mark: Book publication successful!',
image_url: SUCCESS_IMAGE_URL,
alt_text: 'Publication successful'),
{
type: 'divider'
},
context
]
end

def failure_blocks(book:, details:) # rubocop:disable Metrics/MethodLength
[
intro_section(book: book,
message: ':x: Book publication failed!',
image_url: FAILURE_IMAGE_URL,
alt_text: 'Publication failed'),
{
type: 'section',
text: {
type: 'mrkdwn',
text: "```#{details}```"
}
},
{
type: 'divider'
},
context
]
end

def standard_fields(book:) # rubocop:disable Metrics/MethodLength
[
{
type: 'mrkdwn',
text: "*Book*\n#{book&.title || '_unknown_'}"
},
{
type: 'mrkdwn',
text: "*SKU*\n`#{book&.sku || 'unknown'}`"
},
{
type: 'mrkdwn',
text: "*Edition*\n#{book&.edition || '_unknown_'}"
},
{
type: 'mrkdwn',
text: "*Environment*\n`#{ENVIRONMENT}`"
}
]
end

def intro_section(book:, message:, image_url:, alt_text:) # rubocop:disable Metrics/MethodLength
{
type: 'section',
text: {
type: 'mrkdwn',
text: message
},
fields: standard_fields(book: book),
accessory: {
type: 'image',
image_url: image_url,
alt_text: alt_text
}
}
end

def context # rubocop:disable Metrics/MethodLength
{
type: 'context',
elements: [
{
type: 'image',
image_url: ROBLES_CONTEXT_IMAGE_URL,
alt_text: 'robles via razebot'
},
{
type: 'mrkdwn',
text: 'This is a message sent from *robles* via *razebot*.'
}
]
}
end
end
end
3 changes: 3 additions & 0 deletions config/initialisers/environment.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# frozen_string_literal: true

ENVIRONMENT = ENV['ENV'] || 'development'
5 changes: 5 additions & 0 deletions config/initialisers/slack.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

SLACK_WEBHOOK_URL = ENV['SLACK_WEBHOOK_URL']
SLACK_CHANNEL = ENV['SLACK_CHANNEL'] || '#robles'
SLACK_USERNAME = ENV['SLACK_USERNAME'] || 'razebot'