push sheeet
Some checks failed
Periodic Merges (6h) / master → staging-nixos (push) Failing after 12m50s
Periodic Merges (6h) / master → staging-next (push) Failing after 12m54s
Periodic Merges (24h) / merge-base(master,staging) → haskell-updates (push) Failing after 11m54s
Periodic Merges (6h) / staging-next → staging (push) Failing after 12m13s
Periodic Merges (24h) / staging-next-25.05 → staging-25.05 (push) Failing after 13m24s
Periodic Merges (24h) / release-25.05 → staging-next-25.05 (push) Failing after 14m28s

This commit is contained in:
Dark Steveneq
2025-10-09 14:15:47 +02:00
commit 646b892680
49168 changed files with 5897842 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
diff --git a/app/models/global_setting.rb b/app/models/global_setting.rb
index 6e06e18039..b2bef31fe2 100644
--- a/app/models/global_setting.rb
+++ b/app/models/global_setting.rb
@@ -255,6 +255,7 @@ class GlobalSetting
domain: GlobalSetting.smtp_domain,
user_name: GlobalSetting.smtp_user_name,
password: GlobalSetting.smtp_password,
+ ca_file: "/etc/ssl/certs/ca-certificates.crt",
enable_starttls_auto: GlobalSetting.smtp_enable_start_tls,
open_timeout: GlobalSetting.smtp_open_timeout,
read_timeout: GlobalSetting.smtp_read_timeout,

View File

@@ -0,0 +1,48 @@
diff --git a/lib/tasks/admin.rake b/lib/tasks/admin.rake
index 37ef651f2b..b775129498 100644
--- a/lib/tasks/admin.rake
+++ b/lib/tasks/admin.rake
@@ -107,3 +107,43 @@ task "admin:create" => :environment do
end
end
+
+desc "Creates a forum administrator noninteractively"
+task "admin:create_noninteractively" => :environment do
+ email = ENV["ADMIN_EMAIL"]
+ existing_user = User.find_by_email(email)
+
+ # check if user account already exixts
+ if existing_user
+ admin = existing_user
+ else
+ # create new user
+ admin = User.new
+ end
+
+ admin.email = email
+ admin.name = ENV["ADMIN_NAME"]
+ admin.username = ENV["ADMIN_USERNAME"]
+
+ password = ENV["ADMIN_PASSWORD"]
+ unless admin.confirm_password?(password)
+ admin.password = password
+ puts "Admin password set!"
+ end
+
+ admin.active = true
+
+ # save/update user account
+ saved = admin.save
+ raise admin.errors.full_messages.join("\n") unless saved
+
+ puts "Account created successfully with username #{admin.username}" unless existing_user
+
+ # grant admin privileges
+ admin.grant_admin!
+ if admin.trust_level < 1
+ admin.change_trust_level!(1)
+ end
+ admin.email_tokens.update_all confirmed: true
+ admin.activate
+end

View File

@@ -0,0 +1,13 @@
diff --git a/lib/tasks/assets.rake b/lib/tasks/assets.rake
index 9608297789..5487490915 100644
--- a/lib/tasks/assets.rake
+++ b/lib/tasks/assets.rake
@@ -36,7 +36,7 @@ task "assets:precompile:build" do
if only_ember_precompile_build_remaining
exec "#{compile_command}"
elsif only_assets_precompile_remaining
- exec "#{compile_command} && SKIP_EMBER_CLI_COMPILE=1 bin/rake assets:precompile"
+ exec "#{compile_command} && SKIP_EMBER_CLI_COMPILE=1 bundle exec rake assets:precompile"
else
system compile_command, exception: true
EmberCli.clear_cache!

View File

@@ -0,0 +1,13 @@
diff --git a/lib/plugin/instance.rb b/lib/plugin/instance.rb
index 8482ff0210..826d111d65 100644
--- a/lib/plugin/instance.rb
+++ b/lib/plugin/instance.rb
@@ -455,7 +455,7 @@ class Plugin::Instance
end
def auto_generated_path
- File.dirname(path) << "/auto_generated"
+ "#{Rails.root}/public/assets/auto_generated_plugin_assets/#{name}"
end
def after_initialize(&block)

View File

