Use jq to print only the percentages of coverage from a json-summary file to markdown in github actions - jestjs

I want to pretty print my json-coverage jest results to github actions. I have a ci.yml file with the following:
- name: Run Unit Tests
run: |
yarn test:next:unit --runInBand --coverage --coverageReporters="text-summary"
- name: Echo Coverage
run: |
cat coverage/coverage-summary.json | head -1 > coverage-testing/coverage.json
This prints the first line of jest's coverage-summary in the job terminal and it looks like this:
{"total": {"lines":{"total":18326,"covered":11,"skipped":0,"pct":0.06},"statements":{"total":62625,"covered":11,"skipped":0,"pct":0.01},"functions":{"total":19047,"covered":4,"skipped":0,"pct":0.02},"branches":{"total":60202,"covered":11,"skipped":0,"pct":0.01},"branchesTrue":{"total":0,"covered":0,"skipped":0,"pct":100}}
}
I can print this directly to my github action run in the UI by adding this to the ci.yml:
- name: Print to github
run: cat coverage-testing/coverage.json >> $GITHUB_STEP_SUMMARY
and it shows up in github action run under annotations
jest-next summary
{"total": {"lines":{"total":52,"covered":11,"skipped":0,"pct":21.15},"statements":{"total":54,"covered":11,"skipped":0,"pct":20.37},"functions":{"total":16,"covered":4,"skipped":0,"pct":25},"branches":{"total":18,"covered":11,"skipped":0,"pct":61.11},"branchesTrue":{"total":0,"covered":0,"skipped":0,"pct":100}}
Job summary generated at run-time
Now for the pretty printing. I've tried some various jq commands including iterating with to_entries in a way that would make the github action job summary look more like markdown. I got errors because the array was nested and I got those errors to go away by changing -r to -R and adding try, but then nothing printed to github. Since these attempts are all in CI and the jest tests are flaky, changing one thing and waiting is getting cumbersome. Does anyone happen to have a script that does this already? Not picky about how it's formatted, I'd just like it to look less like json and more like markdown.

You can pretty quickly present it as a list of path/value pairs by streaming in the input. You could then join the paths to a more readable form and dump it.
$ jq -r --stream 'select(length == 2)|"\(.[0]|join("_")): \t\(.[1])"' input.json
total_lines_total: 18326
total_lines_covered: 11
total_lines_skipped: 0
total_lines_pct: 0.06
total_statements_total: 62625
total_statements_covered: 11
total_statements_skipped: 0
total_statements_pct: 0.01
total_functions_total: 19047
total_functions_covered: 4
total_functions_skipped: 0
total_functions_pct: 0.02
total_branches_total: 60202
total_branches_covered: 11
total_branches_skipped: 0
total_branches_pct: 0.01
total_branchesTrue_total: 0
total_branchesTrue_covered: 0
total_branchesTrue_skipped: 0
total_branchesTrue_pct: 100
If you want to retain some structure, you'll need to decide on that first...

Related

How to set a "title" or "name" for a bitbucket script execution element?

i am wondering whether or not one can set a title or name for an execution element in a bitbucket pipeline:
pipelines:
default:
- step:
script: # Modify the commands below to build your repository.
- "Configure": ./configure
- "Build": make
- "Test": make test
- "Long Script": |
make whatever1
make whatever2
make whatever3
I'd expect the output to be:
Configure
Build
Test
Long Script
within the titles, and seeing the script only, if I unfolding the execution elements in the UI, just like with github:
Any ideas? :-)
The only one I found was to put everthing in bash scripts, but then I do not see the executed command, which I still want.
Thanks.
Any step of your pipeline can have its own name property, a good example can be found here.
In case you'd like to assign names to individual commands of your step's script, I reckon echo would be a good option:
echo "Test" && make test

Publishing test results to Azure (VS Database Project, tSQLt, Azure Pipelines, Docker)

