git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v2 0/9] ci: make Git's GitHub workflow output much more helpful

From
Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Date
Mar 2, 2022, 12:22 UTC
Message-ID
<220302.86mti87cj2.gmgdl@evledraar.gmail.com>
In-Reply-To
<pull.1117.v2.git.1646130289.gitgitgadget@gmail.com>
On Tue, Mar 01 2022, Johannes Schindelin via GitGitGadget wrote:
Show 9 quoted lines
> Changes since v1:
>
>  * In the patch that removed MAKE_TARGETS, a stale comment about that
>    variable is also removed.
>  * The comment about set -x has been adjusted because it no longer applies
>    as-is.
>  * The commit message of "ci: make it easier to find failed tests' logs in
>    the GitHub workflow" has been adjusted to motivate the improvement
>    better.

Just briefly: Much of the feedback I had on v1 is still unanswered, or in the case of the performance issues I think just saying that this output is aimed at non-long-time-contributors doesn't really justify the large observed slowdowns.

I've been clicking around on the various "seen" links you posted, and while some of the output is improved it's *much* slower, to the point where I don't find those gains worth it.

For the early part of this series teaching the "ci/" this GitHub markdown that's something that's unnecessary in my alternate approach in [1]. This series is is obviously a relatively shorter way to get there, but knowing that you *can* do it in a simpler way now it's odd that the v2 doesn't discuss why getting from "A" to that "B" is still desirable with this method.

As for the later parts:
Show 5 quoted lines
>   5:  94dcbe1bc43 =  5:  9eda6574313 tests: refactor --write-junit-xml code
>   6:  41230100091 =  6:  c8b240af749 test(junit): avoid line feeds in XML attributes
>   7:  98b32630fcd =  7:  15f199e810e ci: optionally mark up output in the GitHub workflow
>   8:  1a6bd1846bc =  8:  91ea54f36c5 ci: use `--github-workflow-markup` in the GitHub workflow
>   9:  992b1575889 =  9:  be2a83f5da3 ci: call `finalize_test_case_output` a little later

I think (and I pointed out to you before) that I really don't see why teaching the test-lib.sh N output formats when we already have a machine-readable output format with TAP *and* are in fact running code with "prove" that is parsing that output format into nicely arranged objects/structures makes sense.

So as a demo for how that can work, here's a quick POC I hacked up a while ago to use "prove" output plugins for this sort of thing.

First we intentionally break a test:
	$ git -P diff
	diff --git a/t/t0002-gitfile.sh b/t/t0002-gitfile.sh
	index 76052cb5620..f085188baf9 100755
	--- a/t/t0002-gitfile.sh
	+++ b/t/t0002-gitfile.sh
	@@ -44,7 +44,7 @@ test_expect_success 'check hash-object' '
	 
	 test_expect_success 'check cat-file' '
	        git cat-file blob $SHA >actual &&
	-       test_cmp bar actual
	+       test_cmp /dev/null actual
	 '
	 
	 test_expect_success 'check update-index' '
	@@ -67,7 +67,7 @@ test_expect_success 'check commit-tree' '
	 
	 test_expect_success 'check rev-list' '
	        git update-ref "HEAD" "$SHA" &&
	-       test "$SHA" = "$(git rev-list HEAD)"
	+       test "$SHA" = "$(xgit rev-list HEAD)"
	 '

And here's the resulting output, which is the same as the existing "prove" summary output, but then followed by nicely formatted details about just the failing tests:

	$ PERL5LIB=$PWD prove --formatter Fmt t0002-gitfile.sh :: -vx
	 
	 test_expect_success 'setup_git_dir twice in subdir' '
	t0002-gitfile.sh .. Dubious, test returned 1 (wstat 256, 0x100)
	Failed 2/14 subtests 
	
	Test Summary Report
	-------------------
	t0002-gitfile.sh (Wstat: 256 Tests: 14 Failed: 2)
	  Failed tests:  6, 10
	  Non-zero exit status: 1
	Files=1, Tests=14,  0 wallclock secs ( 0.02 usr  0.00 sys +  0.13 cusr  0.05 csys =  0.20 CPU)
	Result: FAIL
	Failed in t0002-gitfile.sh#6:
	 ==> test   => not ok 6 - check cat-file
	 ==> source => #
	 ==> source => #        git cat-file blob $SHA >actual &&
	 ==> source => #        test_cmp /dev/null actual
	 ==> source => #
	 ==> trace  => + git cat-file blob 257cc5642cb1a054f08cc83f2d943e56fd3ebe99
	 ==> trace  => + test_cmp /dev/null actual
	 ==> trace  => + test 2 -ne 2
	 ==> trace  => + eval diff -u "$@"
	 ==> trace  => + diff -u /dev/null actual
	 ==> output => --- /dev/null    2022-01-25 04:40:50.187529644 +0000
	 ==> output => +++ actual       2022-03-02 12:29:28.217960535 +0000
	 ==> output => @@ -0,0 +1 @@
	 ==> output => +foo
	 ==> output => error: last command exited with $?=1
	 ==> output => 
	Failed in t0002-gitfile.sh#10:
	 ==> test   => not ok 10 - check rev-list
	 ==> source => #
	 ==> source => #        git update-ref "HEAD" "$SHA" &&
	 ==> source => #        test "$SHA" = "$(xgit rev-list HEAD)"
	 ==> source => #
	 ==> trace  => + git update-ref HEAD f2e10ff57e8c01fe514c650d9de97e913257ba0c
	 ==> trace  => + xgit rev-list HEAD
	 ==> trace  => + test f2e10ff57e8c01fe514c650d9de97e913257ba0c = 
	 ==> output => t0002-gitfile.sh: 5: eval: xgit: not found
	 ==> output => error: last command exited with $?=1
	 ==> output => 