@@ -0,0 +1,452 @@
{
stdenv,
pkgs,
makeWrapper,
runCommand,
lib,
writeShellScript,
fetchFromGitHub,
bundlerEnv,
callPackage,
nixosTests,
ruby_3_3,
gzip,
gnutar,
git,
cacert,
util-linux,
gawk,
net-tools,
imagemagick,
optipng,
pngquant,
libjpeg,
jpegoptim,
gifsicle,
jhead,
oxipng,
libpsl,
redis,
postgresql,
which,
brotli,
procps,
rsync,
icu,
pnpm_9,
svgo,
nodejs,
jq,
moreutils,
terser,
uglify-js,
plugins ? [ ],
}:
let
version = "3.4.7";
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse";
rev = "v${version}";
sha256 = "sha256-vidv5aa2r1YOcnvkqrk7ttuIk1bN5Ct7kMANl8kpEm0=";
};
ruby = ruby_3_3;
runtimeDeps = [
# For backups, themes and assets
rubyEnv.wrappedRuby
rsync
gzip
gnutar
git
brotli
nodejs
# Misc required system utils
which
procps # For ps and kill
util-linux # For renice
gawk
net-tools # For hostname
# Image optimization
imagemagick
optipng
oxipng
pngquant
libjpeg
jpegoptim
gifsicle
svgo
jhead
];
runtimeEnv = {
HOME = "/run/discourse/home";
RAILS_ENV = "production";
UNICORN_LISTENER = "/run/discourse/sockets/unicorn.sock";
};
mkDiscoursePlugin =
{
name ? null,
pname ? null,
version ? null,
meta ? null,
bundlerEnvArgs ? { },
preserveGemsDir ? false,
src,
...
}@args:
let
rubyEnv = bundlerEnv (
bundlerEnvArgs
// {
inherit
name
pname
version
ruby
;
}
);
in
stdenv.mkDerivation (
removeAttrs args [ "bundlerEnvArgs" ]
// {
pluginName = if name != null then name else "${pname}-${version}";
dontConfigure = true;
dontBuild = true;
installPhase = ''
runHook preInstall
mkdir -p $out
cp -r * $out/
''
+ lib.optionalString (bundlerEnvArgs != { }) (
if preserveGemsDir then
''
cp -r ${rubyEnv}/lib/ruby/gems/* $out/gems/
''
else
''
if [[ -e $out/gems ]]; then
echo "Warning: The repo contains a 'gems' directory which will be removed!"
echo " If you need to preserve it, set 'preserveGemsDir = true'."
rm -r $out/gems
fi
ln -sf ${rubyEnv}/lib/ruby/gems $out/gems
''
+ ''
runHook postInstall
''
);
}
);
rake =
runCommand "discourse-rake"
{
nativeBuildInputs = [ makeWrapper ];
}
''
mkdir -p $out/bin
makeWrapper ${rubyEnv}/bin/rake $out/bin/discourse-rake \
${
lib.concatStrings (lib.mapAttrsToList (name: value: "--set ${name} '${value}' ") runtimeEnv)
} \
--prefix PATH : ${lib.makeBinPath runtimeDeps} \
--set RAKEOPT '-f ${discourse}/share/discourse/Rakefile' \
--chdir '${discourse}/share/discourse'
'';
rubyEnv = bundlerEnv {
name = "discourse-ruby-env-${version}";
inherit version ruby;
gemdir = ./rubyEnv;
gemset =
let
gems = import ./rubyEnv/gemset.nix;
in
gems
// {
mini_racer = gems.mini_racer // {
buildInputs = [ icu ];
dontBuild = false;
NIX_LDFLAGS = "-licui18n";
};
libv8-node =
let
noopScript = writeShellScript "noop" "exit 0";
linkFiles = writeShellScript "link-files" ''
cd ../..
mkdir -p vendor/v8/${stdenv.hostPlatform.system}/libv8/obj/
ln -s "${nodejs.libv8}/lib/libv8.a" vendor/v8/${stdenv.hostPlatform.system}/libv8/obj/libv8_monolith.a
ln -s ${nodejs.libv8}/include vendor/v8/include
mkdir -p ext/libv8-node
echo '--- !ruby/object:Libv8::Node::Location::Vendor {}' >ext/libv8-node/.location.yml
'';
in
gems.libv8-node
// {
dontBuild = false;
postPatch = ''
cp ${noopScript} libexec/build-libv8
cp ${noopScript} libexec/build-monolith
cp ${noopScript} libexec/download-node
cp ${noopScript} libexec/extract-node
cp ${linkFiles} libexec/inject-libv8
'';
};
mini_suffix = gems.mini_suffix // {
propagatedBuildInputs = [ libpsl ];
dontBuild = false;
# Use our libpsl instead of the vendored one, which isn't
# available for aarch64. It has to be called
# libpsl.x86_64.so or it isn't found.
postPatch = ''
cp $(readlink -f ${lib.getLib libpsl}/lib/libpsl.so) vendor/libpsl.x86_64.so
'';
};
};
groups = [
"default"
"assets"
"development"
"test"
];
};
assets = stdenv.mkDerivation {
pname = "discourse-assets";
inherit version src;
pnpmDeps = pnpm_9.fetchDeps {
pname = "discourse-assets";
inherit version src;
fetcherVersion = 1;
hash = "sha256-WyRBnuKCl5NJLtqy3HK/sJcrpMkh0PjbasGPNDV6+7Y=";
};
nativeBuildInputs = runtimeDeps ++ [
postgresql
redis
uglify-js
terser
jq
moreutils
nodejs
pnpm_9.configHook
];
outputs = [
"out"
"javascripts"
"node_modules"
];
patches = [
# Use the Ruby API version in the plugin gem path, to match the
# one constructed by bundlerEnv
./plugin_gem_api_version.patch
# Change the path to the auto generated plugin assets, which
# defaults to the plugin's directory and isn't writable at the
# time of asset generation
./auto_generated_path.patch
# Fix the rake command used to recursively execute itself in the
# assets precompilation task.
./assets_rake_command.patch
# Little does he know, so he decided there is no need to generate the
# theme-transpiler over and over again. Which at the same time allows the removal
# of javascript devDependencies from the runtime environment.
./prebuild-theme-transpiler.patch
];
env.RAILS_ENV = "production";
# We have to set up an environment that is close enough to
# production ready or the assets:precompile task refuses to
# run. This means that Redis and PostgreSQL has to be running and
# database migrations performed.
preBuild = ''
# Patch before running postinstall hook script
patchShebangs node_modules/
patchShebangs --build app/assets/javascripts
export SSL_CERT_FILE=${cacert}/etc/ssl/certs/ca-bundle.crt
redis-server >/dev/null &
initdb -A trust $NIX_BUILD_TOP/postgres >/dev/null
postgres -D $NIX_BUILD_TOP/postgres -k $NIX_BUILD_TOP >/dev/null &
export PGHOST=$NIX_BUILD_TOP
echo "Waiting for Redis and PostgreSQL to be ready.."
while ! redis-cli --scan >/dev/null || ! psql -l >/dev/null; do
sleep 0.1
done
psql -d postgres -tAc 'CREATE USER "discourse"'
psql -d postgres -tAc 'CREATE DATABASE "discourse" OWNER "discourse"'
psql 'discourse' -tAc "CREATE EXTENSION IF NOT EXISTS pg_trgm"
psql 'discourse' -tAc "CREATE EXTENSION IF NOT EXISTS hstore"
${lib.concatMapStringsSep "\n" (p: "ln -sf ${p} plugins/${p.pluginName or ""}") plugins}
bundle exec rake db:migrate >/dev/null
chmod -R +w tmp
'';
buildPhase = ''
runHook preBuild
bundle exec rake assets:precompile
runHook postBuild
'';
installPhase = ''
runHook preInstall
mv public/assets $out
mv node_modules $node_modules
rm -r app/assets/javascripts/plugins
mv app/assets/javascripts $javascripts
ln -sf /run/discourse/assets/javascripts/plugins $javascripts/plugins
runHook postInstall
'';
# The node_modules output by design has broken symlinks, as it refers to the source code.
# They are resolved in the primary discourse derivation.
dontCheckForBrokenSymlinks = true;
};
discourse = stdenv.mkDerivation {
pname = "discourse";
inherit version src;
buildInputs = [
rubyEnv
rubyEnv.wrappedRuby
rubyEnv.bundler
];
patches = [
# Load a separate NixOS site settings file
./nixos_defaults.patch
# Add a noninteractive admin creation task
./admin_create.patch
# Add the path to the CA cert bundle to make TLS work
./action_mailer_ca_cert.patch
# Log Unicorn messages to the journal and make request timeout
# configurable
./unicorn_logging_and_timeout.patch
# Use the Ruby API version in the plugin gem path, to match the
# one constructed by bundlerEnv
./plugin_gem_api_version.patch
# Change the path to the auto generated plugin assets, which
# defaults to the plugin's directory and isn't writable at the
# time of asset generation
./auto_generated_path.patch
# Make sure the notification email setting applies
./notification_email.patch
# Little does he know, so he decided there is no need to generate the
# theme-transpiler over and over again. Which at the same time allows the removal
# of javascript devDependencies from the runtime environment.
./prebuild-theme-transpiler.patch
];
postPatch = ''
# Always require lib-files and application.rb through their store
# path, not their relative state directory path. This gets rid of
# warnings and means we don't have to link back to lib from the
# state directory.
find config -type f -name "*.rb" -execdir \
sed -Ei "s,(\.\./)+(lib|app)/,$out/share/discourse/\2/," {} \;
find config -maxdepth 1 -type f -name "*.rb" -execdir \
sed -Ei "s,require_relative (\"|')([[:alnum:]].*)(\"|'),require_relative '$out/share/discourse/config/\2'," {} \;
'';
buildPhase = ''
runHook preBuild
mv config config.dist
mv public public.dist
runHook postBuild
'';
installPhase = ''
runHook preInstall
mkdir -p $out/share
cp -r . $out/share/discourse
rm -r $out/share/discourse/log
ln -sf /var/log/discourse $out/share/discourse/log
ln -sf /var/lib/discourse/tmp $out/share/discourse/tmp
ln -sf /run/discourse/config $out/share/discourse/config
ln -sf /run/discourse/public $out/share/discourse/public
ln -sf ${assets.node_modules} $out/share/discourse/node_modules
ln -sf ${assets} $out/share/discourse/public.dist/assets
rm -r $out/share/discourse/app/assets/javascripts
# This needs to be copied because it contains symlinks to node_modules
cp -r ${assets.javascripts} $out/share/discourse/app/assets/javascripts
${lib.concatMapStringsSep "\n" (
p: "ln -sf ${p} $out/share/discourse/plugins/${p.pluginName or ""}"
) plugins}
runHook postInstall
'';
passthru = {
inherit
rubyEnv
runtimeEnv
runtimeDeps
rake
mkDiscoursePlugin
assets
;
inherit (pkgs)
discourseAllPlugins
;
enabledPlugins = plugins;
plugins = callPackage ./plugins/all-plugins.nix { inherit mkDiscoursePlugin; };
ruby = rubyEnv.wrappedRuby;
tests = {
inherit (nixosTests)
discourse
discourseAllPlugins
;
};
};
meta = with lib; {
homepage = "https://www.discourse.org/";
platforms = platforms.linux;
maintainers = with maintainers; [ talyz ];
license = licenses.gpl2Plus;
description = "Open source discussion platform";
};
};
in
discourse

View File

@@ -0,0 +1,24 @@
To update discourse, do the following:
1. Switch to and work from the `master` branch and the directory this
file is in.
2. Run `./update.py print-diffs` and update the nginx settings and
backend settings accordingly. If you don't know how to, ask for
help - do not skip this step!
3. Run `./update.py update`.
4. Run `nix build -L -f ../../../../ discourse.tests` to make sure the
update works. Also test manually, if possible.
5. If the update works, commit it. If not, apply necessary fixes and
commit. No manual fixes that would be overwritten by the
`./update.py` script should be committed - the script should be
fixed instead.
6. Run `./update.py update-mail-receiver`. If there's an update, do
step 4 and 5 again.
7. Run `./update.py update-plugins`.
8. Run `nix build -L -f ../../../../ discourseAllPlugins.tests` to
make sure the plugins build and discourse starts with them. Also
test manually, if possible.
9. If the update works, commit it. If not, apply necessary fixes and
commit. No manual fixes that would be overwritten by the
`./update.py` script should be committed - the script should be
fixed instead.

View File

@@ -0,0 +1,13 @@
diff --git a/app/models/site_setting.rb b/app/models/site_setting.rb
index a6641f967a..a45353504a 100644
--- a/app/models/site_setting.rb
+++ b/app/models/site_setting.rb
@@ -21,6 +21,8 @@ class SiteSetting < ActiveRecord::Base
end
end
+ load_settings(File.join(Rails.root, 'config', 'nixos_site_settings.json'))
+
setup_deprecated_methods
client_settings << :available_locales

View File

@@ -0,0 +1,18 @@
diff --git a/db/fixtures/990_settings.rb b/db/fixtures/990_settings.rb
deleted file mode 100644
index 6f21e58813..0000000000
--- a/db/fixtures/990_settings.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-# frozen_string_literal: true
-
-if SiteSetting.notification_email == SiteSetting.defaults[:notification_email]
- # don't crash for invalid hostname, which is possible in dev
- begin
- SiteSetting.notification_email = "noreply@#{Discourse.current_hostname}"
- rescue Discourse::InvalidParameters
- if Rails.env.production?
- STDERR.puts "WARNING: Discourse hostname: #{Discourse.current_hostname} is not a valid domain for emails!"
- end
- end
-end

View File

@@ -0,0 +1,13 @@
diff --git a/lib/plugin_gem.rb b/lib/plugin_gem.rb
index 49882b2cd9..96672df2ea 100644
--- a/lib/plugin_gem.rb
+++ b/lib/plugin_gem.rb
@@ -4,7 +4,7 @@ module PluginGem
def self.load(path, name, version, opts = nil)
opts ||= {}
- gems_path = File.dirname(path) + "/gems/#{RUBY_VERSION}"
+ gems_path = File.dirname(path) + "/gems/#{Gem.ruby_api_version}"
spec_path = gems_path + "/specifications"

View File

@@ -0,0 +1,4 @@
Run the nixpkgs/pkgs/servers/web-apps/discourse/update.py script to
update plugins! See the Plugins section of the Discourse chapter in
the NixOS manual (https://nixos.org/manual/nixos/unstable/index.html#module-services-discourse)
for more info.

View File

@@ -0,0 +1,27 @@
{ mkDiscoursePlugin, newScope, ... }@args:
let
callPackage = newScope args;
in
{
discourse-assign = callPackage ./discourse-assign { };
discourse-bbcode-color = callPackage ./discourse-bbcode-color { };
discourse-calendar = callPackage ./discourse-calendar { };
discourse-canned-replies = callPackage ./discourse-canned-replies { };
discourse-chat-integration = callPackage ./discourse-chat-integration { };
discourse-checklist = callPackage ./discourse-checklist { };
discourse-data-explorer = callPackage ./discourse-data-explorer { };
discourse-docs = callPackage ./discourse-docs { };
discourse-github = callPackage ./discourse-github { };
discourse-ldap-auth = callPackage ./discourse-ldap-auth { };
discourse-math = callPackage ./discourse-math { };
discourse-migratepassword = callPackage ./discourse-migratepassword { };
discourse-oauth2-basic = callPackage ./discourse-oauth2-basic { };
discourse-openid-connect = callPackage ./discourse-openid-connect { };
discourse-prometheus = callPackage ./discourse-prometheus { };
discourse-reactions = callPackage ./discourse-reactions { };
discourse-saved-searches = callPackage ./discourse-saved-searches { };
discourse-solved = callPackage ./discourse-solved { };
discourse-spoiler-alert = callPackage ./discourse-spoiler-alert { };
discourse-voting = callPackage ./discourse-voting { };
discourse-yearly-review = callPackage ./discourse-yearly-review { };
}

View File

@@ -0,0 +1,21 @@
{
lib,
mkDiscoursePlugin,
fetchFromGitHub,
}:
mkDiscoursePlugin {
name = "discourse-assign";
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-assign";
rev = "261a47d119d200a8d922d008ad3d1667df869435";
sha256 = "sha256-0OClWO70btM7EN7Vir1LIhCTeO5+2jtkP4RozoKzp+0=";
};
meta = with lib; {
homepage = "https://github.com/discourse/discourse-docs";
maintainers = with maintainers; [ dpausp ];
license = licenses.mit;
description = "Discourse Plugin for assigning users to a topic";
};
}

View File

@@ -0,0 +1,21 @@
{
lib,
mkDiscoursePlugin,
fetchFromGitHub,
}:
mkDiscoursePlugin {
name = "discourse-bbcode-color";
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-bbcode-color";
rev = "ecd4befeb4eae48aa0a37a88e5aca60e59730411";
sha256 = "sha256-enpeXc6pE9+5EdbMIFsnWd++ixlHBKFRxbXmvJYJftg=";
};
meta = with lib; {
homepage = "https://github.com/discourse/discourse-bbcode-color";
maintainers = with maintainers; [ ryantm ];
license = licenses.mit;
description = "Support BBCode color tags";
};
}

View File

@@ -0,0 +1,6 @@
# frozen_string_literal: true
source "https://rubygems.org"
# gem "rails"
gem "rrule", "0.4.4", require: false

View File

@@ -0,0 +1,35 @@
GEM
remote: https://rubygems.org/
specs:
activesupport (7.1.3.3)
base64
bigdecimal
concurrent-ruby (~> 1.0, >= 1.0.2)
connection_pool (>= 2.2.5)
drb
i18n (>= 1.6, < 2)
minitest (>= 5.1)
mutex_m
tzinfo (~> 2.0)
base64 (0.2.0)
bigdecimal (3.1.8)
concurrent-ruby (1.2.3)
connection_pool (2.4.1)
drb (2.2.1)
i18n (1.14.5)
concurrent-ruby (~> 1.0)
minitest (5.23.1)
mutex_m (0.2.0)
rrule (0.4.4)
activesupport (>= 2.3)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
PLATFORMS
ruby
DEPENDENCIES
rrule (= 0.4.4)
BUNDLED WITH
2.5.9

View File

@@ -0,0 +1,22 @@
{
lib,
mkDiscoursePlugin,
fetchFromGitHub,
}:
mkDiscoursePlugin {
name = "discourse-calendar";
bundlerEnvArgs.gemdir = ./.;
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-calendar";
rev = "8d09cf8503b78f4c72b47a7319c0f4b9ad0247e7";
sha256 = "sha256-ES0/f/sv4Doao/MOdHYMwadRIVXb1I7FgSsl7790tio=";
};
meta = with lib; {
homepage = "https://github.com/discourse/discourse-calendar";
maintainers = with maintainers; [ ryantm ];
license = licenses.mit;
description = "Adds the ability to create a dynamic calendar in the first post of a topic";
};
}

View File

@@ -0,0 +1,126 @@
{
activesupport = {
dependencies = [
"base64"
"bigdecimal"
"concurrent-ruby"
"connection_pool"
"drb"
"i18n"
"minitest"
"mutex_m"
"tzinfo"
];
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "0z8kygxmz99krz9pwp947znkzf0jr64sml28df0vf1gzxlg7y57i";
type = "gem";
};
version = "7.1.3.3";
};
base64 = {
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "01qml0yilb9basf7is2614skjp8384h2pycfx86cr8023arfj98g";
type = "gem";
};
version = "0.2.0";
};
bigdecimal = {
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "1gi7zqgmqwi5lizggs1jhc3zlwaqayy9rx2ah80sxy24bbnng558";
type = "gem";
};
version = "3.1.8";
};
concurrent-ruby = {
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "1qh1b14jwbbj242klkyz5fc7npd4j0mvndz62gajhvl1l3wd7zc2";
type = "gem";
};
version = "1.2.3";
};
connection_pool = {
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "1x32mcpm2cl5492kd6lbjbaf17qsssmpx9kdyr7z1wcif2cwyh0g";
type = "gem";
};
version = "2.4.1";
};
drb = {
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "0h5kbj9hvg5hb3c7l425zpds0vb42phvln2knab8nmazg2zp5m79";
type = "gem";
};
version = "2.2.1";
};
i18n = {
dependencies = [ "concurrent-ruby" ];
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "1ffix518y7976qih9k1lgnc17i3v6yrlh0a3mckpxdb4wc2vrp16";
type = "gem";
};
version = "1.14.5";
};
minitest = {
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "1gkslxvkhh44s21rbjvka3zsvfxxrf5pcl6f75rv2vyrzzbgis7i";
type = "gem";
};
version = "5.23.1";
};
mutex_m = {
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "1ma093ayps1m92q845hmpk0dmadicvifkbf05rpq9pifhin0rvxn";
type = "gem";
};
version = "0.2.0";
};
rrule = {
dependencies = [ "activesupport" ];
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "04h3q0ws0wswqj3mwjyv44yx59d9ima9a820ay9w5bwnlb73syj2";
type = "gem";
};
version = "0.4.4";
};
tzinfo = {
dependencies = [ "concurrent-ruby" ];
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "16w2g84dzaf3z13gxyzlzbf748kylk5bdgg3n1ipvkvvqy685bwd";
type = "gem";
};
version = "2.0.6";
};
}

View File

@@ -0,0 +1,21 @@
{
lib,
mkDiscoursePlugin,
fetchFromGitHub,
}:
mkDiscoursePlugin {
name = "discourse-canned-replies";
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-canned-replies";
rev = "732598b6cdc86c74622bb15bfeaebb05611bbc25";
sha256 = "sha256-t0emNsPT8o0ralUedt33ufH0VLl4/12lVBBCnzfdRxE=";
};
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";
};
}

View File

@@ -0,0 +1,21 @@
{
lib,
mkDiscoursePlugin,
fetchFromGitHub,
}:
mkDiscoursePlugin {
name = "discourse-chat-integration";
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-chat-integration";
rev = "29ad813cd04812786780e1706cbc043810dea7d8";
sha256 = "sha256-5mGnHLlw3qIGi8et3WV1RXnrPB+bySi3wQryKTa5wNg=";
};
meta = with lib; {
homepage = "https://github.com/discourse/discourse-chat-integration";
maintainers = with maintainers; [ dpausp ];
license = licenses.mit;
description = "This plugin integrates Discourse with a number of external chatroom systems";
};
}

View File

@@ -0,0 +1,21 @@
{
lib,
mkDiscoursePlugin,
fetchFromGitHub,
}:
mkDiscoursePlugin {
name = "discourse-checklist";
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-checklist";
rev = "6fcf9fed5c3ae3baf9ddd1cca9cef4dc089996c1";
sha256 = "sha256-RIuoqZo7dW1DXbfbWhyyhCOGe4R5sLerzFW2TT0zO6U=";
};
meta = with lib; {
homepage = "https://github.com/discourse/discourse-checklist";
maintainers = with maintainers; [ ryantm ];
license = licenses.gpl2Only;
description = "Simple checklist rendering plugin for discourse";
};
}

View File

@@ -0,0 +1,21 @@
{
lib,
mkDiscoursePlugin,
fetchFromGitHub,
}:
mkDiscoursePlugin {
name = "discourse-data-explorer";
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-data-explorer";
rev = "2ba204a1de2638a7959e588b88f3b6c7fcf7a70f";
sha256 = "sha256-u8yGKANEyqm63/ZnJLe3u1nkNGZyX0wFUBIKU5GgjzY=";
};
meta = with lib; {
homepage = "https://github.com/discourse/discourse-data-explorer";
maintainers = with maintainers; [ ryantm ];
license = licenses.mit;
description = "SQL Queries for admins in Discourse";
};
}

View File

@@ -0,0 +1,21 @@
{
lib,
mkDiscoursePlugin,
fetchFromGitHub,
}:
mkDiscoursePlugin {
name = "discourse-docs";
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-docs";
rev = "4e42539cda9a54d7827bcdf51b6dfbcf56d24cc9";
sha256 = "sha256-sv9Q0qEQVncQw3QLiro5YfVcHJAG8sJ0GTjduCZ0iP4=";
};
meta = with lib; {
homepage = "https://github.com/discourse/discourse-docs";
maintainers = with maintainers; [ dpausp ];
license = licenses.mit;
description = "Find and filter knowledge base topics";
};
}

View File

@@ -0,0 +1,7 @@
# frozen_string_literal: true
source "https://rubygems.org"
# gem "rails"
gem "sawyer", "0.9.2"
gem "octokit", "5.6.1"

View File

@@ -0,0 +1,33 @@
GEM
remote: https://rubygems.org/
specs:
addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0)
faraday (2.12.3)
faraday-net_http (>= 2.0, < 3.5)
json
logger
faraday-net_http (3.4.0)
net-http (>= 0.5.0)
json (2.10.2)
logger (1.7.0)
net-http (0.6.0)
uri
octokit (5.6.1)
faraday (>= 1, < 3)
sawyer (~> 0.9)
public_suffix (6.0.1)
sawyer (0.9.2)
addressable (>= 2.3.5)
faraday (>= 0.17.3, < 3)
uri (1.0.3)
PLATFORMS
ruby
DEPENDENCIES
octokit (= 5.6.1)
sawyer (= 0.9.2)
BUNDLED WITH
2.5.22

View File

@@ -0,0 +1,23 @@
{
lib,
mkDiscoursePlugin,
fetchFromGitHub,
}:
mkDiscoursePlugin {
name = "discourse-github";
bundlerEnvArgs.gemdir = ./.;
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-github";
rev = "59e5fc5692959c6c564ab0e09de364ccfedd6702";
sha256 = "sha256-b+8eSw8Kbz2CZN16Rd7c8uyH5P1iYhOJmdXu1C5UclU=";
};
meta = with lib; {
homepage = "https://github.com/discourse/discourse-github";
maintainers = with maintainers; [ talyz ];
license = licenses.mit;
description = "Adds GitHub badges and linkback functionality";
};
}

View File

@@ -0,0 +1,118 @@
{
addressable = {
dependencies = [ "public_suffix" ];
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "0cl2qpvwiffym62z991ynks7imsm87qmgxf0yfsmlwzkgi9qcaa6";
type = "gem";
};
version = "2.8.7";
};
faraday = {
dependencies = [
"faraday-net_http"
"json"
"logger"
];
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "0dxalpc0ldvjjmd7z95na9lm99d2baz48sf9axk3a6x3pn50ibdi";
type = "gem";
};
version = "2.12.3";
};
faraday-net_http = {
dependencies = [ "net-http" ];
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "0jp5ci6g40d6i50bsywp35l97nc2fpi9a592r2cibwicdb6y9wd1";
type = "gem";
};
version = "3.4.0";
};
json = {
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "01lbdaizhkxmrw4y8j3wpvsryvnvzmg0pfs56c52laq2jgdfmq1l";
type = "gem";
};
version = "2.10.2";
};
logger = {
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "00q2zznygpbls8asz5knjvvj2brr3ghmqxgr83xnrdj4rk3xwvhr";
type = "gem";
};
version = "1.7.0";
};
net-http = {
dependencies = [ "uri" ];
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "1ysrwaabhf0sn24jrp0nnp51cdv0jf688mh5i6fsz63q2c6b48cn";
type = "gem";
};
version = "0.6.0";
};
octokit = {
dependencies = [
"faraday"
"sawyer"
];
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "15g4kyag6gmxxq6d03472h7srm3imlsks1wg6nac7hl3mb1b5vs8";
type = "gem";
};
version = "5.6.1";
};
public_suffix = {
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "0vqcw3iwby3yc6avs1vb3gfd0vcp2v7q310665dvxfswmcf4xm31";
type = "gem";
};
version = "6.0.1";
};
sawyer = {
dependencies = [
"addressable"
"faraday"
];
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "1jks1qjbmqm8f9kvwa81vqj39avaj9wdnzc531xm29a55bb74fps";
type = "gem";
};
version = "0.9.2";
};
uri = {
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "04bhfvc25b07jaiaf62yrach7khhr5jlr5bx6nygg8pf11329wp9";
type = "gem";
};
version = "1.0.3";
};
}

View File

@@ -0,0 +1,8 @@
# frozen_string_literal: true
source "https://rubygems.org"
# gem "rails"
gem 'pyu-ruby-sasl', '0.0.3.3', require: false
gem 'rubyntlm', '0.3.4', require: false
gem 'net-ldap', '0.18.0'

View File

@@ -0,0 +1,17 @@
GEM
remote: https://rubygems.org/
specs:
net-ldap (0.18.0)
pyu-ruby-sasl (0.0.3.3)
rubyntlm (0.3.4)
PLATFORMS
ruby
DEPENDENCIES
net-ldap (= 0.18.0)
pyu-ruby-sasl (= 0.0.3.3)
rubyntlm (= 0.3.4)
BUNDLED WITH
2.5.22

View File

@@ -0,0 +1,22 @@
{
lib,
mkDiscoursePlugin,
fetchFromGitHub,
}:
mkDiscoursePlugin {
name = "discourse-ldap-auth";
bundlerEnvArgs.gemdir = ./.;
src = fetchFromGitHub {
owner = "jonmbake";
repo = "discourse-ldap-auth";
rev = "fa1d661004ca99036ff628a9c4be12a81265d784";
sha256 = "sha256-2DYrYgC3H+e8USoo1MbJin1f5tshIUsQa6J7avnpvEc=";
};
meta = with lib; {
homepage = "https://github.com/jonmbake/discourse-ldap-auth";
maintainers = with maintainers; [ ryantm ];
license = licenses.mit;
description = "Discourse plugin to enable LDAP/Active Directory authentication";
};
}

View File

@@ -0,0 +1,32 @@
{
net-ldap = {
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "0xqcffn3c1564c4fizp10dzw2v5g2pabdzrcn25hq05bqhsckbar";
type = "gem";
};
version = "0.18.0";
};
pyu-ruby-sasl = {
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "1rcpjiz9lrvyb3rd8k8qni0v4ps08psympffyldmmnrqayyad0sn";
type = "gem";
};
version = "0.0.3.3";
};
rubyntlm = {
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "18d1lxhx62swggf4cqg76h7hp04f5801c8h07w08cm9xng2niqby";
type = "gem";
};
version = "0.3.4";
};
}

View File

@@ -0,0 +1,21 @@
{
lib,
mkDiscoursePlugin,
fetchFromGitHub,
}:
mkDiscoursePlugin {
name = "discourse-math";
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-math";
rev = "90a56a5b463546cba5017cf25168bae759bcbf77";
sha256 = "sha256-q8cNRIHYEkaE6QkdsHu4tPwSw3LnCNgKjbyESBXheE0=";
};
meta = with lib; {
homepage = "https://github.com/discourse/discourse-math";
maintainers = with maintainers; [ talyz ];
license = licenses.mit;
description = "Official MathJax support for Discourse";
};
}

View File

@@ -0,0 +1,9 @@
# frozen_string_literal: true
source "https://rubygems.org"
# gem "rails"
gem 'bcrypt', '3.1.13'
gem 'unix-crypt', '1.3.0'
gem 'ffi-compiler', '1.0.1', require: false
gem 'argon2', '2.2.0'

View File

@@ -0,0 +1,25 @@
GEM
remote: https://rubygems.org/
specs:
argon2 (2.2.0)
ffi (~> 1.15)
ffi-compiler (~> 1.0)
bcrypt (3.1.13)
ffi (1.17.0)
ffi-compiler (1.0.1)
ffi (>= 1.0.0)
rake
rake (13.2.1)
unix-crypt (1.3.0)
PLATFORMS
ruby
DEPENDENCIES
argon2 (= 2.2.0)
bcrypt (= 3.1.13)
ffi-compiler (= 1.0.1)
unix-crypt (= 1.3.0)
BUNDLED WITH
2.5.11

View File

@@ -0,0 +1,22 @@
{
lib,
mkDiscoursePlugin,
fetchFromGitHub,
}:
mkDiscoursePlugin {
name = "discourse-migratepassword";
bundlerEnvArgs.gemdir = ./.;
src = fetchFromGitHub {
owner = "communiteq";
repo = "discourse-migratepassword";
rev = "a732ae244cd4125561fd225a67bae95ef5f738d0";
sha256 = "sha256-EO+QnFTy3PgxZ92DZBm9sP8sFAny3ZpFw+faTX32j7Q=";
};
meta = with lib; {
homepage = "https://github.com/communiteq/discourse-migratepassword";
maintainers = with maintainers; [ ryantm ];
license = licenses.gpl2Only;
description = "Support migrated password hashes";
};
}

View File

@@ -0,0 +1,70 @@
{
argon2 = {
dependencies = [
"ffi"
"ffi-compiler"
];
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "1wdllcqlr81nzyf485ldv1p660xsi476p79ghbj7zsf3n9n86gwd";
type = "gem";
};
version = "2.2.0";
};
bcrypt = {
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "0ai0m15jg3n0b22mimk09ppnga316dc7dyvz06w8rrqh5gy1lslp";
type = "gem";
};
version = "3.1.13";
};
ffi = {
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "07139870npj59jnl8vmk39ja3gdk3fb5z9vc0lf32y2h891hwqsi";
type = "gem";
};
version = "1.17.0";
};
ffi-compiler = {
dependencies = [
"ffi"
"rake"
];
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "0c2caqm9wqnbidcb8dj4wd3s902z15qmgxplwyfyqbwa0ydki7q1";
type = "gem";
};
version = "1.0.1";
};
rake = {
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "17850wcwkgi30p7yqh60960ypn7yibacjjha0av78zaxwvd3ijs6";
type = "gem";
};
version = "13.2.1";
};
unix-crypt = {
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "1wflipsmmicmgvqilp9pml4x19b337kh6p6jgrzqrzpkq2z52gdq";
type = "gem";
};
version = "1.3.0";
};
}

View File

@@ -0,0 +1,7 @@
# frozen_string_literal: true
source 'https://rubygems.org'
group :development do
gem 'rubocop-discourse'
end

View File

@@ -0,0 +1,37 @@
GEM
remote: https://rubygems.org/
specs:
ast (2.4.2)
parallel (1.22.1)
parser (3.1.1.0)
ast (~> 2.4.1)
rainbow (3.1.1)
regexp_parser (2.2.1)
rexml (3.2.5)
rubocop (1.26.1)
parallel (~> 1.10)
parser (>= 3.1.0.0)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml
rubocop-ast (>= 1.16.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 3.0)
rubocop-ast (1.16.0)
parser (>= 3.1.1.0)
rubocop-discourse (2.5.0)
rubocop (>= 1.1.0)
rubocop-rspec (>= 2.0.0)
rubocop-rspec (2.9.0)
rubocop (~> 1.19)
ruby-progressbar (1.11.0)
unicode-display_width (2.1.0)
PLATFORMS
ruby
DEPENDENCIES
rubocop-discourse
BUNDLED WITH
2.1.4

View File

@@ -0,0 +1,21 @@
{
lib,
mkDiscoursePlugin,
fetchFromGitHub,
}:
mkDiscoursePlugin rec {
name = "discourse-oauth2-basic";
bundlerEnvArgs.gemdir = ./.;
src = fetchFromGitHub {
owner = "discourse";
repo = name;
rev = "06ba5daa9aabd0487f2f30b944b6500f1f481308";
sha256 = "sha256-T08Q36k2hb9wVimKIa4O5mWcrr6VBTfHvhRJiLBiRPY=";
};
meta = with lib; {
homepage = "https://github.com/discourse/${name}";
license = licenses.mit;
description = "Basic OAuth2 plugin for use with Discourse";
};
}

View File

@@ -0,0 +1,172 @@
{
ast = {
groups = [
"default"
"development"
];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "04nc8x27hlzlrr5c2gn7mar4vdr0apw5xg22wp6m8dx3wqr04a0y";
type = "gem";
};
version = "2.4.2";
};
parallel = {
groups = [
"default"
"development"
];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "07vnk6bb54k4yc06xnwck7php50l09vvlw1ga8wdz0pia461zpzb";
type = "gem";
};
version = "1.22.1";
};
parser = {
dependencies = [ "ast" ];
groups = [
"default"
"development"
];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "0zaghgvva2q4jqbachg8jvpwgbg3w1jqr0d00m8rqciqznjgsw3c";
type = "gem";
};
version = "3.1.1.0";
};
rainbow = {
groups = [
"default"
"development"
];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "0smwg4mii0fm38pyb5fddbmrdpifwv22zv3d3px2xx497am93503";
type = "gem";
};
version = "3.1.1";
};
regexp_parser = {
groups = [
"default"
"development"
];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "155f6cr4rrfw5bs5xd3m5kfw32qhc5fsi4nk82rhif56rc6cs0wm";
type = "gem";
};
version = "2.2.1";
};
rexml = {
groups = [
"default"
"development"
];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "08ximcyfjy94pm1rhcx04ny1vx2sk0x4y185gzn86yfsbzwkng53";
type = "gem";
};
version = "3.2.5";
};
rubocop = {
dependencies = [
"parallel"
"parser"
"rainbow"
"regexp_parser"
"rexml"
"rubocop-ast"
"ruby-progressbar"
"unicode-display_width"
];
groups = [
"default"
"development"
];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "06105yrqajpm5l07fng1nbk55y9490hny542zclnan8hg841pjgl";
type = "gem";
};
version = "1.26.1";
};
rubocop-ast = {
dependencies = [ "parser" ];
groups = [
"default"
"development"
];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "1bd2z82ly7fix8415gvfiwzb6bjialz5rs3sr72kv1lk68rd23wv";
type = "gem";
};
version = "1.16.0";
};
rubocop-discourse = {
dependencies = [
"rubocop"
"rubocop-rspec"
];
groups = [ "development" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "01f4y7am9cq276zl8vsgv64w8wfmhpbzg7vzsifhgnnh92g6s04g";
type = "gem";
};
version = "2.5.0";
};
rubocop-rspec = {
dependencies = [ "rubocop" ];
groups = [
"default"
"development"
];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "051gq9pz49iv4gq34d3n089iaa6cb418n2fhin6gd6fpysbi3nf6";
type = "gem";
};
version = "2.9.0";
};
ruby-progressbar = {
groups = [
"default"
"development"
];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "02nmaw7yx9kl7rbaan5pl8x5nn0y4j5954mzrkzi9i3dhsrps4nc";
type = "gem";
};
version = "1.11.0";
};
unicode-display_width = {
groups = [
"default"
"development"
];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "0csjm9shhfik0ci9mgimb7hf3xgh7nx45rkd9rzgdz6vkwr8rzxn";
type = "gem";
};
version = "2.1.0";
};
}

View File

@@ -0,0 +1,7 @@
# frozen_string_literal: true
source 'https://rubygems.org'
group :development do
gem 'rubocop-discourse'
end

View File

@@ -0,0 +1,37 @@
GEM
remote: https://rubygems.org/
specs:
ast (2.4.1)
parallel (1.19.2)
parser (2.7.2.0)
ast (~> 2.4.1)
rainbow (3.0.0)
regexp_parser (1.8.1)
rexml (3.2.5)
rubocop (0.93.0)
parallel (~> 1.10)
parser (>= 2.7.1.5)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8)
rexml
rubocop-ast (>= 0.6.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 2.0)
rubocop-ast (0.7.1)
parser (>= 2.7.1.5)
rubocop-discourse (2.3.2)
rubocop (>= 0.69.0)
rubocop-rspec (>= 1.39.0)
rubocop-rspec (1.43.2)
rubocop (~> 0.87)
ruby-progressbar (1.10.1)
unicode-display_width (1.7.0)
PLATFORMS
ruby
DEPENDENCIES
rubocop-discourse
BUNDLED WITH
2.1.4

View File

@@ -0,0 +1,22 @@
{
lib,
mkDiscoursePlugin,
fetchFromGitHub,
}:
mkDiscoursePlugin {
name = "discourse-openid-connect";
bundlerEnvArgs.gemdir = ./.;
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-openid-connect";
rev = "e08efecc012a5ab8fa95084be93d4fd07ccebab9";
sha256 = "sha256-v4UWFDdOFON+nHkH490kBQ4sXX7Mrp7KVhN1x9HML7w=";
};
meta = with lib; {
homepage = "https://github.com/discourse/discourse-openid-connect";
maintainers = with maintainers; [ mkg20001 ];
license = licenses.mit;
description = "Discourse plugin to integrate Discourse with an openid-connect login provider";
};
}

View File

@@ -0,0 +1,172 @@
{
ast = {
groups = [
"default"
"development"
];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "1l3468czzjmxl93ap40hp7z94yxp4nbag0bxqs789bm30md90m2a";
type = "gem";
};
version = "2.4.1";
};
parallel = {
groups = [
"default"
"development"
];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "17b127xxmm2yqdz146qwbs57046kn0js1h8synv01dwqz2z1kp2l";
type = "gem";
};
version = "1.19.2";
};
parser = {
dependencies = [ "ast" ];
groups = [
"default"
"development"
];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "1f7gmm60yla325wlnd3qkxs59qm2y0aan8ljpg6k18rwzrrfil6z";
type = "gem";
};
version = "2.7.2.0";
};
rainbow = {
groups = [
"default"
"development"
];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "0bb2fpjspydr6x0s8pn1pqkzmxszvkfapv0p4627mywl7ky4zkhk";
type = "gem";
};
version = "3.0.0";
};
regexp_parser = {
groups = [
"default"
"development"
];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "0n9d14ppshnx71i3mi1pnm3hwhcbb6m6vsc0b0dqgsab8r2rs96n";
type = "gem";
};
version = "1.8.1";
};
rexml = {
groups = [
"default"
"development"
];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "08ximcyfjy94pm1rhcx04ny1vx2sk0x4y185gzn86yfsbzwkng53";
type = "gem";
};
version = "3.2.5";
};
rubocop = {
dependencies = [
"parallel"
"parser"
"rainbow"
"regexp_parser"
"rexml"
"rubocop-ast"
"ruby-progressbar"
"unicode-display_width"
];
groups = [
"default"
"development"
];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "1nrv7i81549addig09grw17qkab3l4319dcsf9y7psl7aa76ng3a";
type = "gem";
};
version = "0.93.0";
};
rubocop-ast = {
dependencies = [ "parser" ];
groups = [
"default"
"development"
];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "129hgz4swc8n0g01715v7y00k0h4mlzkxh63q7z27q7mjp54rl74";
type = "gem";
};
version = "0.7.1";
};
rubocop-discourse = {
dependencies = [
"rubocop"
"rubocop-rspec"
];
groups = [ "development" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "10l2wwnvd4xccgqsyhxrhc5bw10b7an4awl0v90fw5xf2qdjiflw";
type = "gem";
};
version = "2.3.2";
};
rubocop-rspec = {
dependencies = [ "rubocop" ];
groups = [
"default"
"development"
];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "1sc0bwdxzfr8byxzwvfyf22lwzqcaa6ca7wzxx31mk7vvy7r7dhl";
type = "gem";
};
version = "1.43.2";
};
ruby-progressbar = {
groups = [
"default"
"development"
];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "1k77i0d4wsn23ggdd2msrcwfy0i376cglfqypkk2q77r2l3408zf";
type = "gem";
};
version = "1.10.1";
};
unicode-display_width = {
groups = [
"default"
"development"
];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "06i3id27s60141x6fdnjn5rar1cywdwy64ilc59cz937303q3mna";
type = "gem";
};
version = "1.7.0";
};
}

View File

@@ -0,0 +1,6 @@
# frozen_string_literal: true
source "https://rubygems.org"
# gem "rails"
gem "prometheus_exporter", "2.2.0"

View File

@@ -0,0 +1,15 @@
GEM
remote: https://rubygems.org/
specs:
prometheus_exporter (2.2.0)
webrick
webrick (1.9.1)
PLATFORMS
ruby
DEPENDENCIES
prometheus_exporter (= 2.2.0)
BUNDLED WITH
2.5.22

View File

@@ -0,0 +1,30 @@
{
lib,
mkDiscoursePlugin,
fetchFromGitHub,
}:
mkDiscoursePlugin {
bundlerEnvArgs.gemdir = ./.;
name = "discourse-prometheus";
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-prometheus";
rev = "f46906e1d555f6838d74ea38d5037264cc1020b0";
sha256 = "sha256-czrxhH0L+vCZA8DKN6acW///iWJs9GIppEeaP2MOJBQ=";
};
patches = [
# The metrics collector tries to run git to get the commit id but fails
# because we don't run Discourse from a Git repository.
./no-git-version.patch
./spec-import-fix-abi-version.patch
];
meta = with lib; {
homepage = "https://github.com/discourse/discourse-prometheus";
maintainers = with maintainers; [ dpausp ];
license = licenses.mit;
description = "Official Discourse Plugin for Prometheus Monitoring";
};
}

View File

@@ -0,0 +1,23 @@
{
prometheus_exporter = {
dependencies = [ "webrick" ];
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "15vl8fw8vjnaj9g129dzrwk9nlrdqgffaj3rys4ba9ns2bqim9rq";
type = "gem";
};
version = "2.2.0";
};
webrick = {
groups = [ "default" ];
platforms = [ ];
source = {
remotes = [ "https://rubygems.org" ];
sha256 = "12d9n8hll67j737ym2zw4v23cn4vxyfkb6vyv1rzpwv6y6a3qbdl";
type = "gem";
};
version = "1.9.1";
};
}

View File

@@ -0,0 +1,34 @@
diff --git a/lib/internal_metric/global.rb b/lib/internal_metric/global.rb
index 682571b..7bdd431 100644
--- a/lib/internal_metric/global.rb
+++ b/lib/internal_metric/global.rb
@@ -30,28 +30,7 @@ module DiscoursePrometheus::InternalMetric
@active_app_reqs = 0
@queued_app_reqs = 0
@fault_logged = {}
-
- begin
- @@version = nil
-
- out, error, status = Open3.capture3("git rev-parse HEAD")
-
- if status.success?
- @@version ||= out.chomp
- else
- raise error
- end
- rescue => e
- if defined?(::Discourse)
- Discourse.warn_exception(e, message: "Failed to calculate discourse_version_info metric")
- else
- STDERR.puts "Failed to calculate discourse_version_info metric: #{e}\n#{e.backtrace.join("\n")}"
- end
-
- @@retries ||= 10
- @@retries -= 1
- @@version = -1 if @@retries < 0
- end
+ @@version = -1
end
def collect

View File

@@ -0,0 +1,16 @@
diff --git a/bin/collector b/bin/collector
index 4bdce08178..5edc0a4aee 100755
--- a/bin/collector
+++ b/bin/collector
@@ -3,9 +3,11 @@
Process.setproctitle("discourse prometheus-collector")
+# We need the ABI version {MAJOR}.{MINOR}.0 here.
+abi_version = ENV['GEM_PATH'].split("/")[-1]
spec_file =
File.expand_path(
- "../../gems/#{RUBY_VERSION}/specifications/#{"prometheus_exporter-#{ENV["PROMETHEUS_EXPORTER_VERSION"]}"}.gemspec",
+ "../../gems/#{abi_version}/specifications/#{"prometheus_exporter-#{ENV["PROMETHEUS_EXPORTER_VERSION"]}"}.gemspec",
__FILE__,
)

View File

@@ -0,0 +1,21 @@
{
lib,
mkDiscoursePlugin,
fetchFromGitHub,
}:
mkDiscoursePlugin {
name = "discourse-reactions";
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-reactions";
rev = "f87583d9054421869ba0de16c24ad15e32bbebe7";
sha256 = "sha256-v2AkpSTF3VNgBUfvRMQ3BCw0nClWjcVTdKNn9yiByBM=";
};
meta = with lib; {
homepage = "https://github.com/discourse/discourse-reactions";
maintainers = with maintainers; [ bbenno ];
license = licenses.mit;
description = "Allows users to react to a post from a choice of emojis, rather than only the like heart";
};
}

View File

@@ -0,0 +1,21 @@
{
lib,
mkDiscoursePlugin,
fetchFromGitHub,
}:
mkDiscoursePlugin {
name = "discourse-saved-searches";
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-saved-searches";
rev = "b78aae086e95255b1a1e91a01e2d56b45b7aead2";
sha256 = "sha256-Wai+oZR+Pzjre6Th0kQDgvFOwfPRHlZkpKYYOUKNlx4=";
};
meta = with lib; {
homepage = "https://github.com/discourse/discourse-saved-searches";
maintainers = with maintainers; [ dpausp ];
license = licenses.mit;
description = "Allow users to save searches and be notified of new results";
};
}

View File

@@ -0,0 +1,21 @@
{
lib,
mkDiscoursePlugin,
fetchFromGitHub,
}:
mkDiscoursePlugin {
name = "discourse-solved";
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-solved";
rev = "e82c6ae1ca38ccebb34669148f8de93a3028906e";
sha256 = "sha256-KwpBCk4fjkZlSzgtc0OXvQupPd+aPb9nONyyALpEZhg=";
};
meta = with lib; {
homepage = "https://github.com/discourse/discourse-solved";
maintainers = with maintainers; [ talyz ];
license = licenses.mit;
description = "Allow accepted answers on topics";
};
}

View File

@@ -0,0 +1,21 @@
{
lib,
mkDiscoursePlugin,
fetchFromGitHub,
}:
mkDiscoursePlugin {
name = "discourse-spoiler-alert";
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-spoiler-alert";
rev = "42b77ec048b9b386a8b25a22bfec6472817da465";
sha256 = "sha256-BQeID+y9RvmcnuNsodOMXseVvre5QYxv+E/ul8bucUI=";
};
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";
};
}

View File

@@ -0,0 +1,21 @@
{
lib,
mkDiscoursePlugin,
fetchFromGitHub,
}:
mkDiscoursePlugin {
name = "discourse-voting";
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-topic-voting";
rev = "d779202749e56aaee2d548b538796fb5db1b9b7c";
sha256 = "sha256-8YF7W5SXhI7TGJNZkx5or7bxI0MKiDtx10TE2ekBMuM=";
};
meta = with lib; {
homepage = "https://github.com/discourse/discourse-voting";
maintainers = with maintainers; [ dpausp ];
license = licenses.gpl2Only;
description = "Adds the ability for voting on a topic within a specified category in Discourse";
};
}

View File

@@ -0,0 +1,21 @@
{
lib,
mkDiscoursePlugin,
fetchFromGitHub,
}:
mkDiscoursePlugin {
name = "discourse-yearly-review";
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-yearly-review";
rev = "439e0d78f1d8a0f387c0ec26f233a090ce82ef72";
sha256 = "sha256-DXA5P7XnItBjP4H1J/G1cGbFddSDZh0wjMZiJ5JA9s8=";
};
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";
};
}

View File

@@ -0,0 +1,23 @@
diff --git a/lib/discourse_js_processor.rb b/lib/discourse_js_processor.rb
index f1642386c5..5a672818da 100644
--- a/lib/discourse_js_processor.rb
+++ b/lib/discourse_js_processor.rb
@@ -54,7 +54,7 @@ class DiscourseJsProcessor
end
class Transpiler
- TRANSPILER_PATH = "tmp/theme-transpiler.js"
+ TRANSPILER_PATH = "app/assets/javascripts/theme-transpiler.js"
@mutex = Mutex.new
@ctx_init = Mutex.new
@@ -75,7 +75,9 @@ class DiscourseJsProcessor
end
def self.build_production_theme_transpiler
- File.write(TRANSPILER_PATH, build_theme_transpiler)
+ if (!Rails.env.production? or !File.file?(TRANSPILER_PATH))
+ File.write(TRANSPILER_PATH, build_theme_transpiler)
+ end
TRANSPILER_PATH
end

View File

@@ -0,0 +1,294 @@
# frozen_string_literal: true
source "https://rubygems.org"
# if there is a super emergency and rubygems is playing up, try
#source 'http://production.cf.rubygems.org'
gem "bootsnap", require: false, platform: :mri
gem "actionmailer", "~> 7.2.0"
gem "actionpack", "~> 7.2.0"
gem "actionview", "~> 7.2.0"
gem "activemodel", "~> 7.2.0"
gem "activerecord", "~> 7.2.0"
gem "activesupport", "~> 7.2.0"
gem "railties", "~> 7.2.0"
gem "sprockets-rails"
gem "json"
# TODO: At the moment Discourse does not work with Sprockets 4, we would need to correct internals
# We intend to drop sprockets rather than upgrade to 4.x
gem "sprockets", "~> 3.7.3"
# this will eventually be added to rails,
# allows us to precompile all our templates in the unicorn master
gem "actionview_precompiler", require: false
gem "discourse-seed-fu"
gem "mail"
gem "mini_mime"
gem "mini_suffix"
# config/initializers/006-mini_profiler.rb depends upon the RedisClient#call.
# Rework this when upgrading to redis client 5.0 and above.
gem "redis", "< 5.0"
# This is explicitly used by Sidekiq and is an optional dependency.
# We tell Sidekiq to use the namespace "sidekiq" which triggers this
# gem to be used. There is no explicit dependency in sidekiq cause
# redis namespace support is optional
# We already namespace stuff in DiscourseRedis, so we should consider
# just using a single implementation in core vs having 2 namespace implementations
gem "redis-namespace"
# NOTE: AM serializer gets a lot slower with recent updates
# we used an old branch which is the fastest one out there
# are long term goal here is to fork this gem so we have a
# better maintained living fork
gem "active_model_serializers", "~> 0.8.3"
gem "http_accept_language", require: false
gem "discourse-fonts", require: "discourse_fonts"
gem "message_bus"
gem "rails_multisite"
gem "fastimage"
gem "aws-sdk-s3", require: false
gem "aws-sdk-sns", require: false
gem "excon", require: false
gem "unf", require: false
gem "email_reply_trimmer"
gem "image_optim"
gem "multi_json"
gem "mustache"
gem "nokogiri"
gem "loofah"
gem "css_parser", require: false
gem "omniauth"
gem "omniauth-facebook"
gem "omniauth-twitter"
gem "omniauth-github"
gem "omniauth-oauth2", require: false
gem "omniauth-google-oauth2"
gem "oj"
gem "pg"
gem "mini_sql"
gem "pry-rails", require: false
gem "pry-byebug", require: false
gem "rtlcss", require: false
gem "messageformat-wrapper", require: false
gem "rake"
gem "thor", require: false
gem "diffy", require: false
gem "rinku"
gem "sidekiq"
gem "mini_scheduler"
gem "execjs", require: false
gem "mini_racer", "0.17.pre13"
gem "highline", require: false
gem "rack"
gem "rack-protection" # security
gem "cbor", require: false
gem "cose", require: false
gem "addressable"
gem "json_schemer"
gem "net-smtp", require: false
gem "net-imap", require: false
gem "net-pop", require: false
gem "digest", require: false
# Gems used only for assets and not required in production environments by default.
# Allow everywhere for now cause we are allowing asset debugging in production
group :assets do
gem "uglifier"
end
group :test do
gem "capybara", require: false
gem "webmock", require: false
gem "fakeweb", require: false
gem "simplecov", require: false
gem "selenium-webdriver", "~> 4.14", require: false
gem "selenium-devtools", require: false
gem "test-prof"
gem "rails-dom-testing", require: false
gem "minio_runner", require: false
end
group :test, :development do
gem "rspec"
gem "listen", require: false
gem "certified", require: false
gem "fabrication", require: false
gem "mocha", require: false
gem "rb-fsevent", require: RUBY_PLATFORM =~ /darwin/i ? "rb-fsevent" : false
gem "rspec-rails"
gem "shoulda-matchers", require: false
gem "rspec-html-matchers"
gem "pry-stack_explorer", require: false
gem "byebug", require: ENV["RM_INFO"].nil?, platform: :mri
gem "rubocop-discourse", require: false
gem "parallel_tests"
gem "rswag-specs"
gem "annotate"
gem "syntax_tree"
gem "syntax_tree-disable_ternary"
gem "rspec-multi-mock"
end
group :development do
gem "ruby-prof", require: false, platform: :mri
gem "bullet", require: !!ENV["BULLET"]
gem "better_errors", platform: :mri, require: !!ENV["BETTER_ERRORS"]
gem "binding_of_caller"
gem "yaml-lint"
gem "yard"
end
if ENV["ALLOW_DEV_POPULATE"] == "1"
gem "discourse_dev_assets"
gem "faker", "~> 2.16"
else
group :development, :test do
gem "discourse_dev_assets"
gem "faker", "~> 2.16"
end
end
# this is an optional gem, it provides a high performance replacement
# to String#blank? a method that is called quite frequently in current
# ActiveRecord, this may change in the future
gem "fast_blank", platform: :ruby
# this provides a very efficient lru cache
gem "lru_redux"
gem "htmlentities", require: false
# IMPORTANT: mini profiler monkey patches, so it better be required last
# If you want to amend mini profiler to do the monkey patches in the railties
# we are open to it. by deferring require to the initializer we can configure discourse installs without it
gem "rack-mini-profiler", require: ["enable_rails_patches"]
gem "unicorn", require: false, platform: :ruby
gem "puma", require: false
gem "rbtrace", require: false, platform: :mri
# required for feed importing and embedding
gem "ruby-readability", require: false
# rss gem is a bundled gem from Ruby 3 onwards
gem "rss", require: false
gem "stackprof", require: false, platform: :mri
gem "memory_profiler", require: false, platform: :mri
gem "cppjieba_rb", require: false
gem "lograge", require: false
gem "logstash-event", require: false
gem "logster"
# A fork of sassc with dart-sass support
gem "sassc-embedded"
gem "rotp", require: false
gem "rqrcode"
gem "rubyzip", require: false
gem "sshkey", require: false
gem "rchardet", require: false
gem "lz4-ruby", require: false, platform: :ruby
gem "sanitize"
if ENV["IMPORT"] == "1"
gem "mysql2"
gem "redcarpet"
# NOTE: in import mode the version of sqlite can matter a lot, so we stick it to a specific one
gem "sqlite3", "~> 1.3", ">= 1.3.13"
gem "ruby-bbcode-to-md", git: "https://github.com/nlalonde/ruby-bbcode-to-md"
gem "reverse_markdown"
gem "tiny_tds"
gem "csv"
end
group :generic_import, optional: true do
gem "sqlite3"
gem "redcarpet"
end
gem "web-push"
gem "colored2", require: false
gem "maxminddb"
gem "rails_failover", require: false
gem "faraday"
gem "faraday-retry"
# workaround for faraday-net_http, see
# https://github.com/ruby/net-imap/issues/16#issuecomment-803086765
gem "net-http"
# Workaround until Ruby ships with cgi version 0.3.6 or higher.
gem "cgi", ">= 0.3.6", require: false
gem "tzinfo-data"
gem "csv", require: false
# dependencies for the automation plugin
gem "iso8601"
gem "rrule"
group :migrations, optional: true do
gem "extralite-bundle", require: "extralite"
# auto-loading
gem "zeitwerk"
# databases
gem "trilogy"
# CLI
gem "ruby-progressbar"
# non-cryptographic hashing algorithm for generating placeholder IDs
gem "digest-xxhash"
end
gem "dry-initializer", "~> 3.1"
gem "parallel"

View File

@@ -0,0 +1,748 @@
GEM
remote: https://rubygems.org/
specs:
actionmailer (7.2.2.1)
actionpack (= 7.2.2.1)
actionview (= 7.2.2.1)
activejob (= 7.2.2.1)
activesupport (= 7.2.2.1)
mail (>= 2.8.0)
rails-dom-testing (~> 2.2)
actionpack (7.2.2.1)
actionview (= 7.2.2.1)
activesupport (= 7.2.2.1)
nokogiri (>= 1.8.5)
racc
rack (>= 2.2.4, < 3.2)
rack-session (>= 1.0.1)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
useragent (~> 0.16)
actionview (7.2.2.1)
activesupport (= 7.2.2.1)
builder (~> 3.1)
erubi (~> 1.11)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
actionview_precompiler (0.4.0)
actionview (>= 6.0.a)
active_model_serializers (0.8.4)
activemodel (>= 3.0)
activejob (7.2.2.1)
activesupport (= 7.2.2.1)
globalid (>= 0.3.6)
activemodel (7.2.2.1)
activesupport (= 7.2.2.1)
activerecord (7.2.2.1)
activemodel (= 7.2.2.1)
activesupport (= 7.2.2.1)
timeout (>= 0.4.0)
activesupport (7.2.2.1)
base64
benchmark (>= 0.3)
bigdecimal
concurrent-ruby (~> 1.0, >= 1.3.1)
connection_pool (>= 2.2.5)
drb
i18n (>= 1.6, < 2)
logger (>= 1.4.2)
minitest (>= 5.1)
securerandom (>= 0.3)
tzinfo (~> 2.0, >= 2.0.5)
addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0)
annotate (3.2.0)
activerecord (>= 3.2, < 8.0)
rake (>= 10.4, < 14.0)
ast (2.4.2)
aws-eventstream (1.3.0)
aws-partitions (1.894.0)
aws-sdk-core (3.191.3)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.8)
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.77.0)
aws-sdk-core (~> 3, >= 3.191.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.143.0)
aws-sdk-core (~> 3, >= 3.191.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.8)
aws-sdk-sns (1.72.0)
aws-sdk-core (~> 3, >= 3.191.0)
aws-sigv4 (~> 1.1)
aws-sigv4 (1.8.0)
aws-eventstream (~> 1, >= 1.0.2)
base64 (0.2.0)
benchmark (0.4.0)
better_errors (2.10.1)
erubi (>= 1.0.0)
rack (>= 0.9.0)
rouge (>= 1.0.0)
bigdecimal (3.1.9)
binding_of_caller (1.0.1)
debug_inspector (>= 1.2.0)
bootsnap (1.18.4)
msgpack (~> 1.2)
builder (3.3.0)
bullet (8.0.0)
activesupport (>= 3.0.0)
uniform_notifier (~> 1.11)
byebug (11.1.3)
capybara (3.40.0)
addressable
matrix
mini_mime (>= 0.1.3)
nokogiri (~> 1.11)
rack (>= 1.6.0)
rack-test (>= 0.6.3)
regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2)
cbor (0.5.9.8)
certified (1.0.0)
cgi (0.4.1)
chunky_png (1.4.0)
coderay (1.1.3)
colored2 (4.0.3)
concurrent-ruby (1.3.5)
connection_pool (2.5.0)
cose (1.3.1)
cbor (~> 0.5.9)
openssl-signature_algorithm (~> 1.0)
cppjieba_rb (0.4.4)
crack (1.0.0)
bigdecimal
rexml
crass (1.0.6)
css_parser (1.21.0)
addressable
csv (3.3.2)
date (3.4.1)
debug_inspector (1.2.0)
diff-lcs (1.5.1)
diffy (3.4.3)
digest (3.2.0)
digest-xxhash (0.2.9)
discourse-fonts (0.0.18)
discourse-seed-fu (2.3.12)
activerecord (>= 3.1)
activesupport (>= 3.1)
discourse_dev_assets (0.0.4)
faker (~> 2.16)
literate_randomizer
docile (1.4.1)
drb (2.2.1)
dry-initializer (3.2.0)
email_reply_trimmer (0.2.0)
erubi (1.13.1)
excon (1.2.3)
execjs (2.10.0)
exifr (1.4.1)
extralite-bundle (2.8.2)
fabrication (2.31.0)
faker (2.23.0)
i18n (>= 1.8.11, < 2)
fakeweb (1.3.0)
faraday (2.12.2)
faraday-net_http (>= 2.0, < 3.5)
json
logger
faraday-net_http (3.4.0)
net-http (>= 0.5.0)
faraday-retry (2.2.1)
faraday (~> 2.0)
fast_blank (1.0.1)
fastimage (2.3.1)
ffi (1.17.1)
ffi (1.17.1-arm64-darwin)
ffi (1.17.1-x86_64-darwin)
fspath (3.1.2)
globalid (1.2.1)
activesupport (>= 6.1)
google-protobuf (4.29.3)
bigdecimal
rake (>= 13)
google-protobuf (4.29.3-arm64-darwin)
bigdecimal
rake (>= 13)
google-protobuf (4.29.3-x86_64-darwin)
bigdecimal
rake (>= 13)
guess_html_encoding (0.0.11)
hana (1.3.7)
hashdiff (1.1.2)
hashie (5.0.0)
highline (3.1.2)
reline
htmlentities (4.3.4)
http_accept_language (2.1.1)
i18n (1.14.7)
concurrent-ruby (~> 1.0)
image_optim (0.31.4)
exifr (~> 1.2, >= 1.2.2)
fspath (~> 3.0)
image_size (>= 1.5, < 4)
in_threads (~> 1.3)
progress (~> 3.0, >= 3.0.1)
image_size (3.4.0)
in_threads (1.6.0)
io-console (0.8.0)
irb (1.15.1)
pp (>= 0.6.0)
rdoc (>= 4.0.0)
reline (>= 0.4.2)
iso8601 (0.13.0)
jmespath (1.6.2)
json (2.9.1)
json-schema (5.1.1)
addressable (~> 2.8)
bigdecimal (~> 3.1)
json_schemer (2.4.0)
bigdecimal
hana (~> 1.3)
regexp_parser (~> 2.0)
simpleidn (~> 0.2)
jwt (2.10.1)
base64
kgio (2.11.4)
language_server-protocol (3.17.0.4)
libv8-node (22.7.0.4)
libv8-node (22.7.0.4-arm64-darwin)
libv8-node (22.7.0.4-x86_64-darwin)
listen (3.9.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
literate_randomizer (0.4.0)
logger (1.7.0)
lograge (0.14.0)
actionpack (>= 4)
activesupport (>= 4)
railties (>= 4)
request_store (~> 1.0)
logstash-event (1.2.02)
logster (2.20.0)
loofah (2.24.0)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
lru_redux (1.1.0)
lz4-ruby (0.3.3)
mail (2.8.1)
mini_mime (>= 0.1.1)
net-imap
net-pop
net-smtp
matrix (0.4.2)
maxminddb (0.1.22)
memory_profiler (1.1.0)
message_bus (4.3.8)
rack (>= 1.1.3)
messageformat-wrapper (1.1.0)
mini_racer (>= 0.6.3)
method_source (1.1.0)
mini_mime (1.1.5)
mini_portile2 (2.8.9)
mini_racer (0.17.0.pre13)
libv8-node (~> 22.7.0.4)
mini_scheduler (0.18.0)
sidekiq (>= 6.5, < 8.0)
mini_sql (1.6.0)
mini_suffix (0.3.3)
ffi (~> 1.9)
minio_runner (0.1.2)
minitest (5.25.4)
mocha (2.7.1)
ruby2_keywords (>= 0.0.5)
msgpack (1.7.5)
multi_json (1.15.0)
multi_xml (0.7.1)
bigdecimal (~> 3.1)
mustache (1.1.1)
net-http (0.6.0)
uri
net-imap (0.5.5)
date
net-protocol
net-pop (0.1.2)
net-protocol
net-protocol (0.2.2)
timeout
net-smtp (0.5.0)
net-protocol
nio4r (2.7.4)
nokogiri (1.18.2)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
nokogiri (1.18.2-arm64-darwin)
racc (~> 1.4)
nokogiri (1.18.2-x86_64-darwin)
racc (~> 1.4)
oauth (1.1.0)
oauth-tty (~> 1.0, >= 1.0.1)
snaky_hash (~> 2.0)
version_gem (~> 1.1)
oauth-tty (1.0.5)
version_gem (~> 1.1, >= 1.1.1)
oauth2 (1.4.11)
faraday (>= 0.17.3, < 3.0)
jwt (>= 1.0, < 3.0)
multi_json (~> 1.3)
multi_xml (~> 0.5)
rack (>= 1.2, < 4)
oj (3.16.9)
bigdecimal (>= 3.0)
ostruct (>= 0.2)
omniauth (1.9.2)
hashie (>= 3.4.6)
rack (>= 1.6.2, < 3)
omniauth-facebook (9.0.0)
omniauth-oauth2 (~> 1.2)
omniauth-github (1.4.0)
omniauth (~> 1.5)
omniauth-oauth2 (>= 1.4.0, < 2.0)
omniauth-google-oauth2 (0.8.2)
jwt (>= 2.0)
oauth2 (~> 1.1)
omniauth (~> 1.1)
omniauth-oauth2 (>= 1.6)
omniauth-oauth (1.2.1)
oauth
omniauth (>= 1.0, < 3)
rack (>= 1.6.2, < 4)
omniauth-oauth2 (1.7.3)
oauth2 (>= 1.4, < 3)
omniauth (>= 1.9, < 3)
omniauth-twitter (1.4.0)
omniauth-oauth (~> 1.1)
rack
openssl (3.3.0)
openssl-signature_algorithm (1.3.0)
openssl (> 2.0)
optimist (3.2.0)
ostruct (0.6.1)
parallel (1.26.3)
parallel_tests (4.9.0)
parallel
parser (3.3.7.0)
ast (~> 2.4.1)
racc
pg (1.5.9)
pp (0.6.2)
prettyprint
prettier_print (1.2.1)
prettyprint (0.2.0)
progress (3.6.0)
pry (0.14.2)
coderay (~> 1.1)
method_source (~> 1.0)
pry-byebug (3.10.1)
byebug (~> 11.0)
pry (>= 0.13, < 0.15)
pry-rails (0.3.11)
pry (>= 0.13.0)
pry-stack_explorer (0.6.1)
binding_of_caller (~> 1.0)
pry (~> 0.13)
psych (5.2.3)
date
stringio
public_suffix (6.0.1)
puma (6.6.0)
nio4r (~> 2.0)
racc (1.8.1)
rack (2.2.10)
rack-mini-profiler (3.3.1)
rack (>= 1.2.0)
rack-protection (3.2.0)
base64 (>= 0.1.0)
rack (~> 2.2, >= 2.2.4)
rack-session (1.0.2)
rack (< 3)
rack-test (2.2.0)
rack (>= 1.3)
rackup (1.0.1)
rack (< 3)
webrick
rails-dom-testing (2.2.0)
activesupport (>= 5.0.0)
minitest
nokogiri (>= 1.6)
rails-html-sanitizer (1.6.2)
loofah (~> 2.21)
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
rails_failover (2.2.0)
activerecord (>= 6.1, < 8.0)
concurrent-ruby
railties (>= 6.1, < 8.0)
rails_multisite (6.1.0)
activerecord (>= 6.0)
railties (>= 6.0)
railties (7.2.2.1)
actionpack (= 7.2.2.1)
activesupport (= 7.2.2.1)
irb (~> 1.13)
rackup (>= 1.0.0)
rake (>= 12.2)
thor (~> 1.0, >= 1.2.2)
zeitwerk (~> 2.6)
rainbow (3.1.1)
raindrops (0.20.1)
rake (13.2.1)
rb-fsevent (0.11.2)
rb-inotify (0.11.1)
ffi (~> 1.0)
rbtrace (0.5.1)
ffi (>= 1.0.6)
msgpack (>= 0.4.3)
optimist (>= 3.0.0)
rchardet (1.9.0)
rdoc (6.11.0)
psych (>= 4.0.0)
redcarpet (3.6.0)
redis (4.8.1)
redis-namespace (1.11.0)
redis (>= 4)
regexp_parser (2.10.0)
reline (0.6.0)
io-console (~> 0.5)
request_store (1.7.0)
rack (>= 1.4)
rexml (3.4.1)
rinku (2.0.6)
rotp (6.3.0)
rouge (4.5.1)
rqrcode (2.2.0)
chunky_png (~> 1.0)
rqrcode_core (~> 1.0)
rqrcode_core (1.2.0)
rrule (0.6.0)
activesupport (>= 2.3)
rspec (3.13.0)
rspec-core (~> 3.13.0)
rspec-expectations (~> 3.13.0)
rspec-mocks (~> 3.13.0)
rspec-core (3.13.2)
rspec-support (~> 3.13.0)
rspec-expectations (3.13.3)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
rspec-html-matchers (0.10.0)
nokogiri (~> 1)
rspec (>= 3.0.0.a)
rspec-mocks (3.13.2)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
rspec-multi-mock (0.3.1)
rspec (>= 3.7.0)
rspec-rails (7.1.0)
actionpack (>= 7.0)
activesupport (>= 7.0)
railties (>= 7.0)
rspec-core (~> 3.13)
rspec-expectations (~> 3.13)
rspec-mocks (~> 3.13)
rspec-support (~> 3.13)
rspec-support (3.13.2)
rss (0.3.1)
rexml
rswag-specs (2.16.0)
activesupport (>= 5.2, < 8.1)
json-schema (>= 2.2, < 6.0)
railties (>= 5.2, < 8.1)
rspec-core (>= 2.14)
rtlcss (0.2.1)
mini_racer (>= 0.6.3)
rubocop (1.71.1)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 2.9.3, < 3.0)
rubocop-ast (>= 1.38.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 4.0)
rubocop-ast (1.38.0)
parser (>= 3.3.1.0)
rubocop-capybara (2.21.0)
rubocop (~> 1.41)
rubocop-discourse (3.9.3)
activesupport (>= 6.1)
rubocop (>= 1.59.0)
rubocop-capybara (>= 2.0.0)
rubocop-factory_bot (>= 2.0.0)
rubocop-rails (>= 2.25.0)
rubocop-rspec (>= 3.0.1)
rubocop-rspec_rails (>= 2.30.0)
rubocop-factory_bot (2.26.1)
rubocop (~> 1.61)
rubocop-rails (2.29.1)
activesupport (>= 4.2.0)
rack (>= 1.1)
rubocop (>= 1.52.0, < 2.0)
rubocop-ast (>= 1.31.1, < 2.0)
rubocop-rspec (3.4.0)
rubocop (~> 1.61)
rubocop-rspec_rails (2.30.0)
rubocop (~> 1.61)
rubocop-rspec (~> 3, >= 3.0.1)
ruby-prof (1.7.1)
ruby-progressbar (1.13.0)
ruby-readability (0.7.2)
guess_html_encoding (>= 0.0.4)
nokogiri (>= 1.6.0)
ruby2_keywords (0.0.5)
rubyzip (2.4.1)
sanitize (7.0.0)
crass (~> 1.0.2)
nokogiri (>= 1.16.8)
sass-embedded (1.77.5)
google-protobuf (>= 3.25, < 5.0)
rake (>= 13)
sass-embedded (1.77.5-arm64-darwin)
google-protobuf (>= 3.25, < 5.0)
sass-embedded (1.77.5-x86_64-darwin)
google-protobuf (>= 3.25, < 5.0)
sassc-embedded (1.77.7)
sass-embedded (~> 1.77)
securerandom (0.4.1)
selenium-devtools (0.135.0)
selenium-webdriver (~> 4.2)
selenium-webdriver (4.31.0)
base64 (~> 0.2)
logger (~> 1.4)
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0)
websocket (~> 1.0)
shoulda-matchers (6.4.0)
activesupport (>= 5.2.0)
sidekiq (6.5.12)
connection_pool (>= 2.2.5, < 3)
rack (~> 2.0)
redis (>= 4.5.0, < 5)
simplecov (0.22.0)
docile (~> 1.1)
simplecov-html (~> 0.11)
simplecov_json_formatter (~> 0.1)
simplecov-html (0.13.1)
simplecov_json_formatter (0.1.4)
simpleidn (0.2.3)
snaky_hash (2.0.1)
hashie
version_gem (~> 1.1, >= 1.1.1)
sprockets (3.7.5)
base64
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
sprockets-rails (3.5.2)
actionpack (>= 6.1)
activesupport (>= 6.1)
sprockets (>= 3.0.0)
sqlite3 (2.5.0)
mini_portile2 (~> 2.8.0)
sqlite3 (2.5.0-arm64-darwin)
sqlite3 (2.5.0-x86_64-darwin)
sshkey (3.0.0)
stackprof (0.2.27)
stringio (3.1.2)
syntax_tree (6.2.0)
prettier_print (>= 1.2.0)
syntax_tree-disable_ternary (1.0.0)
test-prof (1.4.4)
thor (1.3.2)
timeout (0.4.3)
trilogy (2.9.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
tzinfo-data (1.2025.1)
tzinfo (>= 1.0.0)
uglifier (4.2.1)
execjs (>= 0.3.0, < 3)
unf (0.2.0)
unicode-display_width (3.1.4)
unicode-emoji (~> 4.0, >= 4.0.4)
unicode-emoji (4.0.4)
unicorn (6.1.0)
kgio (~> 2.6)
raindrops (~> 0.7)
uniform_notifier (1.16.0)
uri (1.0.2)
useragent (0.16.11)
version_gem (1.1.4)
web-push (3.0.1)
jwt (~> 2.0)
openssl (~> 3.0)
webmock (3.24.0)
addressable (>= 2.8.0)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
webrick (1.9.1)
websocket (1.2.11)
xpath (3.2.0)
nokogiri (~> 1.8)
yaml-lint (0.1.2)
yard (0.9.37)
zeitwerk (2.7.1)
PLATFORMS
arm64-darwin-21
arm64-darwin-22
arm64-darwin-23
arm64-darwin-24
ruby
x86_64-darwin-22
x86_64-darwin-23
x86_64-darwin-24
DEPENDENCIES
actionmailer (~> 7.2.0)
actionpack (~> 7.2.0)
actionview (~> 7.2.0)
actionview_precompiler
active_model_serializers (~> 0.8.3)
activemodel (~> 7.2.0)
activerecord (~> 7.2.0)
activesupport (~> 7.2.0)
addressable
annotate
aws-sdk-s3
aws-sdk-sns
better_errors
binding_of_caller
bootsnap
bullet
byebug
capybara
cbor
certified
cgi (>= 0.3.6)
colored2
cose
cppjieba_rb
css_parser
csv
diffy
digest
digest-xxhash
discourse-fonts
discourse-seed-fu
discourse_dev_assets
dry-initializer (~> 3.1)
email_reply_trimmer
excon
execjs
extralite-bundle
fabrication
faker (~> 2.16)
fakeweb
faraday
faraday-retry
fast_blank
fastimage
highline
htmlentities
http_accept_language
image_optim
iso8601
json
json_schemer
listen
lograge
logstash-event
logster
loofah
lru_redux
lz4-ruby
mail
maxminddb
memory_profiler
message_bus
messageformat-wrapper
mini_mime
mini_racer (= 0.17.pre13)
mini_scheduler
mini_sql
mini_suffix
minio_runner
mocha
multi_json
mustache
net-http
net-imap
net-pop
net-smtp
nokogiri
oj
omniauth
omniauth-facebook
omniauth-github
omniauth-google-oauth2
omniauth-oauth2
omniauth-twitter
parallel
parallel_tests
pg
pry-byebug
pry-rails
pry-stack_explorer
puma
rack
rack-mini-profiler
rack-protection
rails-dom-testing
rails_failover
rails_multisite
railties (~> 7.2.0)
rake
rb-fsevent
rbtrace
rchardet
redcarpet
redis (< 5.0)
redis-namespace
rinku
rotp
rqrcode
rrule
rspec
rspec-html-matchers
rspec-multi-mock
rspec-rails
rss
rswag-specs
rtlcss
rubocop-discourse
ruby-prof
ruby-progressbar
ruby-readability
rubyzip
sanitize
sassc-embedded
selenium-devtools
selenium-webdriver (~> 4.14)
shoulda-matchers
sidekiq
simplecov
sprockets (~> 3.7.3)
sprockets-rails
sqlite3
sshkey
stackprof
syntax_tree
syntax_tree-disable_ternary
test-prof
thor
trilogy
tzinfo-data
uglifier
unf
unicorn
web-push
webmock
yaml-lint
yard
zeitwerk
BUNDLED WITH
2.6.9

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,25 @@
diff --git a/config/unicorn.conf.rb b/config/unicorn.conf.rb
index b8c549bc0f..a7d3592013 100644
--- a/config/unicorn.conf.rb
+++ b/config/unicorn.conf.rb
@@ -35,19 +35,7 @@ FileUtils.mkdir_p("#{discourse_path}/tmp/pids") if !File.exist?("#{discourse_pat
# feel free to point this anywhere accessible on the filesystem
pid(ENV["UNICORN_PID_PATH"] || "#{discourse_path}/tmp/pids/unicorn.pid")
-if ENV["RAILS_ENV"] == "production"
- # By default, the Unicorn logger will write to stderr.
- # Additionally, some applications/frameworks log to stderr or stdout,
- # so prevent them from going to /dev/null when daemonized here:
- stderr_path unicorn_stderr_path
- stdout_path unicorn_stdout_path
-
- # nuke workers after 30 seconds instead of 60 seconds (the default)
- timeout 30
-else
- # we want a longer timeout in dev cause first request can be really slow
- timeout(ENV["UNICORN_TIMEOUT"] && ENV["UNICORN_TIMEOUT"].to_i || 60)
-end
+timeout(ENV["UNICORN_TIMEOUT"] && ENV["UNICORN_TIMEOUT"].to_i || 60)
# important for Ruby 2.0
preload_app true

View File

@@ -0,0 +1,446 @@
#!/usr/bin/env nix-shell
#! nix-shell -i python3 -p "python3.withPackages (ps: with ps; [ requests click click-log packaging ])" bundix bundler nix-update nurl
from __future__ import annotations
import click
import click_log
import shutil
import tempfile
import re
import logging
import subprocess
import os
import stat
import json
import requests
import textwrap
from functools import total_ordering
from packaging.version import Version
from pathlib import Path
from typing import Union, Iterable
logger = logging.getLogger(__name__)
@total_ordering
class DiscourseVersion:
"""Represents a Discourse style version number and git tag.
This takes either a tag or version string as input and
extrapolates the other. Sorting is implemented to work as expected
in regard to A.B.C.betaD version numbers - 2.0.0.beta1 is
considered lower than 2.0.0.
"""
tag: str = ""
version: str = ""
split_version: Iterable[Union[None, int, str]] = []
def __init__(self, version: str):
"""Take either a tag or version number, calculate the other."""
if version.startswith('v'):
self.tag = version
self.version = version.lstrip('v')
else:
self.tag = 'v' + version
self.version = version
self._version = Version(self.version)
def __eq__(self, other: DiscourseVersion):
"""Versions are equal when their individual parts are."""
return self._version == other._version
def __gt__(self, other: DiscourseVersion):
"""Check if this version is greater than the other."""
return self._version > other._version
class DiscourseRepo:
version_regex = re.compile(r'^v\d+\.\d+\.\d+(\.beta\d+)?$')
_latest_commit_sha = None
def __init__(self, owner: str = 'discourse', repo: str = 'discourse'):
self.owner = owner
self.repo = repo
@property
def versions(self) -> Iterable[str]:
r = requests.get(f'https://api.github.com/repos/{self.owner}/{self.repo}/git/refs/tags').json()
tags = [x['ref'].replace('refs/tags/', '') for x in r]
# filter out versions not matching version_regex
versions = filter(self.version_regex.match, tags)
versions = [DiscourseVersion(x) for x in versions]
versions.sort(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
def get_file(self, filepath, rev):
"""Return file contents at a given rev.
:param str filepath: the path to the file, relative to the repo root
:param str rev: the rev to fetch at :return:
"""
r = requests.get(f'https://raw.githubusercontent.com/{self.owner}/{self.repo}/{rev}/{filepath}')
r.raise_for_status()
return r.text
def _get_build_lock_hash():
nixpkgs_path = Path(__file__).parent / '../../../../'
output = subprocess.run(['nix-build', '-A', 'discourse'], text=True, cwd=nixpkgs_path, capture_output=True)
# The line is of the form " got: sha256-xxx"
lines = [i.strip() for i in output.stderr.splitlines()]
new_hash_lines = [i.strip("got:").strip() for i in lines if i.startswith("got:")]
if len(new_hash_lines) == 0:
if output.returncode != 0:
print("Error while fetching new hash with nix build")
print(output.stderr)
print("No hash change is needed")
return None
if len(new_hash_lines) > 1:
print(new_hash_lines)
raise Exception("Got an unexpected number of new hash lines:")
return new_hash_lines[0]
def _call_nix_update(pkg, version):
"""Call nix-update from nixpkgs root dir."""
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 / '../../../../'
try:
output = subprocess.check_output(['nix-instantiate', '--strict', '--json', '--eval', '-E', f'(with import {nixpkgs_path} {{}}; {expr})'], text=True)
except subprocess.CalledProcessError:
return None
return json.loads(output)
def _get_current_package_version(pkg: str):
return _nix_eval(f'{pkg}.version')
def _diff_file(filepath: str, old_version: DiscourseVersion, new_version: DiscourseVersion):
repo = DiscourseRepo()
current_dir = Path(__file__).parent
old = repo.get_file(filepath, old_version.tag)
new = repo.get_file(filepath, new_version.tag)
if old == new:
click.secho(f'{filepath} is unchanged', fg='green')
return
with tempfile.NamedTemporaryFile(mode='w') as o, tempfile.NamedTemporaryFile(mode='w') as n:
o.write(old), n.write(new)
width = shutil.get_terminal_size((80, 20)).columns
diff_proc = subprocess.run(
['diff', '--color=always', f'--width={width}', '-y', o.name, n.name],
stdout=subprocess.PIPE,
cwd=current_dir,
text=True
)
click.secho(f'Diff for {filepath} ({old_version.version} -> {new_version.version}):', fg='bright_blue', bold=True)
click.echo(diff_proc.stdout + '\n')
return
def _remove_platforms(rubyenv_dir: Path):
for platform in ['arm64-darwin-20', 'x86_64-darwin-18',
'x86_64-darwin-19', 'x86_64-darwin-20',
'x86_64-linux', 'aarch64-linux']:
with open(rubyenv_dir / 'Gemfile.lock', 'r') as f:
for line in f:
if platform in line:
subprocess.check_output(
['bundle', 'lock', '--remove-platform', platform], cwd=rubyenv_dir)
break
@click_log.simple_verbosity_option(logger)
@click.group()
def cli():
pass
@cli.command()
@click.argument('rev', default='latest')
@click.option('--reverse/--no-reverse', default=False, help='Print diffs from REV to current.')
def print_diffs(rev, reverse):
"""Print out diffs for files used as templates for the NixOS module.
The current package version found in the nixpkgs worktree the
script is run from will be used to download the "from" file and
REV used to download the "to" file for the diff, unless the
'--reverse' flag is specified.
REV should be the git rev to find changes in ('vX.Y.Z') or
'latest'; defaults to 'latest'.
"""
if rev == 'latest':
repo = DiscourseRepo()
rev = repo.versions[0].tag
old_version = DiscourseVersion(_get_current_package_version('discourse'))
new_version = DiscourseVersion(rev)
if reverse:
old_version, new_version = new_version, old_version
for f in ['config/nginx.sample.conf', 'config/discourse_defaults.conf']:
_diff_file(f, old_version, new_version)
@cli.command()
@click.argument('rev', default='latest')
def update(rev):
"""Update gem files and version.
REV: the git rev to update to ('vX.Y.Z[.betaA]') or
'latest'; defaults to 'latest'.
"""
repo = DiscourseRepo()
if rev == 'latest':
version = repo.versions[0]
else:
version = DiscourseVersion(rev)
logger.debug(f"Using rev {version.tag}")
logger.debug(f"Using version {version.version}")
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, version.tag))
# work around https://github.com/nix-community/bundix/issues/8
os.environ["BUNDLE_FORCE_RUBY_PLATFORM"] = "true"
subprocess.check_output(['bundle', 'lock'], cwd=rubyenv_dir)
_remove_platforms(rubyenv_dir)
subprocess.check_output(['bundix'], cwd=rubyenv_dir)
_call_nix_update('discourse', version.version)
old_pnpm_hash = _nix_eval('discourse.assets.pnpmDeps.outputHash')
new_pnpm_hash = _get_build_lock_hash()
if new_pnpm_hash is not None:
click.echo(f"Updating yarn lock hash: {old_pnpm_hash} -> {new_pnpm_hash}")
with open(Path(__file__).parent / "default.nix", 'r+') as f:
content = f.read()
content = content.replace(old_pnpm_hash, new_pnpm_hash)
f.seek(0)
f.write(content)
f.truncate()
@cli.command()
@click.argument('rev', default='latest')
def update_mail_receiver(rev):
"""Update discourse-mail-receiver.
REV: the git rev to update to ('vX.Y.Z') or 'latest'; defaults to
'latest'.
"""
repo = DiscourseRepo(repo="mail-receiver")
if rev == 'latest':
version = repo.versions[0]
else:
version = DiscourseVersion(rev)
_call_nix_update('discourse-mail-receiver', version.version)
@cli.command()
def update_plugins():
"""Update plugins to their latest revision."""
plugins = [
{'name': 'discourse-assign'},
{'name': 'discourse-bbcode-color'},
{'name': 'discourse-calendar'},
{'name': 'discourse-canned-replies'},
{'name': 'discourse-chat-integration'},
{'name': 'discourse-checklist'},
{'name': 'discourse-data-explorer'},
{'name': 'discourse-docs'},
{'name': 'discourse-github'},
{'name': 'discourse-ldap-auth', 'owner': 'jonmbake'},
{'name': 'discourse-math'},
{'name': 'discourse-migratepassword', 'owner': 'discoursehosting'},
{'name': 'discourse-openid-connect'},
{'name': 'discourse-prometheus'},
{'name': 'discourse-reactions'},
{'name': 'discourse-saved-searches'},
{'name': 'discourse-solved'},
{'name': 'discourse-spoiler-alert'},
{'name': 'discourse-voting', 'repo_name': "discourse-topic-voting"},
{'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
if fetcher == "fetchFromGitHub":
url = f"https://github.com/{owner}/{repo_name}"
else:
raise NotImplementedError(f"Missing URL pattern for {fetcher}")
repo = DiscourseRepo(owner=owner, repo=repo_name)
# implement the plugin pinning algorithm laid out here:
# https://meta.discourse.org/t/pinning-plugin-and-theme-versions-for-older-discourse-installs/156971
# this makes sure we don't upgrade plugins to revisions that
# are incompatible with the packaged Discourse version
repo_latest_commit = repo.latest_commit_sha
try:
compatibility_spec = repo.get_file('.discourse-compatibility', repo_latest_commit)
versions = [(DiscourseVersion(discourse_version), plugin_rev.strip(' '))
for [discourse_version, plugin_rev]
in [line.lstrip("< ").split(':')
for line
in compatibility_spec.splitlines() if line != '']]
discourse_version = DiscourseVersion(_get_current_package_version('discourse'))
versions = list(filter(lambda ver: ver[0] >= discourse_version, versions))
if versions == []:
rev = repo_latest_commit
else:
rev = versions[0][1]
print(rev)
except requests.exceptions.HTTPError:
rev = repo_latest_commit
filename = _nix_eval(f'builtins.unsafeGetAttrPos "src" discourse.plugins.{name}')
if filename is None:
filename = Path(__file__).parent / 'plugins' / name / 'default.nix'
filename.parent.mkdir()
has_ruby_deps = False
for line in repo.get_file('plugin.rb', rev).splitlines():
if 'gem ' in line:
has_ruby_deps = True
break
with open(filename, 'w') as f:
f.write(textwrap.dedent(f"""
{{ lib, mkDiscoursePlugin, fetchFromGitHub }}:
mkDiscoursePlugin {{
name = "{name}";"""[1:] + ("""
bundlerEnvArgs.gemdir = ./.;""" if has_ruby_deps else "") + f"""
src = {fetcher} {{
owner = "{owner}";
repo = "{repo_name}";
rev = "replace-with-git-rev";
sha256 = "replace-with-sha256";
}};
meta = with lib; {{
homepage = "";
maintainers = with maintainers; [ ];
license = licenses.mit; # change to the correct license!
description = "";
}};
}}"""))
all_plugins_filename = Path(__file__).parent / 'plugins' / 'all-plugins.nix'
with open(all_plugins_filename, 'r+') as f:
content = f.read()
pos = -1
while content[pos] != '}':
pos -= 1
content = content[:pos] + f' {name} = callPackage ./{name} {{}};' + os.linesep + content[pos:]
f.seek(0)
f.write(content)
f.truncate()
else:
filename = filename['file']
prev_commit_sha = _nix_eval(f'discourse.plugins.{name}.src.rev')
if prev_commit_sha == rev:
click.echo(f'Plugin {name} is already at the latest revision')
continue
prev_hash = _nix_eval(f'discourse.plugins.{name}.src.outputHash')
new_hash = subprocess.check_output([
"nurl",
"--fetcher", fetcher,
"--hash",
url,
rev,
], text=True).strip("\n")
click.echo(f"Update {name}, {prev_commit_sha} -> {rev} in {filename}")
with open(filename, 'r+') as f:
content = f.read()
content = content.replace(prev_commit_sha, rev)
content = content.replace(prev_hash, new_hash)
f.seek(0)
f.write(content)
f.truncate()
rubyenv_dir = Path(filename).parent
gemfile = rubyenv_dir / "Gemfile"
version_file_regex = re.compile(r'.*File\.expand_path\("\.\./(.*)", __FILE__\)')
gemfile_text = ''
plugin_file = repo.get_file('plugin.rb', rev)
plugin_file = plugin_file.replace(",\n", ", ") # fix split lines
for line in plugin_file.splitlines():
if 'gem ' in line:
line = ','.join(filter(lambda x: ":require_name" not in x, line.split(',')))
gemfile_text = gemfile_text + line + os.linesep
version_file_match = version_file_regex.match(line)
if version_file_match is not None:
filename = version_file_match.groups()[0]
content = repo.get_file(filename, rev)
with open(rubyenv_dir / filename, 'w') as f:
f.write(content)
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', '--add-platform', 'ruby'], cwd=rubyenv_dir)
subprocess.check_output(['bundle', 'lock', '--update'], cwd=rubyenv_dir)
_remove_platforms(rubyenv_dir)
subprocess.check_output(['bundix'], cwd=rubyenv_dir)
if __name__ == '__main__':
cli()