Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
49f54b0
filter out full coverage reports
ajax-gnatiuk-s May 6, 2025
cc09262
test badges
ajax-gnatiuk-s May 6, 2025
08fd763
test badges
ajax-gnatiuk-s May 6, 2025
ec2b6da
test badges
ajax-gnatiuk-s May 6, 2025
168ea0f
test badges
ajax-gnatiuk-s May 6, 2025
774d5ad
test badges
ajax-gnatiuk-s May 6, 2025
091eca4
test badges
ajax-gnatiuk-s May 6, 2025
7a1368d
test badges
ajax-gnatiuk-s May 6, 2025
e3c92ac
test badges
ajax-gnatiuk-s May 6, 2025
2f6860b
test badges
ajax-gnatiuk-s May 6, 2025
2f42662
test badges
ajax-gnatiuk-s May 7, 2025
4810348
test badges
ajax-gnatiuk-s May 7, 2025
0730609
test badges
ajax-gnatiuk-s May 7, 2025
ddd7b40
test badges
ajax-gnatiuk-s May 7, 2025
de40c55
test badges
ajax-gnatiuk-s May 7, 2025
a766d4f
test badges
ajax-gnatiuk-s May 7, 2025
0ecd33a
test badges
ajax-gnatiuk-s May 7, 2025
d341071
test badges
ajax-gnatiuk-s May 7, 2025
6abe52a
test badges
ajax-gnatiuk-s May 7, 2025
244da38
test badges
ajax-gnatiuk-s May 7, 2025
7cd824a
test badges
ajax-gnatiuk-s May 7, 2025
4eda21a
test badges
ajax-gnatiuk-s May 7, 2025
c5c5864
test badges
ajax-gnatiuk-s May 7, 2025
f9108cf
test badges
ajax-gnatiuk-s May 7, 2025
7def246
test badges
ajax-gnatiuk-s May 7, 2025
15c0636
test badges
ajax-gnatiuk-s May 7, 2025
b0b48f4
test badges
ajax-gnatiuk-s May 7, 2025
d1e3372
test badges
ajax-gnatiuk-s May 7, 2025
162c7ac
test badges
ajax-gnatiuk-s May 7, 2025
4882ce5
test badges
ajax-gnatiuk-s May 7, 2025
19d3749
test badges
ajax-gnatiuk-s May 8, 2025
9e7d8c3
test badges
ajax-gnatiuk-s May 8, 2025
908048d
Merge branch 'main' into test-badges
ajax-gnatiuk-s May 9, 2025
6620ac7
readme
ajax-gnatiuk-s May 11, 2025
f401a74
readme
ajax-gnatiuk-s May 11, 2025
b34d2c8
readme
ajax-gnatiuk-s May 11, 2025
7ac3325
readme
ajax-gnatiuk-s May 11, 2025
910a3f4
empty
ajax-gnatiuk-s May 11, 2025
f169273
readme
ajax-gnatiuk-s May 11, 2025
f5533a6
readme
ajax-gnatiuk-s May 11, 2025
b2f5d89
readme
ajax-gnatiuk-s May 11, 2025
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
40 changes: 40 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Build

on:
push:
branches:
- 'develop'
- 'main'
- 'release/**'
pull_request:
branches:
- '**'

jobs:

build:
runs-on: ubuntu-latest
permissions:
contents: read
issues: read
checks: write
pull-requests: write
packages: write

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Publish Delta Coverage
id: render-delta-coverage
uses: gw-kit/delta-coverage-action@v1
with:
summary-report-base-path: 'test/data/'

- id: upload-badges
uses: actions/upload-artifact@v4
with:
name: coverage-gen.svg
path: ${{ steps.render-delta-coverage.outputs.badges-dir }}
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Delta Coverage Action

## 1.0