Now, some of that is on top of some output changes to test-lib.sh I had locally, but the "test", "source" etc. there is not a hardcoded part of the output, it's corresponding to (some of which I re-labeled, e.g. "comment" => "source") the individual object types the TAP::Parser emits.

The code to do that is below, with brief (unindented) comments:
	package Git::TAP::Formatter::Session;
	use v5.18.2;
	use strict;
	use warnings;
	use base 'TAP::Formatter::Console::ParallelSession';
	
	our %STATE;
	sub result {
		my $self = shift;
		my $result = shift;
So here we just have the TAP object for the current tests (as in "ok",
"not ok" etc.), and save all of those away (both for successful and
non-successful) tests in %STATE for later:
	
		my $res = $self->SUPER::result($result);
		my $test_name = $self->name;
	
		# An AoO of test numbers and their output lines
		$STATE{$test_name} ||= [{lines => []}];
	
		push @{$STATE{$test_name}->[-1]->{lines}} => $result;
	
		# When we see a new test add a new AoA for its output. We do
		# end up with the "plan" type as part of the last test, and
		# might want to split it up
		if ($result->type eq 'test') {
			push @{$STATE{$test_name}} => {};
		}
	
		return $res;
	}

This "Fmt" package is a "prove" plugin. It's just hooking into the code that emits the current summary, now it just shows the "Test Summary Report" that your CL notes issues with, but this shows how easy it is to change or amend it (you can override another accessor here to fully suppress the current output, I just didn't do that):

	package Fmt;
	use strict;
	use warnings;
	use List::MoreUtils qw(firstidx);
	use base 'TAP::Formatter::Console';
	
	sub open_test {
		my $self = shift;
	
		my $session = $self->SUPER::open_test(@_);
		use Data::Dumper;
		#warn "session is = " . Dumper $session;
		return bless $session => 'Git::TAP::Formatter::Session';
	}
	
	sub summary {
		my $self = shift;
		$self->SUPER::summary(@_);
	
		## This state machine needs to go past the "ok" line and grab
		## the comments emitted by e.g. "say_color_tap_comment_lines" in
		## test_ok_()
		for my $test (sort keys %STATE) {
			for (my $i = 1; $i <= $#{$STATE{$test}}; $i++) {
				my @lines = @{$STATE{$test}->[$i]->{lines}};
				my $break = firstidx { $_->raw eq '' } @lines;
				my @source = splice @lines, 0, $break;
	
				splice @lines, 0, 1; # Splice out the '' item
				push @{$STATE{$test}->[$i - 1]->{lines}} => @source;
	
				$STATE{$test}->[$i]->{lines} = \@lines;
	
				# Since we parsed out the source already,
				# let's make it easily machine-readable, and
				# parse the rest.
				$STATE{$test}->[$i]->{source} = \@source;
				my @trace = map { $_->{is_trace} = 1 } grep { $_->raw =~ /^\+ / } @lines;
				$STATE{$test}->[$i]->{trace} = \@trace if @trace;
			}
		}
	
		my $aggregator = $_[0];
		for my $failed ($aggregator->failed) {
			my ($parser) = $aggregator->parsers($failed);
			for my $i ($parser->failed) {
				my $idx = $i - 1;
				my @lines = @{$STATE{$failed}->[$idx]->{lines}};
				my ($test) = grep { $_->is_test } @lines;
	
				say "Failed in $failed#$i:";
				say join "\n", map {
					s/^/ ==> /gr;
				} map {
					sprintf("%-6s => %s",
					     $_->{is_trace} ? "trace" :
					     $_->is_unknown ? "output" :
					     $_->is_comment ? "source" :
					     $_->type,
					     $_->raw,
				     );
				} sort {
					# the "is_trace" may be undef
					no warnings qw(uninitialized);
					# The "[not ]ok" line first...
					$b->is_test <=> $a->is_test ||
					# Then "comment" (i.e. test source)
					$b->is_comment <=> $a->is_comment ||
					# Then the "+ " trace of execution
					$b->{is_trace} <=> $a->{is_trace}
				} @lines;
			}
		}
	}
	
	1;