I am trying to fully automate the build, test, and release of a database project using Azure Pipeline.
I already have a Visual Studio solution which consists of three database projects. The first project is the database, which contains the tables, stored procedures, functions, data, etc.. The second project is the tSQLt framework (v 1.0.5873.27393 if anyone is interested). And finally the third project is the tSQLt tests.
My goal here to check the solution into source control, and the pipeline will automatically build the solution, deploy the dacpacs to a build server (docker in this case), run the tSQLt tests, and publish the results back to the pipeline.
My pipeline works like this.
Building the visual studio solution
Publish the Artifacts
Setup a docker container running Ubuntu & SQL Server
Install SQLPackage
Deploy the dacpacs to the SQL instance
Run the tSQLt tests
Publish the test results
Everything up to publishing the results is working, but on this step I got the following error:
[warning]Failed to read /home/vsts/work/1/Results.xml. Error : Data at the root level is invalid. Line 1, position 1.
I added another step in the pipeline to display the content of the Results.xml file. It appears like this:
XML_F52E2B61-18A1-11d1-B105-00805F49916B
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
<testsuites><testsuite id="1" name="MyNewTestClassOne" tests="1" errors="0" failures="0" timestamp="2021-02-01T10:40:31" time="0.000" hostname="f6a05d4a3932" package="tSQLt"><properties/><testcase classname="MyNewTestClassOne" name="TestNumberOne" time="0.
I'm not sure if the column name and dashes should be in the file, but I'm guessing not. I added another step in to remove them, just leaving me with the XML. But this then gave me a different error to deal with:
##[warning]Failed to read /home/vsts/work/1/Results.xml. Error : There is an unclosed literal string. Line 2, position 1.
This one is a little obvious to spot, because as you'll see above, the XML is incomplete.
Here is the part of my pipeline which runs the tSQLt tests and outs the results to Results.xml
- script: |
sqlcmd -S 127.0.0.1,1433 -U SA -P Password.1! -d StagingDB -Q 'EXEC tSQLt.RunAll;'
displayName: 'tSQLt - Run All Tests'
- script: |
cd $(Pipeline.Workspace)
sqlcmd -S 127.0.0.1,1433 -U SA -P Password.1! -d StagingDB -Q 'SET NOCOUNT ON; EXEC tSQLt.XmlResultFormatter;' -o 'tSQLt_Results.xml'
displayName: 'tSQLt - Output Results'
I've research so many blogs and articles on this, and most people are doing the same. Some people use PowerShell instead of sqlcmd, but given I'm using a Ubuntu machine this isn't an option here.
I am all out of options, so I am looking for a little help on this.
You are dealing with 2 problems here. There is noise in your result set, that is not xml and your xml result is truncated after 256 characters. I can help you with both.
What I am doing is basically this:
/opt/mssql-tools/bin/sqlcmd \
-S "localhost, 31114" -U sa \
-P "password" \
-d dbname \
-y0 \
-Q "BEGIN TRY EXEC tSQLt.RunAll END TRY BEGIN CATCH END CATCH; EXEC tSQLt.XmlResultFormatter" \
| grep -w "<testsuites>" \
| tee "resultfile.xml"
Few things to note:
y0 important. This sets the length of the xml result set to unlimited, up from 256.
grep with a regular expression - make sure you only get the xml and not the noise around it.
If you want to run only a subset of your tests, you need to make amendments to the SQL query being passed in, but other than that, this is a catch it all "oneliner" to run all tests and get the results in xml format, readable by Azure DevOps

How to run an individual test with Stack and Haskell Test.Framework?

I'm cloning the following repository and making one change to the stack.yaml by adding at the end:
docker:
enable: true
To run all the tests for haskoin-core I'm using
stack test haskoin-core:test-haskoin-core
What I want to do is run just one test. If this were HSpec (which it is not) I'd be running something like:
stack test --test-arguments -m "Network.Haskoin.Network.Units"
Now what I could do is modify the file haskcoin-core/test/Main.hs and comment out all the tests I don't want to run. But ya know - there should be a simpler way to run it with just command line parameters. (Mutating the file system goes agains the whole functional grain of Haskell).
I'd also be open to running it with stack ghci somehow.
My question is: How to run an individual test with Stack and Haskell Test.Framework?
As of mid 2019, I think stack has changed.
See --help for options:
stack test --test-arguments "--help"
Do a --dry-run to see what tests will run:
stack test --test-arguments "--dry-run"
Select tests with --match. Note, this alleges glob patterns will work but they don't seem to for me:
stack test --test-arguments "--match=foobar"
AFAICT, "foobar" is interpreted like a glob of *foobar*, but I can't be explicit about it.
Thanks to #sjakobi for this answer.
The process is - list the available test commands:
stack test --test-arguments "--help" haskoin-core:test-haskoin-core
This gives the following result:
haskoin-core-0.4.2: test (suite: test-haskoin-core, args: --help)
Usage: test-haskoin-core [OPTIONS]
--help show this help message
-j NUMBER --threads=NUMBER number of threads to use to run tests
--test-seed=NUMBER|random default seed for test random number generator
-a NUMBER --maximum-generated-tests=NUMBER how many automated tests something like QuickCheck should try, by default
--maximum-unsuitable-generated-tests=NUMBER how many unsuitable candidate tests something like QuickCheck should endure before giving up, by default
-s NUMBER --maximum-test-size=NUMBER to what size something like QuickCheck should test the properties, by default
-d NUMBER --maximum-test-depth=NUMBER to what depth something like SmallCheck should test the properties, by default
-o NUMBER --timeout=NUMBER how many seconds a test should be run for before giving up, by default
--no-timeout specifies that tests should be run without a timeout, by default
-l --list-tests list available tests but don't run any; useful to guide subsequent --select-tests
-t TEST-PATTERN --select-tests=TEST-PATTERN only tests that match at least one glob pattern given by an instance of this argument will be run
--jxml=FILE write a JUnit XML summary of the output to FILE
--jxml-nested use nested testsuites to represent groups in JUnit XML (not standards compliant)
--plain do not use any ANSI terminal features to display the test run
--color use ANSI terminal features to display the test run
--hide-successes hide sucessful tests, and only show failures
Test suite failure for package haskoin-core-0.4.2
test-haskoin-core: exited with: ExitFailure 1
Logs printed to console
From that we can build a command to list the tests:
stack test --test-arguments "--list-tests" haskoin-core:test-haskoin-core
From there we can use this command to glob for a particular test
stack test --test-arguments=--select-tests=Bloom*Filter haskoin-core:test-haskoin-core
Note the * in place of the space, there seems to be some discussion about how to handle spaces in this scenario.
Now this selects the tests we want to run:
haskoin-core-0.4.2: test (suite: test-haskoin-core, args: --select-tests=Bloom*Filter)
Binary encoding and decoding of bloom types:
BloomFilter: [OK, passed 100 tests]
Bloom Filters:
Bloom Filter Vector 1: [OK]
Bloom Filter Vector 2: [OK]
Bloom Filter Vector 3: [OK]
Properties Test Cases Total
Passed 1 3 4
Failed 0 0 0
Total 1 3 4

