Skip to content
This repository has been archived by the owner on Aug 31, 2023. It is now read-only.

ci: comment compare #1782

Merged
merged 9 commits into from
Nov 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 53 additions & 11 deletions .github/workflows/test262.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [windows-latest, macos-latest, ubuntu-latest]
os: [windows-latest, macos-latest, ubuntu-latest]
steps:
- name: Checkout repository
uses: actions/checkout@v2
Expand All @@ -33,31 +33,28 @@ jobs:
uses: Swatinem/rust-cache@v1
- name: Run Test262 suite
continue-on-error: true
run: cargo xtask coverage --json
- name: Rename the emitted file
run: |
mv base_results.json new_results.json
run: cargo xtask coverage --json > new_results.json
- name: Save test results
uses: actions/upload-artifact@v2
with:
name: new_results
path: new_results.json

compare:
# This job compares the coverage results from this PR and the coverage results from master
coverage-comparison:
needs: coverage
name: Compare coverage
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [windows-latest, macos-latest, ubuntu-latest]
os: [windows-latest, macos-latest, ubuntu-latest]
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
submodules: recursive
# To restore once the main branch has the new command
# ref: main
ref: main
- name: Install toolchain
uses: actions-rs/toolchain@v1
with:
Expand All @@ -67,10 +64,55 @@ jobs:
uses: Swatinem/rust-cache@v1
- name: Run Test262 suite on main branch
continue-on-error: true
run: cargo xtask coverage --json
run: cargo xtask coverage --json > base_results.json
ematipico marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that it now takes quite a while until the results show up on the PR because the coverage command must run twice. Do you think there's a way to publish the result for "main" and store it (e.g. using the commit number in the name) whenever a commit gets merged so that we may just retrieve it (and only run xtask coverage in the case it's missing for whatever reason)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is something I discussed with the others during the standup.

Boa uses Github pages to store the results.

Cloudflare doesn't have a storage service yet. Github actions artifacts are not readable across workflows. Maybe, for now, we should use Github pages

- name: Download PRs test results
uses: actions/download-artifact@v2
with:
name: new_results
- name: Compare results on ${{ matrix.os }}
run: cargo xtask compare ./base_results.json ./new_results.json --markdown
if: github.event_name == 'pull_request'
id: comparison
shell: bash
run: |
comment="$(cargo xtask compare ./base_results.json ./new_results.json --markdown)"
comment="${comment//'%'/'%25'}"
comment="${comment//$'\n'/'%0A'}"
comment="${comment//$'\r'/'%0D'}"
echo "::set-output name=comment::$comment"

- name: Get the PR number
if: github.event_name == 'pull_request'
id: pr-number
uses: kkak10/pr-number-action@v1.3

- name: Find Previous Comment
if: github.event_name == 'pull_request'
uses: peter-evans/find-comment@v1.3.0
id: previous-comment
with:
issue-number: ${{ steps.pr-number.outputs.pr }}
body-includes: Test262 conformance changes

- name: Update comment
if: github.event_name == 'pull_request' && steps.previous-comment.outputs.comment-id
uses: peter-evans/create-or-update-comment@v1.4.5
continue-on-error: true
with:
comment-id: ${{ steps.previous-comment.outputs.comment-id }}
body: |
### Test262 comparison coverage results on ${{ matrix.os }}

${{ steps.comparison.outputs.comment }}
edit-mode: replace

- name: Write a new comment
if: github.event_name == 'pull_request' && !steps.previous-comment.outputs.comment-id
uses: peter-evans/create-or-update-comment@v1.4.5
continue-on-error: true
with:
issue-number: ${{ steps.pr-number.outputs.pr }}
body: |
### Test262 comparison coverage results on ${{ matrix.os }}

${{ steps.comparison.outputs.comment }}

23 changes: 16 additions & 7 deletions crates/rslint_parser/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -423,19 +423,24 @@ impl<'t> Parser<'t> {
}