- Now the action generates coverage badges for each test view.
For details see [readme](./README.md#coverage-badges).
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ Also, the action creates a comment in the pull request with links to the check r
If `title` is not blank then the previous comment generated by this action will be updated with the new report,
otherwise a new comment will be created.

## Outputs

- `badges-dir` - The directory where the coverage badges are stored.

## Pre-requisites

Required permissions:
Expand All @@ -40,3 +44,23 @@ jobs:
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
```

## Coverage Badges

The action generates coverage badges for each [coverage view](https://github.com/gw-kit/delta-coverage-plugin/blob/main/README.md#report-views).
The badges are generated based on _full coverage summary_ data files created by [Delta-Coverage plugin](https://github.com/gw-kit/delta-coverage-plugin).

⚠️ Enabling of full coverage report is required:
```kts
deltaCoverageReport {
reports {
fullCoverageReport = true
}
}
```

### Badges example

![aggregated.svg](https://raw.githubusercontent.com/gw-kit/coverage-badges/refs/heads/main/delta-coverage-plugin/badges/aggregated.svg)
![functionalTest.svg](https://raw.githubusercontent.com/gw-kit/coverage-badges/refs/heads/main/delta-coverage-plugin/badges/functionalTest.svg)
![test.svg](https://raw.githubusercontent.com/gw-kit/coverage-badges/refs/heads/main/delta-coverage-plugin/badges/test.svg)
41 changes: 28 additions & 13 deletions action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ inputs:
required: false
default: 'delta-coverage'

outputs:
badges-dir:
description: 'Directory with generated badges.'
value: ${{ steps.generate-badges.outputs.badges-dir }}

runs:
using: "composite"

Expand All @@ -36,18 +41,28 @@ runs:
with:
github-token: ${{ inputs.github-token }}
script: |
const fs = require('fs');
const files = fs.readdirSync(`${{ inputs.summary-report-base-path }}`);
const summaryFiles = files.filter(file => file.includes('-summary.json'))
.filter(file => !file.includes('full-coverage-'));

const summaries = summaryFiles.map(file =>
JSON.parse(fs.readFileSync(`build/reports/coverage-reports/${file}`, 'utf8'))
);
const allSummaries = JSON.stringify(summaries);
const allSummariesFile = 'all-summaries.json';
fs.writeFileSync(allSummariesFile, allSummaries);
core.setOutput('file', allSummariesFile);
const readSummaries = require('${{ github.action_path }}/src/read-summaries.js');
const summariesBaseDir = `${{ inputs.summary-report-base-path }}`;
const deltaSummariesFile = await readSummaries({
isFullCoverageMode: false,
baseSummariesPath: summariesBaseDir,
});
const fullCovSummariesFile = await readSummaries({
isFullCoverageMode: true,
baseSummariesPath: summariesBaseDir,
});
core.setOutput('delta', deltaSummariesFile);
core.setOutput('full', fullCovSummariesFile);

- name: Generate Badges
id: generate-badges
continue-on-error: true
shell: bash
run: |
npm install gradient-badge @actions/core
src_path="${{ github.action_path }}/src"
mv ./node_modules $src_path/
node $src_path/generate-badges.js ${{ steps.all-summaries.outputs.full }}

- name: Fetch PR Labels
id: fetch-labels
Expand Down Expand Up @@ -81,7 +96,7 @@ runs:
script: |
const createCheckRuns = require('${{ github.action_path }}/src/create-check-runs.js');
const checkRuns = await createCheckRuns({
summaryReportPath: `${{ steps.all-summaries.outputs.file }}`,
summaryReportPath: `${{ steps.all-summaries.outputs.delta }}`,
ignoreCoverageFailure: ${{ steps.check-suppress.outputs.suppress }},
core: core,
context: context,
Expand Down
52 changes: 52 additions & 0 deletions src/generate-badges.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
const fs = require('fs');
const path = require('path');
const gradientBadge = require('gradient-badge');
const core = require('@actions/core');

const badgesOutputDir = 'badges/';
fs.mkdirSync(badgesOutputDir, {recursive: true});

const secondColor = '#117efa'; // blue
const firstColors = [
'#ea00ff', // purple
'#16a41f', // green
'#16019f', // blue
'#ff1500', // red
'#ffcc00', // yellow
];

const normalizeColor = (color) => color.replace('#', '');

const mapToBadgeInputs = (index, summary) => {
const lineCoverage = summary.coverageInfo.find(coverage => coverage.coverageEntity === 'LINE');
const firstColor = firstColors[index % firstColors.length];
return {
subject: summary.view,
status: `${lineCoverage.percents}%`,
gradient: [normalizeColor(firstColor), normalizeColor(secondColor)],
};
};

const [, , summariesFile] = process.argv;
const summaries = JSON.parse(fs.readFileSync(summariesFile, 'utf8'));
summaries
.sort((a, b) => a.view.localeCompare(b.view))
.map((summary, index) => {
return {
view: summary.view,
badgeInputs: mapToBadgeInputs(index, summary),
}
})
.map(viewBadgeData => {
return {
view: viewBadgeData.view,
file: path.join(badgesOutputDir, `${viewBadgeData.view}.svg`),
badgeContent: gradientBadge(viewBadgeData.badgeInputs),
};
}).forEach(badge => {
fs.writeFileSync(badge.file, badge.badgeContent);
core.info(`🏷️ Generated badge for ${badge.view} at ${badge.file}`);
core.setOutput(badge.view, badge.file);
});

core.setOutput('badges-dir', badgesOutputDir);
21 changes: 21 additions & 0 deletions src/read-summaries.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module.exports = async (ctx) => {
const fs = require('fs');

const fullCoverageFilter = file => file.includes('full-coverage-');
const deltaCoverageFilter = file => !fullCoverageFilter(file);

const allSummariesFile = ctx.isFullCoverageMode ? 'full-cov-summaries.json' : 'delta-cov-summaries.json';

const chosenFilter = ctx.isFullCoverageMode ? fullCoverageFilter : deltaCoverageFilter;

const files = fs.readdirSync(ctx.baseSummariesPath);
const summaryFiles = files.filter(file => file.includes('-summary.json')).filter(chosenFilter);
console.log(`Reading summaries from ${ctx.baseSummariesPath}: ${JSON.stringify(summaryFiles, null, 2)}`);

const summaries = summaryFiles.map(file =>
JSON.parse(fs.readFileSync(`${ctx.baseSummariesPath}/${file}`, 'utf8'))
);
fs.writeFileSync(allSummariesFile, JSON.stringify(summaries));

return allSummariesFile;
};
29 changes: 29 additions & 0 deletions test/data/full-coverage-aggregated-summary.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"view": "aggregated",
"reportBound": "DELTA_REPORT",
"coverageRulesConfig": {
"failOnViolation": false,
"entitiesRules": {}
},
"verifications": [],
"coverageInfo": [
{
"coverageEntity": "INSTRUCTION",
"covered": 9406,
"total": 10775,
"percents": 87.29
},
{
"coverageEntity": "BRANCH",
"covered": 303,
"total": 377,
"percents": 80.37
},
{
"coverageEntity": "LINE",
"covered": 1943,
"total": 2209,
"percents": 87.96
}
]
}
1 change: 1 addition & 0 deletions test/data/full-coverage-functionalTest-summary.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"view":"functionalTest","reportBound":"DELTA_REPORT","coverageRulesConfig":{"failOnViolation":false,"entitiesRules":{}},"verifications":[],"coverageInfo":[{"coverageEntity":"INSTRUCTION","covered":6843,"total":10775,"percents":63.51},{"coverageEntity":"BRANCH","covered":180,"total":377,"percents":47.75},{"coverageEntity":"LINE","covered":1395,"total":2196,"percents":63.52}]}
1 change: 1 addition & 0 deletions test/data/full-coverage-test-summary.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"view":"test","reportBound":"DELTA_REPORT","coverageRulesConfig":{"failOnViolation":false,"entitiesRules":{}},"verifications":[],"coverageInfo":[{"coverageEntity":"INSTRUCTION","covered":8860,"total":10775,"percents":82.23},{"coverageEntity":"BRANCH","covered":280,"total":371,"percents":75.47},{"coverageEntity":"LINE","covered":1800,"total":2187,"percents":82.3}]}
1 change: 1 addition & 0 deletions version.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
version=1.0.0
Loading