helloadhavan/github_issues huggingface dataset:
Repository: electron/electron
Pull request: perf: prefer `base::SplitStringPiece()` over `base::SplitString()`

Backport of #45924

See that PR for details.


Notes: none.

Changed files:
filename: shell/browser/ui/accelerator_util.cc
patch: @@ -7,6 +7,7 @@
 #include <stdio.h>
 
 #include <string>
+#include <string_view>
 #include <vector>
 
 #include "base/logging.h"
@@ -16,7 +17,7 @@
 
 namespace accelerator_util {
 
-bool StringToAccelerator(const std::string& shortcut,
+bool StringToAccelerator(const std::string_view shortcut,
                          ui::Accelerator* accelerator) {
   if (!base::IsStringASCII(shortcut)) {
     LOG(ERROR) << "The accelerator string can only contain ASCII characters, "
@@ -26,14 +27,14 @@ bool StringToAccelerator(const std::string& shortcut,
     return false;
   }
 
-  std::vector<std::string> tokens = base::SplitString(
+  const std::vector<std::string_view> tokens = base::SplitStringPiece(
       shortcut, "+", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
 
   // Now, parse it into an accelerator.
   int modifiers = ui::EF_NONE;
   ui::KeyboardCode key = ui::VKEY_UNKNOWN;
   std::optional<char16_t> shifted_char;
-  for (const auto& token : tokens) {
+  for (const std::string_view token : tokens) {
     ui::KeyboardCode code = electron::KeyboardCodeFromStr(token, &shifted_char);
     if (shifted_char)
       modifiers |= ui::EF_SHIFT_DOWN;

filename: shell/browser/ui/accelerator_util.h
patch: @@ -6,7 +6,7 @@
 #define ELECTRON_SHELL_BROWSER_UI_ACCELERATOR_UTIL_H_
 
 #include <map>
-#include <string>
+#include <string_view>
 
 #include "base/memory/raw_ptr.h"
 #include "shell/browser/ui/electron_menu_model.h"
@@ -21,7 +21,7 @@ typedef struct {
 typedef std::map<ui::Accelerator, MenuItem> AcceleratorTable;
 
 // Parse a string as an accelerator.
-bool StringToAccelerator(const std::string& shortcut,
+bool StringToAccelerator(std::string_view shortcut,
                          ui::Accelerator* accelerator);
 
 // Generate a table that contains menu model's accelerators and command ids.

filename: shell/common/node_bindings.cc
patch: @@ -395,14 +395,14 @@ void SetNodeOptions(base::Environment* env) {
     if (electron::fuses::IsNodeOptionsEnabled()) {
       std::string options;
       env->GetVar("NODE_OPTIONS", &options);
-      std::vector<std::string> parts = base::SplitString(
+      const std::vector<std::string_view> parts = base::SplitStringPiece(
           options, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
 
       bool is_packaged_app = electron::api::App::IsPackaged();
 
-      for (const auto& part : parts) {
+      for (const std::string_view part : parts) {
         // Strip off values passed to individual NODE_OPTIONs
-        std::string option = part.substr(0, part.find('='));
+        const std::string_view option = part.substr(0, part.find('='));
 
         if (is_packaged_app && !pkg_opts.contains(option)) {
           // Explicitly disallow majority of NODE_OPTIONS in packaged apps
Repository: huggingface/transformers
Pull request: Fix important models CI

# What does this PR do?

Minor. Fixes a few tests failing currently on the important test action, on llama/gemma/mistral/mixtral.

Changed files:
filename: tests/causal_lm_tester.py
patch: @@ -451,5 +451,4 @@ def test_flash_attn_2_equivalence(self):
 
                 logits = outputs.hidden_states[-1]
                 logits_fa = outputs_fa.hidden_states[-1]
-
-                assert torch.allclose(logits_fa, logits, atol=2e-3)
+                torch.testing.assert_close(logits_fa, logits, atol=3e-2, rtol=3e-2)

filename: tests/generation/test_utils.py
patch: @@ -2309,7 +2309,7 @@ def _test_attention_implementation(self, attn_implementation):
 
         set_model_tester_for_less_flaky_test(self)
         for model_class in self.all_generative_model_classes:
-            if not getattr(model_class, support_flag[attn_implementation]):
+            if attn_implementation != "eager" and not getattr(model_class, support_flag[attn_implementation]):
                 self.skipTest(f"{model_class.__name__} does not support `attn_implementation={attn_implementation}`")
 
             config, original_inputs_dict = self.prepare_config_and_inputs_for_generate()

filename: tests/models/kyutai_speech_to_text/test_modeling_kyutai_speech_to_text.py
patch: @@ -552,7 +552,7 @@ def _test_attention_implementation(self, attn_implementation):
         }
 
         for model_class in self.all_generative_model_classes:
-            if not getattr(model_class, support_flag[attn_implementation]):
+            if attn_implementation != "eager" and not getattr(model_class, support_flag[attn_implementation]):
                 self.skipTest(f"{model_class.__name__} does not support `attn_implementation={attn_implementation}`")
 
             config, original_inputs_dict = self.prepare_config_and_inputs_for_generate()

filename: tests/test_modeling_common.py
patch: @@ -4107,7 +4107,9 @@ def test_flash_attn_2_can_compile_with_attention_mask_None_without_graph_break(s
 
         config, _ = self.model_tester.prepare_config_and_inputs_for_common()
         cls = self._torch_compile_train_cls  # e.g. LlamaFroCausalLM
-        model = cls(config, attn_implementation="flash_attention_2").to(device=torch_device, dtype=torch_dtype)
+        model = cls._from_config(config, attn_implementation="flash_attention_2").to(
+            device=torch_device, dtype=torch_dtype
+        )
 
         inputs = {
             "input_ids": torch.randint(low=1, high=model.config.vocab_size, size=(2, 10), device=torch_device),
@@ -4137,7 +4139,7 @@ def flash_attention_padding_matches_padding_free_with_position_ids(
         }
 
         for model_class in self.all_generative_model_classes:
-            if not getattr(model_class, support_flag[attn_implementation]):
+            if attn_implementation != "eager" and not getattr(model_class, support_flag[attn_implementation]):
                 self.skipTest(f"{model_class.__name__} does not support {attn_implementation}")
 
             config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common()
Repository: vercel/next.js
Pull request: Update NextAdapter type and re-export

Just fixes up the type and re-exports it so it can be imported directly from `next`. Also fixes test file not being type checked which didn't catch missing optional fields.

Changed files:
filename: packages/next/src/server/config-shared.ts
patch: @@ -51,10 +51,10 @@ export type AdapterOutputs = Array<{
 
 export interface NextAdapter {
   name: string
-  modifyConfig(
+  modifyConfig?: (
     config: NextConfigComplete
-  ): Promise<NextConfigComplete> | NextConfigComplete
-  onBuildComplete(ctx: {
+  ) => Promise<NextConfigComplete> | NextConfigComplete
+  onBuildComplete?: (ctx: {
     routes: {
       headers: Array<ManifestHeaderRoute>
       redirects: Array<ManifestRedirectRoute>
@@ -66,7 +66,7 @@ export interface NextAdapter {
       dynamicRoutes: Array<{}>
     }
     outputs: AdapterOutputs
-  }): Promise<void> | void
+  }) => Promise<void> | void
 }
 
 export type I18NDomains = readonly DomainLocale[]

filename: packages/next/src/types.ts
patch: @@ -29,6 +29,8 @@ export type ServerRuntime = 'nodejs' | 'experimental-edge' | 'edge' | undefined
 // @ts-ignore This path is generated at build time and conflicts otherwise
 export { NextConfig } from './server/config'
 
+export type { NextAdapter } from './server/config-shared'
+
 export type {
   Metadata,
   MetadataRoute,

filename: test/production/adapter-config/my-adapter.mjs
patch: @@ -1,3 +1,4 @@
+// @ts-check
 /** @type {import('next').NextAdapter } */
 const myAdapter = {
   name: 'my-custom-adapter',
Repository: electron/electron
Pull request: perf: prefer `base::SplitStringPiece()` over `base::SplitString()`

Backport of #45924

See that PR for details.


Notes: none.

Changed files:
filename: shell/browser/ui/accelerator_util.cc
patch: @@ -7,6 +7,7 @@
 #include <stdio.h>
 
 #include <string>
+#include <string_view>
 #include <vector>
 
 #include "base/logging.h"
@@ -16,7 +17,7 @@
 
 namespace accelerator_util {
 
-bool StringToAccelerator(const std::string& shortcut,
+bool StringToAccelerator(const std::string_view shortcut,
                          ui::Accelerator* accelerator) {
   if (!base::IsStringASCII(shortcut)) {
     LOG(ERROR) << "The accelerator string can only contain ASCII characters, "
@@ -26,14 +27,14 @@ bool StringToAccelerator(const std::string& shortcut,
     return false;
   }
 
-  std::vector<std::string> tokens = base::SplitString(
+  const std::vector<std::string_view> tokens = base::SplitStringPiece(
       shortcut, "+", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
 
   // Now, parse it into an accelerator.
   int modifiers = ui::EF_NONE;
   ui::KeyboardCode key = ui::VKEY_UNKNOWN;
   std::optional<char16_t> shifted_char;
-  for (const auto& token : tokens) {
+  for (const std::string_view token : tokens) {
     ui::KeyboardCode code = electron::KeyboardCodeFromStr(token, &shifted_char);
     if (shifted_char)
       modifiers |= ui::EF_SHIFT_DOWN;

filename: shell/browser/ui/accelerator_util.h
patch: @@ -6,7 +6,7 @@
 #define ELECTRON_SHELL_BROWSER_UI_ACCELERATOR_UTIL_H_
 
 #include <map>
-#include <string>
+#include <string_view>
 
 #include "base/memory/raw_ptr.h"
 #include "shell/browser/ui/electron_menu_model.h"
@@ -21,7 +21,7 @@ typedef struct {
 typedef std::map<ui::Accelerator, MenuItem> AcceleratorTable;
 
 // Parse a string as an accelerator.
-bool StringToAccelerator(const std::string& shortcut,
+bool StringToAccelerator(std::string_view shortcut,
                          ui::Accelerator* accelerator);
 
 // Generate a table that contains menu model's accelerators and command ids.

filename: shell/common/node_bindings.cc
patch: @@ -366,14 +366,14 @@ void SetNodeOptions(base::Environment* env) {
     if (electron::fuses::IsNodeOptionsEnabled()) {
       std::string options;
       env->GetVar("NODE_OPTIONS", &options);
-      std::vector<std::string> parts = base::SplitString(
+      const std::vector<std::string_view> parts = base::SplitStringPiece(
           options, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
 
       bool is_packaged_app = electron::api::App::IsPackaged();
 
-      for (const auto& part : parts) {
+      for (const std::string_view part : parts) {
         // Strip off values passed to individual NODE_OPTIONs
-        std::string option = part.substr(0, part.find('='));
+        const std::string_view option = part.substr(0, part.find('='));
 
         if (is_packaged_app && !pkg_opts.contains(option)) {
           // Explicitly disallow majority of NODE_OPTIONS in packaged apps
Repository: nodejs/node
Pull request: tools: ignore deps and benchmark folder

This should solve https://github.com/nodejs/security-wg/issues/1453#issuecomment-2863222963

cc: @nodejs/security-wg 

Changed files:
filename: .github/codeql-config.yml
patch: @@ -2,5 +2,5 @@ name: CodeQL config
 
 paths-ignore:
   - test
-  - deps/v8/test
-  - deps/v8/tools
+  - deps
+  - benchmark
Repository: ggml-org/llama.cpp
Pull request: server : only attempt to enable thinking if using jinja

Avoids crash introduced in #15404 when not using `--jinja`, but `minja` can't parse the chat template. Will still refuse to start when using `--jinja`, but this is expected behavior.

Fixes #15930

Changed files:
filename: tools/server/server.cpp
patch: @@ -2313,7 +2313,7 @@ struct server_context {
         // thinking is enabled if:
         // 1. It's not explicitly disabled (reasoning_budget == 0)
         // 2. The chat template supports it
-        const bool enable_thinking = params_base.reasoning_budget != 0 && common_chat_templates_support_enable_thinking(chat_templates.get());
+        const bool enable_thinking = params_base.use_jinja && params_base.reasoning_budget != 0 && common_chat_templates_support_enable_thinking(chat_templates.get());
         SRV_INF("Enable thinking? %d\n", enable_thinking);
 
         oai_parser_opt = {
Repository: denoland/deno
Pull request: ci: update Slack bot action

This was showing double "minus" (`-`) sign

Changed files:
filename: tests/node_compat/slack.ts
patch: @@ -43,7 +43,7 @@ function formatDiff(diff: number) {
   if (diff > 0) {
     return `+${diffStr}% 🟩`;
   } else {
-    return `-${diffStr}% 🟥`;
+    return `${diffStr}% 🟥`;
   }
 }
Repository: facebook/react
Pull request: Convert SyntheticEvent-test.js to createRoot


Changed files:
filename: packages/react-dom/src/events/__tests__/SyntheticEvent-test.js
patch: @@ -10,16 +10,20 @@
 'use strict';
 
 let React;
-let ReactDOM;
+let ReactDOMClient;
+let act;
 
 describe('SyntheticEvent', () => {
   let container;
+  let root;
 
   beforeEach(() => {
     React = require('react');
-    ReactDOM = require('react-dom');
+    ReactDOMClient = require('react-dom/client');
+    act = require('internal-test-utils').act;
 
     container = document.createElement('div');
+    root = ReactDOMClient.createRoot(container);
     document.body.appendChild(container);
   });
 
@@ -28,7 +32,7 @@ describe('SyntheticEvent', () => {
     container = null;
   });
 
-  it('should be able to `preventDefault`', () => {
+  it('should be able to `preventDefault`', async () => {
     let expectedCount = 0;
 
     const eventHandler = syntheticEvent => {
@@ -39,7 +43,11 @@ describe('SyntheticEvent', () => {
 
       expectedCount++;
     };
-    const node = ReactDOM.render(<div onClick={eventHandler} />, container);
+    const nodeRef = React.createRef();
+    await act(async () => {
+      root.render(<div onClick={eventHandler} ref={nodeRef} />);
+    });
+    const node = nodeRef.current;
 
     const event = document.createEvent('Event');
     event.initEvent('click', true, true);
@@ -48,15 +56,19 @@ describe('SyntheticEvent', () => {
     expect(expectedCount).toBe(1);
   });
 
-  it('should be prevented if nativeEvent is prevented', () => {
+  it('should be prevented if nativeEvent is prevented', async () => {
     let expectedCount = 0;
 
     const eventHandler = syntheticEvent => {
       expect(syntheticEvent.isDefaultPrevented()).toBe(true);
 
       expectedCount++;
     };
-    const node = ReactDOM.render(<div onClick={eventHandler} />, container);
+    const nodeRef = React.createRef();
+    await act(async () => {
+      root.render(<div onClick={eventHandler} ref={nodeRef} />);
+    });
+    const node = nodeRef.current;
 
     let event;
     event = document.createEvent('Event');
@@ -80,7 +92,7 @@ describe('SyntheticEvent', () => {
     expect(expectedCount).toBe(2);
   });
 
-  it('should be able to `stopPropagation`', () => {
+  it('should be able to `stopPropagation`', async () => {
     let expectedCount = 0;
 
     const eventHandler = syntheticEvent => {
@@ -90,7 +102,11 @@ describe('SyntheticEvent', () => {
 
       expectedCount++;
     };
-    const node = ReactDOM.render(<div onClick={eventHandler} />, container);
+    const nodeRef = React.createRef();
+    await act(async () => {
+      root.render(<div onClick={eventHandler} ref={nodeRef} />);
+    });
+    const node = nodeRef.current;
 
     const event = document.createEvent('Event');
     event.initEvent('click', true, true);
Repository: vercel/next.js
Pull request: Allow `beforePageLoad` to be async

This is useful when working with `Playwright.Clock`.

Changed files:
filename: test/e2e/app-dir/segment-cache/staleness/segment-cache-stale-time.test.ts
patch: @@ -81,16 +81,17 @@ describe('segment cache (staleness)', () => {
 
   it('reuses dynamic data up to the staleTimes.dynamic threshold', async () => {
     let page: Playwright.Page
+    const startDate = Date.now()
+
     const browser = await next.browser('/', {
-      beforePageLoad(p: Playwright.Page) {
+      async beforePageLoad(p: Playwright.Page) {
         page = p
+        await page.clock.install()
+        await page.clock.setFixedTime(startDate)
       },
     })
-    const act = createRouterAct(page)
 
-    await page.clock.install()
-    const startDate = Date.now()
-    await page.clock.setFixedTime(startDate)
+    const act = createRouterAct(page)
 
     // Navigate to the dynamic page
     await act(

filename: test/lib/browsers/playwright.ts
patch: @@ -228,7 +228,7 @@ export class Playwright<TCurrent = undefined> {
       disableCache?: boolean
       cpuThrottleRate?: number
       pushErrorAsConsoleLog?: boolean
-      beforePageLoad?: (page: Page) => void
+      beforePageLoad?: (page: Page) => void | Promise<void>
     }
   ) {
     await this.close()
@@ -310,7 +310,7 @@ export class Playwright<TCurrent = undefined> {
       })
     })
 
-    opts?.beforePageLoad?.(page)
+    await opts?.beforePageLoad?.(page)
 
     await page.goto(url, { waitUntil: 'load' })
   }

filename: test/lib/next-modes/base.ts
patch: @@ -703,8 +703,8 @@ export class NextInstance {
     const [browser, response] = await Promise.all([
       webdriver(this.url, url, {
         ...options,
-        beforePageLoad(page: Page) {
-          options.beforePageLoad?.(page)
+        async beforePageLoad(page: Page) {
+          await options.beforePageLoad?.(page)
 
           page.on('response', async (response) => {
             if (response.url() === absoluteUrl) {

filename: test/lib/next-webdriver.ts
patch: @@ -62,7 +62,7 @@ export interface WebdriverOptions {
    * @param page
    * @returns
    */
-  beforePageLoad?: (page: Page) => void
+  beforePageLoad?: (page: Page) => void | Promise<void>
   /**
    * browser locale
    */
Repository: ggml-org/llama.cpp
Pull request: rocm.Dockerfile: added gfx1200,gfx1201 architectures to support  AMD Radeon RX 9000 series

https://rocm.docs.amd.com/projects/install-on-linux/en/docs-6.4.1/reference/system-requirements.html#rdna-os states the Radeon RX 9000 series is supported from Ubuntu 24.04.2, and the dockerfile is using 24.04 which is ROCm 6.4.

This fixed the `ROCm error: invalid device function` I was getting when trying to use the rocm container.

*Make sure to read the [contributing guidelines](https://github.com/ggml-org/llama.cpp/blob/master/CONTRIBUTING.md) before submitting a PR*


Changed files:
filename: .devops/rocm.Dockerfile
patch: @@ -4,7 +4,7 @@ ARG UBUNTU_VERSION=24.04
 ARG ROCM_VERSION=6.4
 ARG AMDGPU_VERSION=6.4
 
-# Target the CUDA build image
+# Target the ROCm build image
 ARG BASE_ROCM_DEV_CONTAINER=rocm/dev-ubuntu-${UBUNTU_VERSION}:${ROCM_VERSION}-complete
 
 ### Build image
@@ -15,12 +15,12 @@ FROM ${BASE_ROCM_DEV_CONTAINER} AS build
 # This is mostly tied to rocBLAS supported archs.
 # gfx803, gfx900, gfx1032, gfx1101, gfx1102,not officialy supported
 # gfx906 is deprecated
-#check https://rocm.docs.amd.com/projects/install-on-linux/en/docs-6.2.4/reference/system-requirements.html
+#check https://rocm.docs.amd.com/projects/install-on-linux/en/docs-6.4.1/reference/system-requirements.html
 
-ARG ROCM_DOCKER_ARCH='gfx803,gfx900,gfx906,gfx908,gfx90a,gfx942,gfx1010,gfx1030,gfx1032,gfx1100,gfx1101,gfx1102'
+ARG ROCM_DOCKER_ARCH='gfx803,gfx900,gfx906,gfx908,gfx90a,gfx942,gfx1010,gfx1030,gfx1032,gfx1100,gfx1101,gfx1102,gfx1200,gfx1201'
 #ARG ROCM_DOCKER_ARCH=gfx1100
 
-# Set nvcc architectured
+# Set ROCm architectured
 ENV AMDGPU_TARGETS=${ROCM_DOCKER_ARCH}
 # Enable ROCm
 # ENV CC=/opt/rocm/llvm/bin/clang
Repository: huggingface/transformers
Pull request: Fix link in "Inference server backends" doc

The link now points to the correct place in the vLLM docs

Changed files:
filename: docs/source/en/transformers_as_backend.md
patch: @@ -40,7 +40,7 @@ vllm serve meta-llama/Llama-3.2-1B \
     --model-impl transformers
 ```
 
-Refer to the [vLLM docs](https://docs.vllm.ai/en/latest/models/transformers_backend.html) for more usage examples and tips on using a Transformers as the backend.
+Refer to the [vLLM docs](https://docs.vllm.ai/en/latest/models/supported_models.html#transformers) for more usage examples and tips on using a Transformers as the backend.
 
 
 ## SGLang
Repository: vercel/next.js
Pull request: [segment explorer] fix content overflow styling

* The bottom reset button should cover the content
* No need for transparent button background

| After | Before |
|:--|:--|
| <video src="https://github.com/user-attachments/assets/598a6474-315a-4ed5-819b-dd49306125ef"> | <video src="https://github.com/user-attachments/assets/9d7ba02c-033e-43b7-a65c-6764e903e10e"> |



Changed files:
filename: packages/next/src/next-devtools/dev-overlay/components/overview/segment-explorer.css
patch: @@ -3,7 +3,7 @@
   padding: 0 8px;
   width: 100%;
   height: 100%;
-  overflow: auto;
+  overflow-y: hidden;
 }
 
 .segment-explorer-page-route-bar {
@@ -156,7 +156,6 @@
 }
 
 .segment-explorer-footer-button--disabled {
-  opacity: 0.5;
   cursor: not-allowed;
 }
Repository: denoland/deno
Pull request: ci: Show percentage diff for Node compat tests

This is for internal Slack automation

Changed files:
filename: tests/node_compat/slack.ts
patch: @@ -18,27 +18,76 @@ const client = new WebClient(token, {
   logLevel: LogLevel.DEBUG,
 });
 
-function formatRatio(report: { pass: number; total: number } | undefined) {
+function getRatio(report: { pass: number; total: number } | undefined) {
   if (!report) {
+    return -1;
+  }
+
+  return (report.pass / report.total) * 100;
+}
+
+function formatRatio(ratio: number) {
+  if (ratio === -1) {
     return "N/A";
   }
-  const ratio = (report.pass / report.total) * 100;
   return ratio.toFixed(2) + "%";
 }
 
+function formatDiff(diff: number) {
+  if (diff === 0) {
+    return `±0% 🟨`;
+  }
+
+  const diffStr = diff.toFixed(2);
+
+  if (diff > 0) {
+    return `+${diffStr}% 🟩`;
+  } else {
+    return `-${diffStr}% 🟥`;
+  }
+}
+
 function createMessage(monthSummary: MonthSummary) {
-  const daySummary = Object.values(monthSummary.reports).sort((a, b) =>
+  const sortedMonthSummary = Object.values(monthSummary.reports).sort((a, b) =>
     new Date(a.date).getTime() - new Date(b.date).getTime()
-  ).at(-1);
+  );
+
+  const daySummary = sortedMonthSummary.at(-1);
   if (!daySummary) {
     throw new Error("No summary data found");
   }
+  const prevDaySummary = sortedMonthSummary.at(-2);
   const { date, linux, windows, darwin } = daySummary;
-  const linuxRatio = formatRatio(linux);
-  const windowsRatio = formatRatio(windows);
-  const darwinRatio = formatRatio(darwin);
-  const mrkdwn =
-    `Linux *${linuxRatio}* / Windows *${windowsRatio}* / Darwin *${darwinRatio}* <https://node-test-viewer.deno.dev/results/${date}|(Full report)>`;
+  let mrkdwn = "";
+
+  const currentLinuxRatio = getRatio(linux);
+  const prevLinuxRatio = getRatio(prevDaySummary?.linux);
+  const linuxRatioDiff = prevLinuxRatio !== -1
+    ? currentLinuxRatio - prevLinuxRatio
+    : 0;
+  mrkdwn += `Linux *${formatRatio(currentLinuxRatio)}* (${
+    formatDiff(linuxRatioDiff)
+  })\n`;
+
+  const currentWindowsRatio = getRatio(windows);
+  const prevWindowsRatio = getRatio(prevDaySummary?.windows);
+  const windowsRatioDiff = prevWindowsRatio !== -1
+    ? currentWindowsRatio - prevWindowsRatio
+    : 0;
+  mrkdwn += `Windows *${formatRatio(currentWindowsRatio)}* (${
+    formatDiff(windowsRatioDiff)
+  })\n`;
+
+  const currentDarwinRatio = getRatio(darwin);
+  const prevDarwinRatio = getRatio(prevDaySummary?.darwin);
+  const darwinRatioDiff = prevDarwinRatio !== -1
+    ? currentDarwinRatio - prevDarwinRatio
+    : 0;
+  mrkdwn += `Darwin *${formatRatio(currentDarwinRatio)}* (${
+    formatDiff(darwinRatioDiff)
+  })\n`;
+
+  mrkdwn += `<https://node-test-viewer.deno.dev/results/${date}|(Full report)>`;
 
   return [
     {