Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Capture Grid view in Release Summary Report #596

Closed
4 tasks
llxia opened this issue Jan 25, 2022 · 15 comments
Closed
4 tasks

Capture Grid view in Release Summary Report #596

llxia opened this issue Jan 25, 2022 · 15 comments
Labels
enhancement New feature or request epic

Comments

@llxia
Copy link
Contributor

llxia commented Jan 25, 2022

Background:
In Release Summary Report, we display all failed builds. It is very useful for triaging. However, it lacks an overview of the pipeline status. It would be great if we can capture the Grid view in Release Summary Report.

For example, the Release Summary Report will become:

Release Summary Report for openjdk8-pipeline

TRSS Build and TRSS Grid View
Jenkins Build URL https://ci.adoptopenjdk.net/job/build-scripts/job/openjdk8-pipeline/1950/
Started by user George Adams at 1/25/2022, 5:47:27 AM


create_installer_linux ❌ undefined ❌


Test_openjdk8_hs_extended.openjdk_arm_linux ⚠️ UNSTABLE ⚠️

Test_openjdk8_hs_extended.openjdk_arm_linux_testList_0 ⚠️ UNSTABLE ⚠️
jdk_net_2 => deep history 1/2 passed | possible issues
jdk_tools_2 => deep history 0/2 passed | possible issues

Test_openjdk8_hs_extended.openjdk_arm_linux_testList_1 ⚠️ UNSTABLE ⚠️
hotspot_jre_2 => deep history 0/2 passed | possible issues
jdk_management_2 => deep history 0/2 passed | possible issues

Test_openjdk8_hs_extended.openjdk_arm_linux_testList_2 ⚠️ UNSTABLE ⚠️
jdk_beans_2 => deep history 0/2 passed | possible issues
jdk_other_2 => deep history 1/2 passed | possible issues
jdk_security4_2 => deep history 1/2 passed | possible issues
jdk_jfr_2 => deep history 0/2 passed | possible issues
jdk_imageio_2 => deep history 0/2 passed | possible issues

Test_openjdk8_hs_sanity.openjdk_arm_linux ⚠️ UNSTABLE ⚠️
jdk_util_2 => deep history 1/6 passed | possible issues
jdk_jdi_jdk8_2 => deep history 0/6 passed | possible issues

Test_openjdk8_hs_sanity.system_arm_linux ⚠️ UNSTABLE ⚠️
TestJlmRemoteMemoryAuth_2 => deep history 2/6 passed | possible issues
TestJlmRemoteMemoryNoAuth_2 => deep history 4/6 passed | possible issues
TestJlmRemoteClassAuth_2 => deep history 4/6 passed | possible issues
TestJlmRemoteNotifierProxyAuth_2 => deep history 5/6 passed | possible issues
TestJlmRemoteClassNoAuth_2 => deep history 3/6 passed | possible issues
TestJlmRemoteThreadAuth_2 => deep history 3/6 passed | possible issues
MauveSingleThrdLoad_HS_5m_2 => deep history 5/6 passed | possible issues
TestJlmRemoteThreadNoAuth_2 => deep history 3/6 passed | possible issues
MauveSingleInvocLoad_HS_5m_2 => deep history 5/6 passed | possible issues

Click to see the Grid view!

image

Implementation:

  • Investigate git (i.e., githubusercontent) API for uploading an image

  • Capture Grid view using https://html2canvas.hertzen.com/

  • Capture the Grid view and upload to githubusercontent once the user clicks on Release Summary Report

  • Update Release Summary Report to add the collapsible section with Grid view image. For example:

<details>
  <summary>Click to see the Grid view!</summary>
  
