summary refs log tree commit diff
diff options
context:
space:
mode:
authorKim Lindberger <kim.lindberger@gmail.com>2021-07-15 14:50:28 +0200
committerGitHub <noreply@github.com>2021-07-15 14:50:28 +0200
commit4dcf295417a17524978de4065b457f6ff101ed9e (patch)
treea859b2309cfc112db49cfb3fa8f98b825c08d361
parentad1437bb6dd6e2ef102ed0258107f463a7d0cc94 (diff)
parent60d78d7f1f218e19b1d0997ff4798c97a274cc47 (diff)
downloadnixpkgs-4dcf295417a17524978de4065b457f6ff101ed9e.tar
nixpkgs-4dcf295417a17524978de4065b457f6ff101ed9e.tar.gz
nixpkgs-4dcf295417a17524978de4065b457f6ff101ed9e.tar.bz2
nixpkgs-4dcf295417a17524978de4065b457f6ff101ed9e.tar.lz
nixpkgs-4dcf295417a17524978de4065b457f6ff101ed9e.tar.xz
nixpkgs-4dcf295417a17524978de4065b457f6ff101ed9e.tar.zst
nixpkgs-4dcf295417a17524978de4065b457f6ff101ed9e.zip
Merge pull request #129464 from talyz/discourse-plugins
discourse: Updates and fixes
-rw-r--r--nixos/modules/services/web-apps/discourse.nix19
-rw-r--r--nixos/modules/services/web-apps/discourse.xml43
-rw-r--r--pkgs/servers/web-apps/discourse/default.nix6
-rw-r--r--pkgs/servers/web-apps/discourse/plugins/all-plugins.nix6
-rw-r--r--pkgs/servers/web-apps/discourse/plugins/discourse-canned-replies/default.nix12
-rw-r--r--pkgs/servers/web-apps/discourse/plugins/discourse-github/Gemfile8
-rw-r--r--pkgs/servers/web-apps/discourse/plugins/discourse-github/Gemfile.lock12
-rw-r--r--pkgs/servers/web-apps/discourse/plugins/discourse-github/default.nix13
-rw-r--r--pkgs/servers/web-apps/discourse/plugins/discourse-github/gemset.nix30
-rw-r--r--pkgs/servers/web-apps/discourse/plugins/discourse-math/default.nix12
-rw-r--r--pkgs/servers/web-apps/discourse/plugins/discourse-solved/default.nix12
-rw-r--r--pkgs/servers/web-apps/discourse/plugins/discourse-spoiler-alert/default.nix12
-rw-r--r--pkgs/servers/web-apps/discourse/plugins/discourse-yearly-review/default.nix12
-rw-r--r--pkgs/servers/web-apps/discourse/rubyEnv/Gemfile.lock18
-rw-r--r--pkgs/servers/web-apps/discourse/rubyEnv/gemset.nix12
-rwxr-xr-xpkgs/servers/web-apps/discourse/update.py104
-rw-r--r--pkgs/top-level/all-packages.nix4
17 files changed, 250 insertions, 85 deletions
diff --git a/nixos/modules/services/web-apps/discourse.nix b/nixos/modules/services/web-apps/discourse.nix
index d3ae072f86a..8d5302ba267 100644
--- a/nixos/modules/services/web-apps/discourse.nix
+++ b/nixos/modules/services/web-apps/discourse.nix
@@ -475,21 +475,16 @@ in
       plugins = lib.mkOption {
         type = lib.types.listOf lib.types.package;
         default = [];
-        example = ''
-          [
-            (pkgs.fetchFromGitHub {
-              owner = "discourse";
-              repo = "discourse-spoiler-alert";
-              rev = "e200cfa571d252cab63f3d30d619b370986e4cee";
-              sha256 = "0ya69ix5g77wz4c9x9gmng6l25ghb5xxlx3icr6jam16q14dzc33";
-            })
+        example = lib.literalExample ''
+          with config.services.discourse.package.plugins; [
+            discourse-canned-replies
+            discourse-github
           ];
         '';
         description = ''
-          <productname>Discourse</productname> plugins to install as a
-          list of derivations. As long as a plugin supports the
-          standard install method, packaging it should only require
-          fetching its source with an appropriate fetcher.
+          Plugins to install as part of
+          <productname>Discourse</productname>, expressed as a list of
+          derivations.
         '';
       };
 
diff --git a/nixos/modules/services/web-apps/discourse.xml b/nixos/modules/services/web-apps/discourse.xml
index bae56242321..1d6866e7b35 100644
--- a/nixos/modules/services/web-apps/discourse.xml
+++ b/nixos/modules/services/web-apps/discourse.xml
@@ -262,9 +262,31 @@ services.discourse = {
     <para>
       You can install <productname>Discourse</productname> plugins
       using the <xref linkend="opt-services.discourse.plugins" />
-      option. As long as a plugin supports the standard install
-      method, packaging it should only require fetching its source
-      with an appropriate fetcher.
+      option. Pre-packaged plugins are provided in
+      <literal>&lt;your_discourse_package_here&gt;.plugins</literal>. If
+      you want the full suite of plugins provided through
+      <literal>nixpkgs</literal>, you can also set the <xref
+      linkend="opt-services.discourse.package" /> option to
+      <literal>pkgs.discourseAllPlugins</literal>.
+    </para>
+
+    <para>
+      Plugins can be built with the
+      <literal>&lt;your_discourse_package_here&gt;.mkDiscoursePlugin</literal>
+      function. Normally, it should suffice to provide a
+      <literal>name</literal> and <literal>src</literal> attribute. If
+      the plugin has Ruby dependencies, however, they need to be
+      packaged in accordance with the <link
+      xlink:href="https://nixos.org/manual/nixpkgs/stable/#developing-with-ruby">Developing
+      with Ruby</link> section of the Nixpkgs manual and the
+      appropriate gem options set in <literal>bundlerEnvArgs</literal>
+      (normally <literal>gemdir</literal> is sufficient). A plugin's
+      Ruby dependencies are listed in its
+      <filename>plugin.rb</filename> file as function calls to
+      <literal>gem</literal>. To construct the corresponding
+      <filename>Gemfile</filename>, run <command>bundle
+      init</command>, then add the <literal>gem</literal> lines to it
+      verbatim.
     </para>
 
     <para>
@@ -280,7 +302,10 @@ services.discourse = {
     <para>
       For example, to add the <link
       xlink:href="https://github.com/discourse/discourse-spoiler-alert">discourse-spoiler-alert</link>
-      plugin and disable it by default:
+      and <link
+      xlink:href="https://github.com/discourse/discourse-solved">discourse-solved</link>
+      plugins, and disable <literal>discourse-spoiler-alert</literal>
+      by default:
 
 <programlisting>
 services.discourse = {
@@ -301,13 +326,9 @@ services.discourse = {
     <link linkend="opt-services.discourse.mail.outgoing.passwordFile">passwordFile</link> = "/path/to/smtp_password_file";
   };
   <link linkend="opt-services.discourse.mail.incoming.enable">mail.incoming.enable</link> = true;
-  <link linkend="opt-services.discourse.mail.incoming.enable">plugins</link> = [
-    (pkgs.fetchFromGitHub {
-      owner = "discourse";
-      repo = "discourse-spoiler-alert";
-      rev = "e200cfa571d252cab63f3d30d619b370986e4cee";
-      sha256 = "0ya69ix5g77wz4c9x9gmng6l25ghb5xxlx3icr6jam16q14dzc33";
-    })
+  <link linkend="opt-services.discourse.mail.incoming.enable">plugins</link> = with config.services.discourse.package.plugins; [
+    discourse-spoiler-alert
+    discourse-solved
   ];
   <link linkend="opt-services.discourse.siteSettings">siteSettings</link> = {
     plugins = {
diff --git a/pkgs/servers/web-apps/discourse/default.nix b/pkgs/servers/web-apps/discourse/default.nix
index 5a3301040d3..72ea8a943dc 100644
--- a/pkgs/servers/web-apps/discourse/default.nix
+++ b/pkgs/servers/web-apps/discourse/default.nix
@@ -9,13 +9,13 @@
 }:
 
 let
-  version = "2.7.4";
+  version = "2.7.5";
 
   src = fetchFromGitHub {
     owner = "discourse";
     repo = "discourse";
     rev = "v${version}";
-    sha256 = "sha256-3cvrdWBXRM5F8qFEqbe8ru1U0wBqCkRxK7GAV0beJNk=";
+    sha256 = "sha256-OykWaiBAHcZy41i+aRzBHCRgwnfQUBijHjb+ofIk25M=";
   };
 
   runtimeDeps = [
@@ -64,7 +64,6 @@ let
       });
     in
       stdenv.mkDerivation (builtins.removeAttrs args [ "bundlerEnvArgs" ] // {
-        inherit name pname version src meta;
         pluginName = if name != null then name else "${pname}-${version}";
         phases = [ "unpackPhase" "installPhase" ];
         installPhase = ''
@@ -151,6 +150,7 @@ let
       brotli
       procps
       nodePackages.uglify-js
+      nodePackages.terser
     ];
 
     patches = [
diff --git a/pkgs/servers/web-apps/discourse/plugins/all-plugins.nix b/pkgs/servers/web-apps/discourse/plugins/all-plugins.nix
index e6640cbbe97..f64fbb137df 100644
--- a/pkgs/servers/web-apps/discourse/plugins/all-plugins.nix
+++ b/pkgs/servers/web-apps/discourse/plugins/all-plugins.nix
@@ -3,10 +3,10 @@ let
   callPackage = newScope args;
 in
 {
-  discourse-spoiler-alert = callPackage ./discourse-spoiler-alert {};
-  discourse-solved = callPackage ./discourse-solved {};
   discourse-canned-replies = callPackage ./discourse-canned-replies {};
-  discourse-math = callPackage ./discourse-math {};
   discourse-github = callPackage ./discourse-github {};
+  discourse-math = callPackage ./discourse-math {};
+  discourse-solved = callPackage ./discourse-solved {};
+  discourse-spoiler-alert = callPackage ./discourse-spoiler-alert {};
   discourse-yearly-review = callPackage ./discourse-yearly-review {};
 }
diff --git a/pkgs/servers/web-apps/discourse/plugins/discourse-canned-replies/default.nix b/pkgs/servers/web-apps/discourse/plugins/discourse-canned-replies/default.nix
index 05c153cd70b..558abec36f4 100644
--- a/pkgs/servers/web-apps/discourse/plugins/discourse-canned-replies/default.nix
+++ b/pkgs/servers/web-apps/discourse/plugins/discourse-canned-replies/default.nix
@@ -1,11 +1,17 @@
-{ mkDiscoursePlugin, fetchFromGitHub }:
+{ lib, mkDiscoursePlugin, fetchFromGitHub }:
 
 mkDiscoursePlugin {
   name = "discourse-canned-replies";
   src = fetchFromGitHub {
     owner = "discourse";
     repo = "discourse-canned-replies";
-    rev = "7ee748f18a276aca42185e2079c1d4cadeecdaf8";
-    sha256 = "0j10kxfr6v2rdd58smg2i7iac46z74qnnjk8b91jd1svazhis1ph";
+    rev = "e3f1de8928df5955b64994079b7e2073556e5456";
+    sha256 = "1g4fazm6cn6hbfd08mq2zhc6dgm4qj1r1f1amhbgxhk6qsxf42cd";
+  };
+  meta = with lib; {
+    homepage = "https://github.com/discourse/discourse-canned-replies";
+    maintainers = with maintainers; [ talyz ];
+    license = licenses.gpl2Only;
+    description = "Adds support for inserting a canned reply into the composer window via a UI";
   };
 }
diff --git a/pkgs/servers/web-apps/discourse/plugins/discourse-github/Gemfile b/pkgs/servers/web-apps/discourse/plugins/discourse-github/Gemfile
index f0205f4ff1d..7c0e7f435ae 100644
--- a/pkgs/servers/web-apps/discourse/plugins/discourse-github/Gemfile
+++ b/pkgs/servers/web-apps/discourse/plugins/discourse-github/Gemfile
@@ -1,3 +1,9 @@
-source 'https://rubygems.org'
+# frozen_string_literal: true
+
+source "https://rubygems.org"
+
+git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
+
+# gem "rails"
 gem 'sawyer', '0.8.2'
 gem 'octokit', '4.21.0'
diff --git a/pkgs/servers/web-apps/discourse/plugins/discourse-github/Gemfile.lock b/pkgs/servers/web-apps/discourse/plugins/discourse-github/Gemfile.lock
index f28833a35c0..0486ea1402b 100644
--- a/pkgs/servers/web-apps/discourse/plugins/discourse-github/Gemfile.lock
+++ b/pkgs/servers/web-apps/discourse/plugins/discourse-github/Gemfile.lock
@@ -1,21 +1,25 @@
 GEM
   remote: https://rubygems.org/
   specs:
-    addressable (2.7.0)
+    addressable (2.8.0)
       public_suffix (>= 2.0.2, < 5.0)
-    faraday (1.4.2)
+    faraday (1.5.0)
       faraday-em_http (~> 1.0)
       faraday-em_synchrony (~> 1.0)
       faraday-excon (~> 1.1)
+      faraday-httpclient (~> 1.0.1)
       faraday-net_http (~> 1.0)
       faraday-net_http_persistent (~> 1.1)
+      faraday-patron (~> 1.0)
       multipart-post (>= 1.2, < 3)
       ruby2_keywords (>= 0.0.4)
     faraday-em_http (1.0.0)
     faraday-em_synchrony (1.0.0)
     faraday-excon (1.1.0)
+    faraday-httpclient (1.0.1)
     faraday-net_http (1.0.1)
     faraday-net_http_persistent (1.1.0)
+    faraday-patron (1.0.0)
     multipart-post (2.1.1)
     octokit (4.21.0)
       faraday (>= 0.9)
@@ -27,11 +31,11 @@ GEM
       faraday (> 0.8, < 2.0)
 
 PLATFORMS
-  ruby
+  x86_64-linux
 
 DEPENDENCIES
   octokit (= 4.21.0)
   sawyer (= 0.8.2)
 
 BUNDLED WITH
-   2.1.4
+   2.2.20
diff --git a/pkgs/servers/web-apps/discourse/plugins/discourse-github/default.nix b/pkgs/servers/web-apps/discourse/plugins/discourse-github/default.nix
index e5d8cff0a9f..bb6d16bfe46 100644
--- a/pkgs/servers/web-apps/discourse/plugins/discourse-github/default.nix
+++ b/pkgs/servers/web-apps/discourse/plugins/discourse-github/default.nix
@@ -1,4 +1,4 @@
-{ mkDiscoursePlugin, fetchFromGitHub }:
+{ lib, mkDiscoursePlugin, fetchFromGitHub }:
 
 mkDiscoursePlugin {
   name = "discourse-github";
@@ -6,7 +6,14 @@ mkDiscoursePlugin {
   src = fetchFromGitHub {
     owner = "discourse";
     repo = "discourse-github";
-    rev = "151e353a5a1971157c70c2e2b0f56387f212a81f";
-    sha256 = "00kra6zd2k1f2vwcdvxnxnammzh72f5qxcqbb94m0z6maj598wdy";
+    rev = "154fd5ea597640c2259ce489b4ce75b48ac1973c";
+    sha256 = "0wb5p219z42rc035rnh2iwrbsj000nxa9shbmc325rzcg6xlhdhw";
   };
+  meta = with lib; {
+    homepage = "https://github.com/discourse/discourse-github";
+    maintainers = with maintainers; [ talyz ];
+    license = licenses.mit;
+    description = "Adds GitHub badges and linkback functionality";
+  };
+
 }
diff --git a/pkgs/servers/web-apps/discourse/plugins/discourse-github/gemset.nix b/pkgs/servers/web-apps/discourse/plugins/discourse-github/gemset.nix
index bad1f962957..ae20ec89521 100644
--- a/pkgs/servers/web-apps/discourse/plugins/discourse-github/gemset.nix
+++ b/pkgs/servers/web-apps/discourse/plugins/discourse-github/gemset.nix
@@ -5,21 +5,21 @@
     platforms = [];
     source = {
       remotes = ["https://rubygems.org"];
-      sha256 = "1fvchp2rhp2rmigx7qglf69xvjqvzq7x0g49naliw29r2bz656sy";
+      sha256 = "022r3m9wdxljpbya69y2i3h9g3dhhfaqzidf95m6qjzms792jvgp";
       type = "gem";
     };
-    version = "2.7.0";
+    version = "2.8.0";
   };
   faraday = {
-    dependencies = ["faraday-em_http" "faraday-em_synchrony" "faraday-excon" "faraday-net_http" "faraday-net_http_persistent" "multipart-post" "ruby2_keywords"];
+    dependencies = ["faraday-em_http" "faraday-em_synchrony" "faraday-excon" "faraday-httpclient" "faraday-net_http" "faraday-net_http_persistent" "faraday-patron" "multipart-post" "ruby2_keywords"];
     groups = ["default"];
     platforms = [];
     source = {
       remotes = ["https://rubygems.org"];
-      sha256 = "07mhk70gv453pg38md346470hknyhipdqppnplq706ll3k3lzb7v";
+      sha256 = "0gwbii45plm9bljk22bwzhzxrc5xid8qx24f54vrm74q3zaz00ah";
       type = "gem";
     };
-    version = "1.4.2";
+    version = "1.5.0";
   };
   faraday-em_http = {
     groups = ["default"];
@@ -51,6 +51,16 @@
     };
     version = "1.1.0";
   };
+  faraday-httpclient = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0fyk0jd3ks7fdn8nv3spnwjpzx2lmxmg2gh4inz3by1zjzqg33sc";
+      type = "gem";
+    };
+    version = "1.0.1";
+  };
   faraday-net_http = {
     groups = ["default"];
     platforms = [];
@@ -71,6 +81,16 @@
     };
     version = "1.1.0";
   };
+  faraday-patron = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "19wgsgfq0xkski1g7m96snv39la3zxz6x7nbdgiwhg5v82rxfb6w";
+      type = "gem";
+    };
+    version = "1.0.0";
+  };
   multipart-post = {
     groups = ["default"];
     platforms = [];
diff --git a/pkgs/servers/web-apps/discourse/plugins/discourse-math/default.nix b/pkgs/servers/web-apps/discourse/plugins/discourse-math/default.nix
index 8cf2a4abc0d..0e751c1dc54 100644
--- a/pkgs/servers/web-apps/discourse/plugins/discourse-math/default.nix
+++ b/pkgs/servers/web-apps/discourse/plugins/discourse-math/default.nix
@@ -1,11 +1,17 @@
-{ mkDiscoursePlugin, fetchFromGitHub }:
+{ lib, mkDiscoursePlugin, fetchFromGitHub }:
 
 mkDiscoursePlugin {
   name = "discourse-math";
   src = fetchFromGitHub {
     owner = "discourse";
     repo = "discourse-math";
-    rev = "143ddea4558ea9a1b3fd71635bc11e055763c8e7";
-    sha256 = "18pq5ybl3g34i39cpixc3nszvq8gx5yji58zlbbl6428mm011cbx";
+    rev = "aed0c83cee568d5239143bcf1df59c5fbe86b276";
+    sha256 = "1k6kpnhf8s2l0w9zr5pn3wvn8w0n3gwkv7qkv0mkhkzy246ag20z";
+  };
+  meta = with lib; {
+    homepage = "https://github.com/discourse/discourse-math";
+    maintainers = with maintainers; [ talyz ];
+    license = licenses.mit;
+    description = "Official MathJax support for Discourse";
   };
 }
diff --git a/pkgs/servers/web-apps/discourse/plugins/discourse-solved/default.nix b/pkgs/servers/web-apps/discourse/plugins/discourse-solved/default.nix
index c382a83d089..2d451418bdd 100644
--- a/pkgs/servers/web-apps/discourse/plugins/discourse-solved/default.nix
+++ b/pkgs/servers/web-apps/discourse/plugins/discourse-solved/default.nix
@@ -1,11 +1,17 @@
-{ mkDiscoursePlugin, fetchFromGitHub }:
+{ lib, mkDiscoursePlugin, fetchFromGitHub }:
 
 mkDiscoursePlugin {
   name = "discourse-solved";
   src = fetchFromGitHub {
     owner = "discourse";
     repo = "discourse-solved";
-    rev = "179611766d53974308e6f7def21836997c3c55fc";
-    sha256 = "sha256:1s77h42d3bv2lqw33akxh8ss482vxnz4d7qz6xicwqfwv34qjf03";
+    rev = "b96374bf4ab7e6d5cecb0761918b060a524eb9bf";
+    sha256 = "0zrv70p0wz93akpcj6gpwjkw7az3iz9bx4n2z630kyrlmxdbj32a";
+  };
+  meta = with lib; {
+    homepage = "https://github.com/discourse/discourse-solved";
+    maintainers = with maintainers; [ talyz ];
+    license = licenses.mit;
+    description = "Allow accepted answers on topics";
   };
 }
diff --git a/pkgs/servers/web-apps/discourse/plugins/discourse-spoiler-alert/default.nix b/pkgs/servers/web-apps/discourse/plugins/discourse-spoiler-alert/default.nix
index 8eba43e47e4..da47dbf182c 100644
--- a/pkgs/servers/web-apps/discourse/plugins/discourse-spoiler-alert/default.nix
+++ b/pkgs/servers/web-apps/discourse/plugins/discourse-spoiler-alert/default.nix
@@ -1,11 +1,17 @@
-{ mkDiscoursePlugin, fetchFromGitHub }:
+{ lib, mkDiscoursePlugin, fetchFromGitHub }:
 
 mkDiscoursePlugin {
   name = "discourse-spoiler-alert";
   src = fetchFromGitHub {
     owner = "discourse";
     repo = "discourse-spoiler-alert";
-    rev = "e200cfa571d252cab63f3d30d619b370986e4cee";
-    sha256 = "0ya69ix5g77wz4c9x9gmng6l25ghb5xxlx3icr6jam16q14dzc33";
+    rev = "ec14a2316da0a4fc055cfc21c68a60040188a2b4";
+    sha256 = "11n977gp8va7jkqa6i3ja279k4nmkhk5l4hg9xhs229450m1rnfp";
+  };
+  meta = with lib; {
+    homepage = "https://github.com/discourse/discourse-spoiler-alert";
+    maintainers = with maintainers; [ talyz ];
+    license = licenses.mit;
+    description = "Hide spoilers behind the spoiler-alert jQuery plugin";
   };
 }
diff --git a/pkgs/servers/web-apps/discourse/plugins/discourse-yearly-review/default.nix b/pkgs/servers/web-apps/discourse/plugins/discourse-yearly-review/default.nix
index 8e76123ae59..b20e16118c7 100644
--- a/pkgs/servers/web-apps/discourse/plugins/discourse-yearly-review/default.nix
+++ b/pkgs/servers/web-apps/discourse/plugins/discourse-yearly-review/default.nix
@@ -1,11 +1,17 @@
-{ mkDiscoursePlugin, fetchFromGitHub }:
+{ lib, mkDiscoursePlugin, fetchFromGitHub }:
 
 mkDiscoursePlugin {
   name = "discourse-yearly-review";
   src = fetchFromGitHub {
     owner = "discourse";
     repo = "discourse-yearly-review";
-    rev = "d1471bdb68945f55342e72e2c525b4f628419a50";
-    sha256 = "sha256:0xpl0l1vpih8xzb6y7k1lm72nj4ya99378viyhqfvpwzsn5pha2a";
+    rev = "95149df2282d62eebeb265b4895df15a2b259d03";
+    sha256 = "02n27al8n8cxz3dx4awlnd4qhv8a0fmjac57yyblmpviapja1wj7";
+  };
+  meta = with lib; {
+    homepage = "https://github.com/discourse/discourse-yearly-review";
+    maintainers = with maintainers; [ talyz ];
+    license = licenses.mit;
+    description = "Publishes an automated Year in Review topic";
   };
 }
diff --git a/pkgs/servers/web-apps/discourse/rubyEnv/Gemfile.lock b/pkgs/servers/web-apps/discourse/rubyEnv/Gemfile.lock
index af968cdf331..1f7a3641caa 100644
--- a/pkgs/servers/web-apps/discourse/rubyEnv/Gemfile.lock
+++ b/pkgs/servers/web-apps/discourse/rubyEnv/Gemfile.lock
@@ -186,11 +186,6 @@ GEM
     jwt (2.2.3)
     kgio (2.11.3)
     libv8-node (15.14.0.1)
-    libv8-node (15.14.0.1-arm64-darwin-20)
-    libv8-node (15.14.0.1-x86_64-darwin-18)
-    libv8-node (15.14.0.1-x86_64-darwin-19)
-    libv8-node (15.14.0.1-x86_64-darwin-20)
-    libv8-node (15.14.0.1-x86_64-linux)
     listen (3.5.1)
       rb-fsevent (~> 0.10, >= 0.10.3)
       rb-inotify (~> 0.9, >= 0.9.10)
@@ -214,7 +209,7 @@ GEM
       rack (>= 1.1.3)
     method_source (1.0.0)
     mini_mime (1.1.0)
-    mini_portile2 (2.5.1)
+    mini_portile2 (2.5.3)
     mini_racer (0.4.0)
       libv8-node (~> 15.14.0.0)
     mini_scheduler (0.13.0)
@@ -232,7 +227,7 @@ GEM
     multipart-post (2.1.1)
     mustache (1.1.1)
     nio4r (2.5.7)
-    nokogiri (1.11.5)
+    nokogiri (1.11.7)
       mini_portile2 (~> 2.5.0)
       racc (~> 1.4)
     nokogumbo (2.0.5)
@@ -267,7 +262,7 @@ GEM
     omniauth-twitter (1.4.0)
       omniauth-oauth (~> 1.1)
       rack
-    onebox (2.2.15)
+    onebox (2.2.17)
       addressable (~> 2.7.0)
       htmlentities (~> 4.3)
       multi_json (~> 1.11)
@@ -465,12 +460,7 @@ GEM
     zeitwerk (2.4.2)
 
 PLATFORMS
-  arm64-darwin-20
   ruby
-  x86_64-darwin-18
-  x86_64-darwin-19
-  x86_64-darwin-20
-  x86_64-linux
 
 DEPENDENCIES
   actionmailer (= 6.1.3.2)
@@ -600,4 +590,4 @@ DEPENDENCIES
   yaml-lint
 
 BUNDLED WITH
-   2.2.16
+   2.2.20
diff --git a/pkgs/servers/web-apps/discourse/rubyEnv/gemset.nix b/pkgs/servers/web-apps/discourse/rubyEnv/gemset.nix
index 974df1ed4ea..2fe2587d25f 100644
--- a/pkgs/servers/web-apps/discourse/rubyEnv/gemset.nix
+++ b/pkgs/servers/web-apps/discourse/rubyEnv/gemset.nix
@@ -1135,10 +1135,10 @@
     platforms = [];
     source = {
       remotes = ["https://rubygems.org"];
-      sha256 = "0xg1x4708a4pn2wk8qs2d8kfzzdyv9kjjachg2f1phsx62ap2rx2";
+      sha256 = "1ad0mli9rc0f17zw4ibp24dbj1y39zkykijsjmnzl4gwpg5s0j6k";
       type = "gem";
     };
-    version = "2.5.1";
+    version = "2.5.3";
   };
   mini_racer = {
     dependencies = ["libv8-node"];
@@ -1284,10 +1284,10 @@
     platforms = [];
     source = {
       remotes = ["https://rubygems.org"];
-      sha256 = "1i80ny61maqzqr1fq5wgpkijmh5j8abisrmhn16kv7mzmxqg5w0m";
+      sha256 = "1vrn31385ix5k9b0yalnlzv360isv6dincbcvi8psllnwz4sjxj9";
       type = "gem";
     };
-    version = "1.11.5";
+    version = "1.11.7";
   };
   nokogumbo = {
     dependencies = ["nokogiri"];
@@ -1414,10 +1414,10 @@
     platforms = [];
     source = {
       remotes = ["https://rubygems.org"];
-      sha256 = "0a76xmwikcg2lv8k2cawzhmi2hx7j145v12mbpriby6zff797z4g";
+      sha256 = "1swlysqwfc6mb7smv52yv12sd79dchjf2f6r738wrag0wp5hazqy";
       type = "gem";
     };
-    version = "2.2.15";
+    version = "2.2.17";
   };
   openssl = {
     groups = ["default"];
diff --git a/pkgs/servers/web-apps/discourse/update.py b/pkgs/servers/web-apps/discourse/update.py
index c401ab552bb..ae4dadfc3a7 100755
--- a/pkgs/servers/web-apps/discourse/update.py
+++ b/pkgs/servers/web-apps/discourse/update.py
@@ -1,5 +1,5 @@
 #!/usr/bin/env nix-shell
-#! nix-shell -i python3 -p bundix bundler nix-update python3 python3Packages.requests python3Packages.click python3Packages.click-log
+#! nix-shell -i python3 -p bundix bundler nix-update nix-universal-prefetch python3 python3Packages.requests python3Packages.click python3Packages.click-log
 
 import click
 import click_log
@@ -8,17 +8,22 @@ import tempfile
 import re
 import logging
 import subprocess
-import pathlib
+import os
+import stat
+import json
+import requests
 from distutils.version import LooseVersion
+from pathlib import Path
 from typing import Iterable
 
-import requests
 
 logger = logging.getLogger(__name__)
 
 
 class DiscourseRepo:
     version_regex = re.compile(r'^v\d+\.\d+\.\d+$')
+    _latest_commit_sha = None
+
     def __init__(self, owner: str = 'discourse', repo: str = 'discourse'):
         self.owner = owner
         self.repo = repo
@@ -35,6 +40,15 @@ class DiscourseRepo:
         versions.sort(key=lambda x: LooseVersion(x.replace('v', '')), reverse=True)
         return versions
 
+    @property
+    def latest_commit_sha(self) -> str:
+        if self._latest_commit_sha is None:
+            r = requests.get(f'https://api.github.com/repos/{self.owner}/{self.repo}/commits?per_page=1')
+            r.raise_for_status()
+            self._latest_commit_sha = r.json()[0]['sha']
+
+        return self._latest_commit_sha
+
     @staticmethod
     def rev2version(tag: str) -> str:
         """
@@ -57,19 +71,23 @@ class DiscourseRepo:
 
 def _call_nix_update(pkg, version):
     """calls nix-update from nixpkgs root dir"""
-    nixpkgs_path = pathlib.Path(__file__).parent / '../../../../'
+    nixpkgs_path = Path(__file__).parent / '../../../../'
     return subprocess.check_output(['nix-update', pkg, '--version', version], cwd=nixpkgs_path)
 
 
+def _nix_eval(expr: str):
+    nixpkgs_path = Path(__file__).parent / '../../../../'
+    return json.loads(subprocess.check_output(['nix', 'eval', '--json', f'(with import {nixpkgs_path} {{}}; {expr})'], text=True))
+
+
 def _get_current_package_version(pkg: str):
-    nixpkgs_path = pathlib.Path(__file__).parent / '../../../../'
-    return subprocess.check_output(['nix', 'eval', '--raw', f'nixpkgs.{pkg}.version'], text=True)
+    return _nix_eval(f'{pkg}.version')
 
 
 def _diff_file(filepath: str, old_version: str, new_version: str):
     repo = DiscourseRepo()
 
-    current_dir = pathlib.Path(__file__).parent
+    current_dir = Path(__file__).parent
 
     old = repo.get_file(filepath, 'v' + old_version)
     new = repo.get_file(filepath, 'v' + new_version)
@@ -148,17 +166,87 @@ def update(rev):
     version = repo.rev2version(rev)
     logger.debug(f"Using version {version}")
 
-    rubyenv_dir = pathlib.Path(__file__).parent / "rubyEnv"
+    rubyenv_dir = Path(__file__).parent / "rubyEnv"
 
     for fn in ['Gemfile.lock', 'Gemfile']:
         with open(rubyenv_dir / fn, 'w') as f:
             f.write(repo.get_file(fn, rev))
 
     subprocess.check_output(['bundle', 'lock'], cwd=rubyenv_dir)
+    for platform in ['arm64-darwin-20', 'x86_64-darwin-18',
+                     'x86_64-darwin-19', 'x86_64-darwin-20',
+                     'x86_64-linux']:
+        subprocess.check_output(['bundle', 'lock', '--remove-platform', platform], cwd=rubyenv_dir)
     subprocess.check_output(['bundix'], cwd=rubyenv_dir)
 
     _call_nix_update('discourse', repo.rev2version(rev))
 
+@cli.command()
+def update_plugins():
+    """Update plugins to their latest revision.
+
+    """
+    plugins = [
+        {'name': 'discourse-canned-replies'},
+        {'name': 'discourse-github'},
+        {'name': 'discourse-math'},
+        {'name': 'discourse-solved'},
+        {'name': 'discourse-spoiler-alert'},
+        {'name': 'discourse-yearly-review'},
+    ]
+
+    for plugin in plugins:
+        fetcher = plugin.get('fetcher') or "fetchFromGitHub"
+        owner = plugin.get('owner') or "discourse"
+        name = plugin.get('name')
+        repo_name = plugin.get('repo_name') or name
+
+        repo = DiscourseRepo(owner=owner, repo=repo_name)
+        prev_commit_sha = _nix_eval(f'discourse.plugins.{name}.src.rev')
+
+        if prev_commit_sha == repo.latest_commit_sha:
+            click.echo(f'Plugin {name} is already at the latest revision')
+            continue
+
+        filename = _nix_eval(f'builtins.unsafeGetAttrPos "src" discourse.plugins.{name}')['file']
+        prev_hash = _nix_eval(f'discourse.plugins.{name}.src.outputHash')
+        new_hash = subprocess.check_output([
+            'nix-universal-prefetch', fetcher,
+            '--owner', owner,
+            '--repo', repo_name,
+            '--rev', repo.latest_commit_sha,
+        ], text=True).strip("\n")
+
+        click.echo(f"Update {name}, {prev_commit_sha} -> {repo.latest_commit_sha} in {filename}")
+
+        with open(filename, 'r+') as f:
+            content = f.read()
+            content = content.replace(prev_commit_sha, repo.latest_commit_sha)
+            content = content.replace(prev_hash, new_hash)
+            f.seek(0)
+            f.write(content)
+            f.truncate()
+
+        rubyenv_dir = Path(filename).parent
+        gemfile = rubyenv_dir / "Gemfile"
+        gemfile_text = ''
+        for line in repo.get_file('plugin.rb', repo.latest_commit_sha).splitlines():
+            if 'gem ' in line:
+                gemfile_text = gemfile_text + line + os.linesep
+
+        if len(gemfile_text) > 0:
+            if os.path.isfile(gemfile):
+                os.remove(gemfile)
+
+            subprocess.check_output(['bundle', 'init'], cwd=rubyenv_dir)
+            os.chmod(gemfile, stat.S_IREAD | stat.S_IWRITE | stat.S_IRGRP | stat.S_IROTH)
+
+            with open(gemfile, 'a') as f:
+                f.write(gemfile_text)
+
+            subprocess.check_output(['bundle', 'lock', '--update'], cwd=rubyenv_dir)
+            subprocess.check_output(['bundix'], cwd=rubyenv_dir)
+
 
 if __name__ == '__main__':
     cli()
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 5d0d24b0862..b9c6fb0d95e 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -2487,6 +2487,10 @@ in
 
   discourse = callPackage ../servers/web-apps/discourse { };
 
+  discourseAllPlugins = discourse.override {
+    plugins = lib.filter (p: p ? pluginName) (builtins.attrValues discourse.plugins);
+  };
+
   discourse-mail-receiver = callPackage ../servers/web-apps/discourse/mail_receiver { };
 
   discocss = callPackage ../tools/misc/discocss { };