diff --git a/app/assets/javascripts/admin/addon/components/plugin-commit-hash.hbs b/app/assets/javascripts/admin/addon/components/plugin-commit-hash.hbs
new file mode 100644
index 00000000000..441febf757f
--- /dev/null
+++ b/app/assets/javascripts/admin/addon/components/plugin-commit-hash.hbs
@@ -0,0 +1,7 @@
+{{#if this.commitHash}}
+ {{this.shortCommitHash}}
+{{/if}}
\ No newline at end of file
diff --git a/app/assets/javascripts/admin/addon/components/plugin-commit-hash.js b/app/assets/javascripts/admin/addon/components/plugin-commit-hash.js
new file mode 100644
index 00000000000..0848db33c5e
--- /dev/null
+++ b/app/assets/javascripts/admin/addon/components/plugin-commit-hash.js
@@ -0,0 +1,11 @@
+import Component from "@glimmer/component";
+
+export default class PluginCommitHash extends Component {
+ get shortCommitHash() {
+ return this.commitHash?.slice(0, 7);
+ }
+
+ get commitHash() {
+ return this.args.plugin.commit_hash;
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/templates/plugins-index.hbs b/app/assets/javascripts/admin/addon/templates/plugins-index.hbs
index 36916108607..c02746557af 100644
--- a/app/assets/javascripts/admin/addon/templates/plugins-index.hbs
+++ b/app/assets/javascripts/admin/addon/templates/plugins-index.hbs
@@ -42,7 +42,8 @@
{{i18n "admin.plugins.version"}}
- {{plugin.version}}
+ {{plugin.version}}
+
|
{{i18n "admin.plugins.enabled"}}
diff --git a/app/assets/stylesheets/common/admin/plugins.scss b/app/assets/stylesheets/common/admin/plugins.scss
index 8a0061b5852..a070e836bea 100644
--- a/app/assets/stylesheets/common/admin/plugins.scss
+++ b/app/assets/stylesheets/common/admin/plugins.scss
@@ -11,6 +11,12 @@
font-weight: bold;
}
}
+ td.version {
+ .commit-hash {
+ color: var(--primary-low-mid);
+ font-size: var(--font-down-1);
+ }
+ }
.grid {
@media screen and (min-width: 550px) {
tr {
diff --git a/app/serializers/admin_plugin_serializer.rb b/app/serializers/admin_plugin_serializer.rb
index 75a0771612c..e80e157fc94 100644
--- a/app/serializers/admin_plugin_serializer.rb
+++ b/app/serializers/admin_plugin_serializer.rb
@@ -10,7 +10,9 @@ class AdminPluginSerializer < ApplicationSerializer
:enabled,
:enabled_setting,
:has_settings,
- :is_official
+ :is_official,
+ :commit_hash,
+ :commit_url
def id
object.directory_name
@@ -68,4 +70,12 @@ class AdminPluginSerializer < ApplicationSerializer
def is_official
Plugin::Metadata::OFFICIAL_PLUGINS.include?(object.name)
end
+
+ def commit_hash
+ object.commit_hash
+ end
+
+ def commit_url
+ object.commit_url
+ end
end
diff --git a/lib/discourse.rb b/lib/discourse.rb
index 728b559b618..1e5d85e66da 100644
--- a/lib/discourse.rb
+++ b/lib/discourse.rb
@@ -1141,6 +1141,7 @@ module Discourse
Discourse.git_version
Discourse.git_branch
Discourse.full_version
+ Discourse.plugins.each { |p| p.commit_url }
end,
Thread.new do
require "actionview_precompiler"
diff --git a/lib/git_repo.rb b/lib/git_repo.rb
new file mode 100644
index 00000000000..4d8dcb952ac
--- /dev/null
+++ b/lib/git_repo.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+class GitRepo
+ attr_reader :path, :name
+
+ def initialize(path, name = nil)
+ @path = path
+ @name = name
+ @memoize = {}
+ end
+
+ def url
+ url = run("config --get remote.origin.url")
+ return if url.blank?
+
+ url.sub!(/\Agit@github\.com:/, "https://github.com/")
+ url.sub!(/\.git\z/, "")
+ url
+ end
+
+ def latest_local_commit
+ run "rev-parse HEAD"
+ end
+
+ protected
+
+ def run(cmd)
+ @memoize[cmd] ||= begin
+ cmd = "git #{cmd}".split(" ")
+ Discourse::Utils.execute_command(*cmd, chdir: path).strip
+ rescue => e
+ Discourse.warn_exception(e, message: "Error running git command: #{cmd} in #{path}")
+ nil
+ end
+ end
+end
diff --git a/lib/plugin/instance.rb b/lib/plugin/instance.rb
index eba36d1f756..c1278def0a0 100644
--- a/lib/plugin/instance.rb
+++ b/lib/plugin/instance.rb
@@ -516,6 +516,19 @@ class Plugin::Instance
initializers << block
end
+ def commit_hash
+ git_repo.latest_local_commit
+ end
+
+ def commit_url
+ return if commit_hash.blank?
+ "#{git_repo.url}/commit/#{commit_hash}"
+ end
+
+ def git_repo
+ @git_repo ||= GitRepo.new(directory, name)
+ end
+
def before_auth(&block)
if @before_auth_complete
raise "Auth providers must be registered before omniauth middleware. after_initialize is too late!"
diff --git a/spec/lib/git_repo_spec.rb b/spec/lib/git_repo_spec.rb
new file mode 100644
index 00000000000..4620cf36422
--- /dev/null
+++ b/spec/lib/git_repo_spec.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+RSpec.describe GitRepo do
+ let(:git_repo) { GitRepo.new("/tmp", "discourse") }
+
+ it "returns the correct URL" do
+ Discourse::Utils.stubs(:execute_command).returns("https://github.com/username/my_plugin.git")
+ expect(git_repo.url).to eq("https://github.com/username/my_plugin")
+ Discourse::Utils.stubs(:execute_command).returns("git@github.com/username/my_plugin.git")
+ expect(git_repo.url).to eq("https://github.com/username/my_plugin")
+ end
+
+ it "returns the correct commit hash" do
+ Discourse::Utils.expects(:execute_command).returns("123456")
+ expect(git_repo.latest_local_commit).to eq("123456")
+ end
+end
diff --git a/spec/lib/plugin/instance_spec.rb b/spec/lib/plugin/instance_spec.rb
index ce202acb5a8..2957b94cab2 100644
--- a/spec/lib/plugin/instance_spec.rb
+++ b/spec/lib/plugin/instance_spec.rb
@@ -11,6 +11,13 @@ RSpec.describe Plugin::Instance do
expect(plugin.name).to eq("plugin-name")
expect(plugin.path).to eq("#{Rails.root}/spec/fixtures/plugins/my_plugin/plugin.rb")
+
+ git_repo = plugin.git_repo
+ plugin.git_repo.stubs(:latest_local_commit).returns("123456")
+ plugin.git_repo.stubs(:url).returns("http://github.com/discourse/discourse-plugin")
+
+ expect(plugin.commit_hash).to eq("123456")
+ expect(plugin.commit_url).to eq("http://github.com/discourse/discourse-plugin/commit/123456")
end
it "does not blow up on missing directory" do
diff --git a/spec/serializers/admin_plugin_serializer_spec.rb b/spec/serializers/admin_plugin_serializer_spec.rb
index 0ca42794713..6e242356606 100644
--- a/spec/serializers/admin_plugin_serializer_spec.rb
+++ b/spec/serializers/admin_plugin_serializer_spec.rb
@@ -11,4 +11,18 @@ RSpec.describe AdminPluginSerializer do
expect(subject.enabled_setting).to eq("test")
end
end
+
+ describe "commit_hash" do
+ it "should return commit_hash and commit_url" do
+ instance = Plugin::Instance.find_all("#{Rails.root}/spec/fixtures/plugins")[0]
+ subject = described_class.new(instance)
+
+ git_repo = instance.git_repo
+ git_repo.stubs(:latest_local_commit).returns("123456")
+ git_repo.stubs(:url).returns("http://github.com/discourse/discourse-plugin")
+
+ expect(subject.commit_hash).to eq("123456")
+ expect(subject.commit_url).to eq("http://github.com/discourse/discourse-plugin/commit/123456")
+ end
+ end
end
|