![image](https://user-images.githubusercontent.com/19273206/151177104-b9917c13-0a5e-4534-af21-6fcd08fb04f0.png)
</details>

@tommytwm
Copy link
Contributor

I can take this!

@tommytwm
Copy link
Contributor

tommytwm commented Jan 31, 2022

Investigate git (i.e., githubusercontent) API for uploading an image

In my investigation, it seems that there isn't a direct API available for us to upload images to Markdown that recreates the copy and paste image on comment/thread in GitHub. Based on a stack overflow thread it seems that he closest implementation would be to commit an image into the repository itself, which is not ideal since we do not want to upload all snapshots images of the reports to the repo.

Alternatively, a Medium article references Markdown Monster in which we can reference raw HTML in Markdown. This allows us to insert base64 content into Markdown:
image
The website offers a free download or install via chocolatey but recommends purchasing or obtaining a license for contributors and/or organizations.

Since we will be using html2canvas to generate a screenshot/image of the Grid view, I propose some alternatives:

  1. We can embed the image in some local cache. I'm unsure if this will prevent users from copying the README to clipboard since they will be copying the temporary directory.
  2. We write a script to upload the image to Imgur and then reference the url after. But this likely means we'll be uploading all images to Imgur whenever we direct users to the Release Summary Report. Is this safe and sustainable?
    2.1. Do we have a remote sever that we can use to upload the images?

Thoughts?

@smlambert
Copy link
Contributor

thank you for this excellent analysis @tommytwm, I have responded in Slack and reiterate here... based on your findings, we must reconsider this approach. Rather than capture grid view and include with release report, we should consider alternative ways to achieve the requirement of succinctly indicated the entirety of what was run in a pipeline (including passing jobs). To this end, we can start with a simple listing of passing jobs, or translate the Grid view into markdown tables.

@llxia
Copy link
Contributor Author

llxia commented Feb 1, 2022

Could we try one last thing before we look into other alternatives?

It looks like the https://github.com/upload/policies/assets API is used for uploading images. authenticity_token is required for the POST request. It would be great if we could give it a try.

image

image

@smlambert
Copy link
Contributor

We can intend to use https://github.com/eclipse-aqavit-bot for this.

FYI @gdams

@llxia
Copy link
Contributor Author

llxia commented Feb 7, 2022

@tommytwm There are 2 API calls.

  1. calls https://github.com/upload/policies/assets to get aws URL
  2. calls aws to upload
Click to see the testing code!
const fetch = require("node-fetch");
const FormData = require("form-data");
const fs = require("fs");
(async () => {
  const doFetch = async (...args) => {
    return (await fetch(...args)).json();
  };

  const file = fs.readFileSync("<path to image>");
  const form1 = new FormData();
  form1.append("content_type", "image/jpeg");
  form1.append("authenticity_token", "<token>");
  form1.append("repository_id", "<repo id>");
  form1.append("size", file.length);
  form1.append("name", "very high building.jpg");

  const { upload_url, asset, form } = await doFetch("https://github.com/upload/policies/assets", {
    headers: {
      accept: "application/json",
      ...form1.getHeaders(),
      cookie: "user_session=<cookie>; __Host-user_session_same_site=<cookie>;",
    },
    body: form1.getBuffer(),
    method: "POST",
  });
  console.log(asset, form);

  const form2 = new FormData();
  for (let key of Object.keys(form)) {
    form2.append(key, form[key]);
  }
  form2.append("file", file);
  const res2 = await fetch(upload_url, {
    headers: {
      ...form2.getHeaders(),
    },
    body: form2.getBuffer(),
    method: "POST",
  });
  console.log(res2);
})();

The above code works in my local. Please give it a try. Assuming we have the token and repo id, we need to figure out how to get cookie info.

@tommytwm
Copy link
Contributor

tommytwm commented Feb 8, 2022

I'm having some issues with getting the dependencies to work. I'll get back to you later today to see if I'm able to run the dependencies.

[nodemon] restarting due to changes...
[nodemon] starting `node frontend.js --configFile=./trssConf.json`
4:25:44 PM - warn: Cannot find the config file:  --configFile=./trssConf.json
internal/modules/cjs/loader.js:1015
      throw new ERR_REQUIRE_ESM(filename, parentPath, packageJsonPath);
      ^

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /Users/tommytho/Documents/UBC/aqa-test-tools/TestResultSummaryService/node_modules/node-fetch/src/index.js
require() of ES modules is not supported.
require() of /Users/tommytho/Documents/UBC/aqa-test-tools/TestResultSummaryService/node_modules/node-fetch/src/index.js from /Users/tommytho/Documents/UBC/aqa-test-tools/TestResultSummaryService/routes/getParents.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename index.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /Users/tommytho/Documents/UBC/aqa-test-tools/TestResultSummaryService/node_modules/node-fetch/package.json.

    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1015:13)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Module.require (internal/modules/cjs/loader.js:887:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at Object.<anonymous> (/Users/tommytho/Documents/UBC/aqa-test-tools/TestResultSummaryService/routes/getParents.js:2:15)
    at Module._compile (internal/modules/cjs/loader.js:999:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Module.require (internal/modules/cjs/loader.js:887:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at Object.<anonymous> (/Users/tommytho/Documents/UBC/aqa-test-tools/TestResultSummaryService/routes/index.js:30:31)
    at Module._compile (internal/modules/cjs/loader.js:999:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32) {
  code: 'ERR_REQUIRE_ESM'
}
[nodemon] app crashed - waiting for file changes before starting...```

@tommytwm
Copy link
Contributor

tommytwm commented Feb 8, 2022

Update: The code runs when I place it in getParents.js in TestResultsSummaryService backend, but I do not see a call being made to github. I assume this is running concurrently with an API call made to getParents, but could I get a confirmation on this?

@tommytwm
Copy link
Contributor

tommytwm commented Feb 8, 2022

image

getParents.js

const { TestResultsDB, ObjectID } = require( '../Database' );
const fetch = import("node-fetch");
const FormData = import("form-data");
const fs = import("fs");

module.exports = async ( req, res ) => {
    (async () => {
        const doFetch = async (...args) => {
          return (await fetch(...args)).json();
        };
      
        const file = fs.readFileSync("<path to image>");
        const form1 = new FormData();
        form1.append("content_type", "image/jpeg");
        form1.append("authenticity_token", "<token>");
        form1.append("repository_id", "<repo id>");
        form1.append("size", file.length);
        form1.append("name", "very high building.jpg");
      
        const { upload_url, asset, form } = await doFetch("https://github.com/upload/policies/assets", {
          headers: {
            accept: "application/json",
            ...form1.getHeaders(),
            cookie: "user_session=<cookie>; __Host-user_session_same_site=<cookie>;",
          },
          body: form1.getBuffer(),
          method: "POST",
        });
        console.log(asset, form);
      
        const form2 = new FormData();
        for (let key of Object.keys(form)) {
          form2.append(key, form[key]);
        }
        form2.append("file", file);
        const res2 = await fetch(upload_url, {
          headers: {
            ...form2.getHeaders(),
          },
          body: form2.getBuffer(),
          method: "POST",
        });
        console.log(res2);
      })();
      
    const db = new TestResultsDB();
    const result = [];

    let _id = new ObjectID( req.query.id );
    while ( _id ) {
        const build = await db.findOne( { _id }, { parentId: 1, buildName: 1, buildNum: 1, hasChildren: 1, type: 1 } );
        if ( !build )
            break;
        result.push( build );
        _id = build.parentId;
    }
    res.send( result.reverse() );
}

@llxia
Copy link
Contributor Author

llxia commented Feb 8, 2022

#596 (comment) is a quick POC. You need to fill the placeholder (<path to image>, <token>, <repo id>, etc) to make it work on your end. Also, you won't be able to see backend details from the frontend inspection.

@tommytwm
Copy link
Contributor

The above code works in my local. Please give it a try. Assuming we have the token and repo id, we need to figure out how to get cookie info.

I've managed to source some documentation regarding obtaining cookies:

  1. MDN Web Docs shows that calling Document.cookie will let us read all cookies associated with the document via the Document property. It is unclear what kind of information or what kind of payload we receive in return or if we need to set up the cookies ourselves in the client.
  2. In the same source, it shows a function call cookies.get() that calls the cookies API to retrieve information about a single cookie. This API call returns a Cookie object that contains attributes like domain (string), name (string), value (string), and session (boolean). I'm unsure if we would need to go through another issue to set up cookies in the service as well because it seems like there's some setting up required to enable these functions.

@tommytwm
Copy link
Contributor

I'm having some issues with getting the dependencies to work. I'll get back to you later today to see if I'm able to run the dependencies.

[nodemon] restarting due to changes...
[nodemon] starting `node frontend.js --configFile=./trssConf.json`
4:25:44 PM - warn: Cannot find the config file:  --configFile=./trssConf.json
internal/modules/cjs/loader.js:1015
      throw new ERR_REQUIRE_ESM(filename, parentPath, packageJsonPath);
      ^

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /Users/tommytho/Documents/UBC/aqa-test-tools/TestResultSummaryService/node_modules/node-fetch/src/index.js
require() of ES modules is not supported.
require() of /Users/tommytho/Documents/UBC/aqa-test-tools/TestResultSummaryService/node_modules/node-fetch/src/index.js from /Users/tommytho/Documents/UBC/aqa-test-tools/TestResultSummaryService/routes/getParents.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename index.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /Users/tommytho/Documents/UBC/aqa-test-tools/TestResultSummaryService/node_modules/node-fetch/package.json.

    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1015:13)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Module.require (internal/modules/cjs/loader.js:887:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at Object.<anonymous> (/Users/tommytho/Documents/UBC/aqa-test-tools/TestResultSummaryService/routes/getParents.js:2:15)
    at Module._compile (internal/modules/cjs/loader.js:999:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Module.require (internal/modules/cjs/loader.js:887:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at Object.<anonymous> (/Users/tommytho/Documents/UBC/aqa-test-tools/TestResultSummaryService/routes/index.js:30:31)
    at Module._compile (internal/modules/cjs/loader.js:999:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32) {
  code: 'ERR_REQUIRE_ESM'
}
[nodemon] app crashed - waiting for file changes before starting...```

According to node-fetch documentation, ES Modules is only supported in node-fetch for up to version 2.

@tommytwm
Copy link
Contributor

The above code works in my local. Please give it a try. Assuming we have the token and repo id, we need to figure out how to get cookie info.

I've managed to source some documentation regarding obtaining cookies:

1. MDN Web Docs shows that calling [`Document.cookie`](https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie) will let us read all cookies associated with the document via the `Document` property. It is unclear what kind of information or what kind of payload we receive in return or if we need to set up the cookies ourselves in the client.

2. In the same source, it shows a function call [`cookies.get()`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/cookies/get) that calls the [cookies API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/cookies) to retrieve information about a single cookie. This API call returns a Cookie object that contains attributes like domain (string), name (string), value (string), and session (boolean). I'm unsure if we would need to go through another issue to set up cookies in the service as well because it seems like there's some setting up required to enable these functions.

I've tested the two approaches locally by simply printing out the document's cookie, but the most I've managed to score is an <empty string> response via calling console.log(document.cookie). I suspect that because the client is running locally, no cookies will be generated. I could be misunderstanding the approach to printing out the cookie, but what would be a workaround to see if we are getting the appropriate cookie fields so that we may pass them to the request header?

@llxia
Copy link
Contributor Author

llxia commented Nov 18, 2022

@momanmalik could you take a look at this one? Thanks

@smlambert
Copy link
Contributor

Closing this in favour of a simpler table view mentioned in #649

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request epic
Projects
None yet
Development

No branches or pull requests

3 participants