/// Bump and add an error event
pub fn err_and_bump(&mut self, err: impl Into<ParserError>) {
pub fn err_and_bump(&mut self, err: impl Into<ParserError>, unknown_syntax_kind: SyntaxKind) {
let m = self.start();
self.bump_any();
m.complete(self, SyntaxKind::ERROR);
m.complete(self, unknown_syntax_kind);
self.error(err);
}

pub fn err_if_not_ts(&mut self, mut marker: impl BorrowMut<CompletedMarker>, err: &str) {
pub fn err_if_not_ts(
&mut self,
mut marker: impl BorrowMut<CompletedMarker>,
err: &str,
unknown_syntax_kind: SyntaxKind,
) {
if self.typescript() {
return;
}
let borrow = marker.borrow_mut();
borrow.change_kind(self, SyntaxKind::ERROR);
borrow.change_kind(self, unknown_syntax_kind);
let err = self.err_builder(err).primary(borrow.range(self), "");

self.error(err);
Expand Down Expand Up @@ -489,7 +494,11 @@ impl<'t> Parser<'t> {
start..end
}

pub fn expr_with_semi_recovery(&mut self, assign: bool) -> Option<CompletedMarker> {
pub fn expr_with_semi_recovery(
&mut self,
assign: bool,
unknown_syntax_kind: SyntaxKind,
) -> Option<CompletedMarker> {
let func = if assign {
syntax::expr::assign_expr
} else {
Expand All @@ -504,7 +513,7 @@ impl<'t> Parser<'t> {

self.error(err);
self.bump_any();
m.complete(self, SyntaxKind::ERROR);
m.complete(self, unknown_syntax_kind);
return None;
}

Expand Down Expand Up @@ -715,7 +724,7 @@ impl CompletedMarker {
}

pub fn err_if_not_ts(&mut self, p: &mut Parser, err: &str) {
p.err_if_not_ts(self, err);
p.err_if_not_ts(self, err, SyntaxKind::ERROR);
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/rslint_parser/src/syntax/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1026,7 +1026,7 @@ pub fn primary_expr(p: &mut Parser) -> Option<CompletedMarker> {
))
.primary(p.cur_tok().range, "");

p.err_and_bump(err);
p.err_and_bump(err, ERROR);
m.complete(p, ERROR)
} else {
let err = p
Expand Down
12 changes: 6 additions & 6 deletions crates/rslint_parser/src/syntax/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ pub fn stmt(

// We must explicitly handle this case or else infinite recursion can happen
if p.at_ts(token_set![T!['}'], T![import], T![export]]) {
p.err_and_bump(err);
p.err_and_bump(err, ERROR);
return None;
}

Expand Down Expand Up @@ -231,7 +231,7 @@ fn expr_stmt(p: &mut Parser, decorator: Option<CompletedMarker>) -> Option<Compl
m.complete(p, ERROR);
}

let mut expr = p.expr_with_semi_recovery(false)?;
let mut expr = p.expr_with_semi_recovery(false, ERROR)?;
// Labelled stmt
if expr.kind() == NAME_REF && p.at(T![:]) {
expr.change_kind(p, NAME);
Expand Down Expand Up @@ -315,7 +315,7 @@ pub fn throw_stmt(p: &mut Parser) -> CompletedMarker {

p.error(err);
} else {
p.expr_with_semi_recovery(false);
p.expr_with_semi_recovery(false, ERROR);
}
semi(p, start..p.cur_tok().range.end);
m.complete(p, JS_THROW_STATEMENT)
Expand Down Expand Up @@ -407,7 +407,7 @@ pub fn return_stmt(p: &mut Parser) -> CompletedMarker {
let start = p.cur_tok().range.start;
p.expect(T![return]);
if !p.has_linebreak_before_n(0) && p.at_ts(STARTS_EXPR) {
p.expr_with_semi_recovery(false);
p.expr_with_semi_recovery(false, ERROR);
}
semi(p, start..p.cur_tok().range.end);
let complete = m.complete(p, JS_RETURN_STATEMENT);
Expand Down Expand Up @@ -852,13 +852,13 @@ fn variable_initializer(p: &mut Parser) {
let m = p.start();

p.expect(T![=]);
p.expr_with_semi_recovery(true);
p.expr_with_semi_recovery(true, ERROR);

m.complete(p, SyntaxKind::JS_EQUAL_VALUE_CLAUSE);
}

// A do.. while statement, such as `do {} while (true)`
// test do_while_stmt
// test do_while_stmtR
// do { } while (true)
// do throw Error("foo") while (true)
pub fn do_stmt(p: &mut Parser) -> CompletedMarker {
Expand Down
6 changes: 5 additions & 1 deletion xtask/src/compare/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ use std::path::PathBuf;

mod results;

pub fn run(base_result_path: Option<&str>, new_result_path: Option<&str>, markdown: bool) {
pub fn coverage_compare(
base_result_path: Option<&str>,
new_result_path: Option<&str>,
markdown: bool,
) {
// resolve the path passed as argument, or retrieve the default one
let base_result_dir = if let Some(base_result_path) = base_result_path {
PathBuf::from(base_result_path)
Expand Down
58 changes: 44 additions & 14 deletions xtask/src/compare/results.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::coverage::files::{Outcome, TestResults};
use crate::coverage::files::{Outcome, TestResult, TestResults};
use ascii_table::{AsciiTable, Column};
use colored::Colorize;
use std::{fs::File, path::Path};
use std::{collections::HashMap, ffi::OsStr, fs::File, path::Path};

pub fn emit_compare(base: &Path, new: &Path, markdown: bool) {
let base_results: TestResults =
Expand Down Expand Up @@ -35,9 +35,37 @@ pub fn emit_compare(base: &Path, new: &Path, markdown: bool) {

if markdown {
/// Generates a proper diff format, with some bold text if things change.
fn diff_format(diff: isize) -> String {
fn diff_format(diff: isize, i_am_passed_results: bool, show_increase: bool) -> String {
let good = "✅ ";
let bad = "❌ ";
let up = "⏫ ";
let down = "⏬ ";
ematipico marked this conversation as resolved.
Show resolved Hide resolved

let emoji = if show_increase {
match diff.cmp(&0) {
std::cmp::Ordering::Less => {
if i_am_passed_results {
format!("{}{}", bad, down)
} else {
format!("{}{}", good, down)
}
}
std::cmp::Ordering::Equal => format!(""),
std::cmp::Ordering::Greater => {
if i_am_passed_results {
format!("{}{}", good, up)
} else {
format!("{}{}", bad, up)
}
}
}
} else {
format!("")
};

format!(
"{}{}{}{}",
"{}{}{}{}{}",
emoji,
if diff != 0 { "**" } else { "" },
if diff > 0 { "+" } else { "" },
diff,
Expand All @@ -52,28 +80,28 @@ pub fn emit_compare(base: &Path, new: &Path, markdown: bool) {
"| Total | {} | {} | {} |",
base_total,
new_total,
diff_format(total_diff)
diff_format(total_diff, false, false)
);

println!(
"| Passed | {} | {} | {} |",
base_passed,
new_passed,
diff_format(passed_diff)
diff_format(passed_diff, true, true)
);

println!(
"| Failed | {} | {} | {} |",
base_failed,
new_failed,
diff_format(failed_diff)
diff_format(failed_diff, false, true)
);

println!(
"| Panics | {} | {} | {} |",
base_passed,
new_passed,
diff_format(panics_diff)
base_panics,
new_panics,
diff_format(panics_diff, false, true)
);

println!(
Expand Down Expand Up @@ -209,11 +237,13 @@ fn compare_diffs<'a>(
new_results: &'a TestResults,
) -> ReportDiff<'a> {
let mut report_diff = ReportDiff::new();
let new_paths: HashMap<&OsStr, &TestResult> = new_results
.details
.iter()
.map(|detail| return (detail.path.as_os_str(), detail))
.collect();
for base_result in &base_results.details {
let test_to_analyze = new_results
.details
.iter()
.find(|new_test| new_test.path.as_os_str().eq(base_result.path.as_os_str()));
let test_to_analyze = new_paths.get(base_result.path.as_os_str());

if let Some(test_to_analyze) = test_to_analyze {
match (&base_result.outcome, &test_to_analyze.outcome) {
Expand Down
Loading