1. https://lore.kernel.org/git/cover-00.25-00000000000-20220221T143936Z-avarab@gmail.com/
2. https://lore.kernel.org/git/220222.86y2236ndp.gmgdl@evledraar.gmail.com/
Previous: Junio C HamanoNext: Johannes Schindelin
Message 63 of 98 in “ci: make Git's GitHub workflow output much more helpful”
  1. 0/9 ci: make Git's GitHub workflow output much more helpfulJohannes Schindelin via GitGitGadget, Jan 24, 2022
  2. 1/9 ci: fix code styleJohannes Schindelin via GitGitGadget, Jan 24, 2022
  3. 2/9 ci/run-build-and-tests: take a more high-level viewJohannes Schindelin via GitGitGadget, Jan 24, 2022
  4. Eric SunshineJan 24, 2022
  5. Johannes SchindelinJan 25, 2022
  6. 3/9 ci: make it easier to find failed tests' logs in the GitHub workflowJohannes Schindelin via GitGitGadget, Jan 24, 2022
  7. Ævar Arnfjörð BjarmasonJan 25, 2022
  8. 4/9 ci/run-build-and-tests: add some structure to the GitHub workflow outputJohannes Schindelin via GitGitGadget, Jan 24, 2022
  9. Phillip WoodFeb 23, 2022
  10. Johannes SchindelinFeb 25, 2022
  11. 5/9 tests: refactor --write-junit-xml codeJohannes Schindelin via GitGitGadget, Jan 24, 2022
  12. Ævar Arnfjörð BjarmasonJan 26, 2022
  13. 6/9 test(junit): avoid line feeds in XML attributesJohannes Schindelin via GitGitGadget, Jan 24, 2022
  14. 9/9 ci: call `finalize_test_case_output` a little laterJohannes Schindelin via GitGitGadget, Jan 24, 2022
  15. 8/9 ci: use `--github-workflow-markup` in the GitHub workflowJohannes Schindelin via GitGitGadget, Jan 24, 2022
  16. 7/9 ci: optionally mark up output in the GitHub workflowJohannes Schindelin via GitGitGadget, Jan 24, 2022
  17. Ævar Arnfjörð BjarmasonJan 26, 2022
  18. CI "grouping" within jobs v.s. lighter split-out jobs (was: [PATCH 0/9] ci: make Git's GitHub workflow output much more helpful)Ævar Arnfjörð Bjarmason, Jan 27, 2022
  19. Johannes SchindelinFeb 19, 2022
  20. Junio C HamanoFeb 20, 2022
  21. Johannes SchindelinFeb 20, 2022
  22. Ævar Arnfjörð BjarmasonFeb 21, 2022
  23. Johannes SchindelinFeb 22, 2022
  24. Ævar Arnfjörð BjarmasonFeb 20, 2022
  25. Johannes SchindelinFeb 22, 2022
  26. Ævar Arnfjörð BjarmasonFeb 22, 2022
  27. Phillip WoodFeb 23, 2022
  28. Ævar Arnfjörð BjarmasonFeb 25, 2022
  29. Johannes SchindelinFeb 25, 2022
  30. Junio C HamanoFeb 25, 2022
  31. Junio C HamanoFeb 26, 2022
  32. Junio C HamanoMar 1, 2022
  33. Junio C HamanoMar 1, 2022
  34. Johannes SchindelinMar 1, 2022
  35. Junio C HamanoMar 1, 2022
  36. Johannes SchindelinMar 1, 2022
  37. Junio C HamanoMar 1, 2022
  38. Johannes SchindelinMar 1, 2022
  39. win+VS environment has "cut" but not "paste"?Junio C Hamano, Mar 4, 2022
  40. Ævar Arnfjörð BjarmasonMar 4, 2022
  41. Johannes SchindelinMar 7, 2022
  42. Junio C HamanoMar 7, 2022
  43. Johannes SchindelinMar 9, 2022
  44. Ævar Arnfjörð BjarmasonMar 10, 2022
  45. Johannes SchindelinMar 7, 2022
  46. Junio C HamanoMar 7, 2022
  47. Phillip WoodMar 2, 2022
  48. Johannes SchindelinMar 7, 2022
  49. Junio C HamanoMar 7, 2022
  50. Ævar Arnfjörð BjarmasonMar 9, 2022
  51. Phillip WoodMar 7, 2022
  52. 0/9 ci: make Git's GitHub workflow output much more helpfulJohannes Schindelin via GitGitGadget, Mar 1, 2022
  53. 1/9 ci: fix code styleJohannes Schindelin via GitGitGadget, Mar 1, 2022
  54. 2/9 ci/run-build-and-tests: take a more high-level viewJohannes Schindelin via GitGitGadget, Mar 1, 2022
  55. 3/9 ci: make it easier to find failed tests' logs in the GitHub workflowJohannes Schindelin via GitGitGadget, Mar 1, 2022
  56. 4/9 ci/run-build-and-tests: add some structure to the GitHub workflow outputJohannes Schindelin via GitGitGadget, Mar 1, 2022
  57. 5/9 tests: refactor --write-junit-xml codeJohannes Schindelin via GitGitGadget, Mar 1, 2022
  58. 6/9 test(junit): avoid line feeds in XML attributesJohannes Schindelin via GitGitGadget, Mar 1, 2022
  59. 7/9 ci: optionally mark up output in the GitHub workflowJohannes Schindelin via GitGitGadget, Mar 1, 2022
  60. 8/9 ci: use `--github-workflow-markup` in the GitHub workflowJohannes Schindelin via GitGitGadget, Mar 1, 2022
  61. 9/9 ci: call `finalize_test_case_output` a little laterJohannes Schindelin via GitGitGadget, Mar 1, 2022
  62. Junio C HamanoMar 1, 2022
  63. Ævar Arnfjörð BjarmasonMar 2, 2022
  64. Johannes SchindelinMar 7, 2022
  65. Ævar Arnfjörð BjarmasonMar 7, 2022
  66. Junio C HamanoMar 7, 2022
  67. Ævar Arnfjörð BjarmasonMar 9, 2022
  68. Johannes SchindelinMar 9, 2022
  69. Junio C HamanoMar 9, 2022
  70. Ævar Arnfjörð BjarmasonMar 9, 2022
  71. Victoria DyeMar 25, 2022
  72. Ævar Arnfjörð BjarmasonMar 25, 2022
  73. Victoria DyeMar 25, 2022
  74. Johannes SchindelinMay 21, 2022
  75. Junio C HamanoMay 21, 2022
  76. Johannes SchindelinMay 22, 2022
  77. Junio C HamanoMay 22, 2022
  78. Johannes SchindelinMay 23, 2022
  79. Junio C HamanoMay 22, 2022
  80. Junio C HamanoMay 23, 2022
  81. Johannes SchindelinMay 23, 2022
  82. Ævar Arnfjörð BjarmasonMay 23, 2022
  83. Johannes SchindelinMay 23, 2022
  84. Ævar Arnfjörð BjarmasonMay 24, 2022
  85. 00/12 ci: make Git's GitHub workflow output much more helpfulJohannes Schindelin via GitGitGadget, May 21, 2022
  86. 01/12 ci: fix code styleJohannes Schindelin via GitGitGadget, May 21, 2022
  87. 02/12 tests: refactor --write-junit-xml codeJohannes Schindelin via GitGitGadget, May 21, 2022
  88. 03/12 test(junit): avoid line feeds in XML attributesJohannes Schindelin via GitGitGadget, May 21, 2022
  89. 04/12 ci/run-build-and-tests: take a more high-level viewJohannes Schindelin via GitGitGadget, May 21, 2022
  90. 05/12 ci: make it easier to find failed tests' logs in the GitHub workflowJohannes Schindelin via GitGitGadget, May 21, 2022
  91. 06/12 ci/run-build-and-tests: add some structure to the GitHub workflow outputJohannes Schindelin via GitGitGadget, May 21, 2022
  92. 07/12 ci: optionally mark up output in the GitHub workflowJohannes Schindelin via GitGitGadget, May 21, 2022
  93. 08/12 ci(github): skip the logs of the successful test casesJohannes Schindelin via GitGitGadget, May 21, 2022
  94. Ævar Arnfjörð BjarmasonMay 24, 2022
  95. 10/12 ci: use `--github-workflow-markup` in the GitHub workflowJohannes Schindelin via GitGitGadget, May 21, 2022
  96. 09/12 ci(github): avoid printing test case preamble twiceVictoria Dye via GitGitGadget, May 21, 2022
  97. 12/12 ci: call `finalize_test_case_output` a little laterJohannes Schindelin via GitGitGadget, May 21, 2022
  98. 11/12 ci(github): mention where the full logs can be foundJohannes Schindelin via GitGitGadget, May 21, 2022

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.