Various GitHub Onebox improvements (#13163)

Various GitHub Onebox improvements (#13163)

  • FIX: Improve GitHub folder regexp in Onebox

It used to match any GitHub URL that was not matched by the other GitHub Oneboxes and it did not do a good job at handling those. With this change, the generic Onebox will handle the remaining URLs.

  • FEATURE: Add Onebox for GitHub Actions

  • FEATURE: Add Onebox for PR check runs

  • FIX: Remove image from GitHub folder Oneboxes

It is a generic, auto-generated image which does not provide any value.

  • DEV: Add tests

  • FIX: Strip HTML comments from PR body

diff --git a/app/assets/javascripts/discourse/app/initializers/post-decorations.js b/app/assets/javascripts/discourse/app/initializers/post-decorations.js
index 4d34658..b425a81 100644
--- a/app/assets/javascripts/discourse/app/initializers/post-decorations.js
+++ b/app/assets/javascripts/discourse/app/initializers/post-decorations.js
@@ -88,6 +88,7 @@ export default {
 
       const oneboxTypes = {
         amazon: "discourse-amazon",
+        githubactions: "fab-github",
         githubblob: "fab-github",
         githubcommit: "fab-github",
         githubpullrequest: "fab-github",
diff --git a/app/assets/stylesheets/common/base/onebox.scss b/app/assets/stylesheets/common/base/onebox.scss
index 41f7aeb..ef88ca7 100644
--- a/app/assets/stylesheets/common/base/onebox.scss
+++ b/app/assets/stylesheets/common/base/onebox.scss
@@ -507,6 +507,49 @@ pre.onebox code {
   }
 }
 
+.onebox.githubactions {
+  h4 {
+    margin-top: 5px;
+    margin-bottom: 5px;
+  }
+
+  .github-row {
+    display: flex;
+  }
+
+  .github-icon-container {
+    display: flex;
+    align-items: flex-start;
+    margin-right: 5px;
+  }
+
+  .github-icon {
+    fill: var(--primary-medium);
+    width: var(--font-up-3);
+    height: var(--font-up-3);
+  }
+
+  .github-icon-success {
+    fill: var(--success);
+  }
+
+  .github-icon-failure {
+    fill: var(--danger);
+  }
+
+  .github-icon-pending {
+    fill: #dbab0a;
+  }
+
+  .github-info {
+    color: var(--primary-high);
+  }
+
+  .github-run-number {
+    color: var(--primary-medium);
+  }
+}
+
 //Onebox - Github - Pull request
 .onebox-body .github-commit-status {
   background: #f5f5f5;
diff --git a/lib/onebox/engine/github_actions_onebox.rb b/lib/onebox/engine/github_actions_onebox.rb
new file mode 100644
index 0000000..cdb7e16
--- /dev/null
+++ b/lib/onebox/engine/github_actions_onebox.rb
@@ -0,0 +1,87 @@
+# frozen_string_literal: true
+
+require_relative '../mixins/github_body'
+
+module Onebox
+  module Engine
+    class GithubActionsOnebox
+      include Engine
+      include LayoutSupport
+      include JSON
+
+      matches_regexp(/^https?:\/\/(?:www\.)?(?:(?:\w)+\.)?github\.com\/(?<org>.+)\/(?<repo>.+)\/(actions\/runs\/[[:digit:]]+|pull\/[[:digit:]]*\/checks\?check_run_id=[[:digit:]]+)/)
+      always_https
+
+      def url
+        if type == :actions_run
+          "https://api.github.com/repos/#{match[:org]}/#{match[:repo]}/actions/runs/#{match[:run_id]}"
+        elsif type == :pr_run
+          "https://api.github.com/repos/#{match[:org]}/#{match[:repo]}/check-runs/#{match[:check_run_id]}"
+        end
+      end
+
+      def self.priority
+        90 # overlaps with GithubPullRequestOnebox
+      end
+
+      private
+
+      def match_url
+        return if defined?(@match) && defined?(@type)
+
+        if match = @url.match(/^https?:\/\/(?:www\.)?(?:(?:\w)+\.)?github\.com\/(?<org>.+)\/(?<repo>.+)\/actions\/runs\/(?<run_id>[[:digit:]]+)/)
+          @match = match
+          @type = :actions_run
+        end
+
+        if match = @url.match(/^https?:\/\/(?:www\.)?(?:(?:\w)+\.)?github\.com\/(?<org>.+)\/(?<repo>.+)\/pull\/(?<pr_id>[[:digit:]]*)\/checks\?check_run_id=(?<check_run_id>[[:digit:]]+)/)
+          @match = match
+          @type = :pr_run
+        end
+      end
+
+      def match
+        return @match if defined?(@match)
+
+        match_url
+        @match
+      end
+
+      def type
+        return @type if defined?(@type)
+
+        match_url
+        @type
+      end
+
+      def data
+        status = "unknown"
+        if raw["status"] == "completed"
+          if raw["conclusion"] == "success"
+            status = "success"
+          elsif raw["conclusion"] == "failure"
+            status = "failure"
+          elsif raw["conclusion"] == "cancelled"
+          end
+        elsif raw["status"] == "in_progress"
+          status = "pending"
+        end
+
+        title = if type == :actions_run
+          raw["head_commit"]["message"].lines.first
+        elsif type == :pr_run
+          pr_url = "https://api.github.com/repos/#{match[:org]}/#{match[:repo]}/pulls/#{match[:pr_id]}"
+          ::MultiJson.load(URI.open(pr_url, read_timeout: timeout))["title"]
+        end
+
+        {
+          link: @url,
+          title: title,
+          name: raw["name"],
+          run_number: raw["run_number"],
+          status => true,
+        }
+      end
+    end
+  end
+end
diff --git a/lib/onebox/engine/github_folder_onebox.rb b/lib/onebox/engine/github_folder_onebox.rb
index a0c565f..fb8bbe1 100644
--- a/lib/onebox/engine/github_folder_onebox.rb
+++ b/lib/onebox/engine/github_folder_onebox.rb
@@ -7,14 +7,9 @@ module Onebox
       include StandardEmbed
       include LayoutSupport
 
-      matches_regexp(/^https?:\/\/(?:www\.)?(?:(?:\w)+\.)?(github)\.com[\:\d]*(\/[^\/]+){2}/)
+      matches_regexp(/^https?:\/\/(?:www\.)?(?:(?:\w)+\.)?(github)\.com[\:\d]*(\/[^\/]+){2}\/tree/)
       always_https
 
-      def self.priority
-        # This engine should have lower priority than the other Github engines
-        150
-      end
-
       private
 
       def data
@@ -46,7 +41,6 @@ module Onebox
 
         {
           link: url,
-          image: og.image,
           title: Onebox::Helpers.truncate(title, 250),
           path: display_path,
           description: display_description,
diff --git a/lib/onebox/mixins/github_body.rb b/lib/onebox/mixins/github_body.rb
index 22ee13a..f6c1e84 100644
--- a/lib/onebox/mixins/github_body.rb
+++ b/lib/onebox/mixins/github_body.rb
@@ -9,17 +9,18 @@ module Onebox
       end
 
       module InstanceMethods
-        GITHUB_COMMENT_REGEX = /(<!--.*?-->\r\n)/
+        GITHUB_COMMENT_REGEX = /<!--.*?-->/
         MAX_BODY_LENGTH = 80
-        def compute_body(body)
-          body = body.dup
-          excerpt = nil
 
-          body = (body || '').gsub(GITHUB_COMMENT_REGEX, '')
-          body = body.length > 0 ? body : nil
-          if body && body.length > MAX_BODY_LENGTH
-            excerpt = body[MAX_BODY_LENGTH..body.length].rstrip
-            body = body[0..MAX_BODY_LENGTH - 1]
+        def compute_body(body)
+          if body
+            body = body.gsub(GITHUB_COMMENT_REGEX, '').strip
+            if body.length == 0
+              body = nil
+            elsif body.length > MAX_BODY_LENGTH
+              excerpt = body[MAX_BODY_LENGTH..body.length].rstrip
+              body = body[0..MAX_BODY_LENGTH - 1]
+            end
           end
 
           [body, excerpt]
diff --git a/lib/onebox/templates/githubactions.mustache b/lib/onebox/templates/githubactions.mustache
new file mode 100644
index 0000000..e8ddaaa
--- /dev/null
+++ b/lib/onebox/templates/githubactions.mustache
@@ -0,0 +1,31 @@
+<div class="github-row">
+  <div class="github-icon-container" title="Commit">
+    {{#success}}
+      <svg width="24" height="24" class="github-icon github-icon-success" viewBox="0 0 24 24" aria-hidden="true"><path fill-rule="evenodd" d="M1 12C1 5.925 5.925 1 12 1s11 4.925 11 11-4.925 11-11 11S1 18.075 1 12zm16.28-2.72a.75.75 0 00-1.06-1.06l-5.97 5.97-2.47-2.47a.75.75 0 00-1.06 1.06l3 3a.75.75 0 001.06 0l6.5-6.5z"></path></svg>
+    {{/success}}
+
+    {{#pending}}
+      <svg width="24" height="24" class="github-icon github-icon-pending" viewBox="0 0 24 24" aria-hidden="true"><path d="M12 18a6 6 0 100-12 6 6 0 000 12z"></path></svg>
+    {{/pending}}
+
+    {{#failure}}
+      <svg width="24" height="24" class="github-icon github-icon-failure" viewBox="0 0 24 24" aria-hidden="true"><path fill-rule="evenodd" d="M1 12C1 5.925 5.925 1 12 1s11 4.925 11 11-4.925 11-11 11S1 18.075 1 12zm8.036-4.024a.75.75 0 00-1.06 1.06L10.939 12l-2.963 2.963a.75.75 0 101.06 1.06L12 13.06l2.963 2.964a.75.75 0 001.061-1.06L13.061 12l2.963-2.964a.75.75 0 10-1.06-1.06L12 10.939 9.036 7.976z"></path></svg>
+    {{/failure}}
+
+    {{#unknown}}

[... diff too long, it was truncated ...]

GitHub sha: 723d7de1

This commit appears in #13163 which was approved by ZogStriP. It was merged by udan11.