Extensions Are Dead, Long Live Extensions!

SolidusConf 2019

alessandro.codes

github.com/aldesantis

medium.com/@aldesantis

Why extensions?

Indicator of health 🏥

Reduced overhead 💰

Ease of onboarding 🚀

The questions we get most often about Solidus are about the size, governance model and overall health of its extension ecosystem.

50+ extensions

180K+ lines of code

Where are we today?

6 core team members

40 hours in the week

😕

What we'll cover

Maintaining extensions 🛠

Extending extensions 🙆‍♂️

Governing extensions 👑

Advertising extensions 📣

 🛠
Maintaining extensions

Stale issues and PRs

Broken builds

Outdated docs

No changelogs

Inconsistent coding style

Insufficient tests

Outdated dependencies

Just the tip of the iceberg...

What can we do?

Designated maintainers

Implement new features

Triage issues and PRs

Improve tests

Upgrade dependencies

Maintain documentation

Maintainers will...

Gather feedback

Automate all the things!

Our goal is to minimize the human work required for maintaining extensions.

🤖

Readme template

Changelog generation

$ github_changelog_generator solidusio/solidus_auth_devise

PR reminders

Automatic upgrades

A few more tricks

One spec_helper to rule them all

ENV["RAILS_ENV"] ||= "test"

require File.expand_path("dummy/config/environment.rb", __dir__)

require "solidus_support/extension/feature_helper"

Dir[File.join(File.dirname(__FILE__), "support/**/*.rb")].each { |f| require f }
$ rake

Centralized CI

version: 2.1

orbs:
  ext: solidusio/extensions@volatile

jobs:
  run-specs-with-postgres:
    executor: ext/postgres
    steps:
      - ext/run-tests
  run-specs-with-mysql:
    executor: ext/mysql
    steps:
      - ext/run-tests

workflows:
  "Run specs on supported Solidus versions":
    jobs:
      - run-specs-with-postgres
      - run-specs-with-mysql
  "Weekly run specs against master":
    triggers:
      - schedule:
          cron: "0 0 * * 4"
    jobs:
      - run-specs-with-postgres
      - run-specs-with-mysql
$ gem install solidus_cmd
$ solidus extension my_extension

🙆‍♂️

Extending
extensions

module Spree
  class FeedProduct
    attr_reader :product

    def initialize(product)
      @product = product
    end

    def id
      product.id
    end

    def title
      product.name
    end

    # ...
  end
end

class_eval

Spree::FeedProduct.class_eval do
  def description
    product.description
  end
end

super ❌

Hard to debug

Very brittle

prepend

module AcmeStore
  module Spree
    module FeedProduct
      module AddDescription
        def description
          product.description
        end

        ::Spree::FeedProduct.prepend self
      end
    end
  end
end

super ✅

Module#ancestors

Still brittle

POROs

# app/models/acme_store/feed_product.rb
module AcmeStore
  class FeedProduct < Spree::FeedProduct
    def description
      product.description
    end
  end
end

# config/intitializers/solidus_product_feed.rb
SolidusProductFeed.configure do |config|
  config.feed_product_class = 'AcmeStore::FeedProduct'
end

super ✅

Clearly documented

Stable contract

One more thing...

The Event Bus

# Somewhere in an extension:
Spree::Event.fire(
  'subscription.renewed', 
  subscription: @subscription
)

# Somewhere in my app:
Spree::Event.subscribe 'subscription.renewed' do |event|
  subscription = event.payload[:subscription]
  SubscriptionsMailer.thank_you_email(subscription).deliver_now
end

Support for multiple adapters

Flexible subscribers

Extension-friendly

👑
Governing extensions

Unclear governance

solidus_virtual_gift_card

solidus_multi_domain

solidus_asset_variant_options

solidus_signifyd

solidus_avatax

solidusio

solidus_reviews

solidus_stripe

solidus_cmd

solidus_reports

solidus_graphql_api

solidusio-contrib

solidusio

solidusio-contrib

Critical functionality/integrations

Maintained by the core team

Proposed by the core team

Additional functionality

Maintained by the community

Proposed by the community

Unclear governance

We don't need...

Legacy code

Trivial customizations

Business-specific features

📣
Advertising extensions

Presentation matters

Too many channels

a single point of discovery,

quality metrics, and

a dashboard for maintainers.

We want to streamline the experience of looking for Solidus extensions by creating a unified experience that will provide:

(Coming in 2020!)

☠️
Extensions are dead.

We need to radically rethink how we use extensions and where we direct our maintenance efforts.

🙌
Long live extensions!

With the right mindset, we can create an extensions ecosystem that will save our users time and money.

🙏
We need you!

Volunteer as an extension maintainer

Contribute on GitHub

Improve our automation tools

Support us on OpenCollective

With your help, we can build the future of Solidus, a future that will continue to be

free,

open

and extensible.

Extensions Are Dead, Long Live Extensions!

By Alessandro Desantis

Extensions Are Dead, Long Live Extensions!

What is the true place of extensions in the Solidus ecosystem and what does their future look like? In this talk, I will walk you through the challenges Solidus extensions currently face and how we have decided to tackle them.

  • 1,043