Bash run a function in background

Have a relatively simple question here. I need to run a function in the background in bash. Normally I would do it just like so:
FUNCTION &
but things are a bit more complicated than that. I have the following line that runs the main function for each record in a text database. I cant really edit this code all that much without vastly changing the rest of the entire project, but im still open to new ideas.
cat databases/$WAN | grep -v \# | while read LINE; do MAIN; done
I want to spawn a new terminal in background for each record to do a sort of parallel type processing, making things go much faster. Main takes a minute to process for each record. This however does not work.
cat databases/$WAN | grep -v \# | while read LINE; do MAIN &; done
Any suggestions?
* UPDATE *
Thanks for all the responses. Let me see if I can answer some of those questions.
gniourf_gniourf - Yes I know using cat like this is wrong. This was early on, and critical code, so I have not updated it yet. I now read into the while loop for most things I do. I will fix it eventually. You may be right about syntax. When I break it up like so, things seem to work now:
cat databases/$WAN | grep -v \# | while read LINE
do
MAIN & > /dev/null 2>&1
done
So that fixes the background problem. I wonder what was messed up in my single line syntax. Thanks
chepner - I don't believe LINE is a variable. I could be wrong though. Some things about Bash still confuse me. Maybe it is and is a variable that the entire record from the database gets stored to prior to processing.
Bruce K - Waiting is exactly what I was trying to avoid. If I let it run in the same terminal one at a time, it will slowly process each record in order. If I push each record to a seperate terminal for processing, all records will be processed simultaneously (at least in our eyes). The additional overhead is intentional in order to speed up how quickly the loop through the database occurs.
Radix - Yes you're right. I'll read up on that. Thanks for the link.
This worked for me:
$ function testt(){ echo "lineee is <$lineee>";}
$ grep 5432 /etc/services|while read lineee;do testt&done
lineee is <postgres 5432/udp # POSTGRES>
lineee is <postgres 5432/tcp # POSTGRES>
If, for some reason, your MAIN function is not seeing a LINE variable, you can try:
"export" the LINE variable beforehand:
$ export LINE
$ # do your thing
Or, pass the line read as an argument to the function:
$ function testt(){ LINE="$1"; echo "LINE is <$LINE>";}
$ grep 5432 /etc/services|while read LINE;do testt "$LINE"&done

How do I print the first few lines of a makefile (-Wall -g flags)?

How do I get the first n lines of the output of a makefile (specifically, my complier is g++). Either a script in linux or in the makefile would work (if you could provide both, that'll be even better).
I have tried
make | head -n 5
but it's not working.
Currently, the process I go through is tedious; I'm piping the output to a text file before using head on it (then having to delete the file).
Given that the messages from the compiler appear on standard error rather than standard output, you need to redirect both:
make 2>&1 | head -n 20
(I think 5 lines will be too small to be useful.)

Resources