Skip to content

Commit

Permalink
Support for raw coverage file
Browse files Browse the repository at this point in the history
- Update README with instructions for raw file and Java example
  • Loading branch information
MikeEdgar committed May 6, 2020
1 parent 348853a commit eb405b7
Show file tree
Hide file tree
Showing 4 changed files with 223 additions and 29 deletions.
48 changes: 47 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ The action's step needs to run after your test suite has outputted an LCOV file.
| Name | Requirement | Description |
| --------------------- | ----------- | ----------- |
| `github-token` | _required_ | Must be in form `github-token: ${{ secrets.GITHUB_TOKEN }}`; Coveralls uses this token to verify the posted coverage data on the repo and create a new check based on the results. It is built into Github Actions and does not need to be manually specified in your secrets store. [More Info](https://help.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token)|
| `path-to-lcov` | _optional_ | Default: "./coverage/lcov.info". Local path to the lcov output file produced by your test suite. An error will be thrown if the file can't be found. This is the file that will be sent to the Coveralls API. |
| `path-to-file` | _optional_ | Default: "./coverage/lcov.info". Local path to the coverage output file produced by your test suite. An error will be thrown if the file can't be found. This is the file that will be sent to the Coveralls API. |
| `path-to-lcov` | _optional_ | **Deprecated, use `path-to-file`**. Default: "./coverage/lcov.info". Local path to the lcov output file produced by your test suite. An error will be thrown if the file can't be found. This is the file that will be sent to the Coveralls API. |
| `coverage-format` | _optional_ | The format of your coverage file. Supported values are `lcov` and `raw`. defaults to `lcov`. `raw` formatted file must already contain the coverage information in Coveralls JSON format. |
| `flag-name` | _optional (unique required if parallel)_ | Job flag name, e.g. "Unit", "Functional", or "Integration". Will be shown in the Coveralls UI. |
| `parallel` | _optional_ | Set to true for parallel (or matrix) based steps, where multiple posts to Coveralls will be performed in the check. `flag-name` needs to be set and unique, e.g. `flag-name: run-${{ matrix.test_number }}` |
| `parallel-finished` | _optional_ | Set to true in the last job, after the other parallel jobs steps have completed, this will send a webhook to Coveralls to set the build complete. |
Expand Down Expand Up @@ -107,6 +109,50 @@ jobs:
The "Coveralls Finished" step needs to run after all other steps have completed; it will let Coveralls know that all jobs in the build are done and aggregate coverage calculation can be calculated and notifications sent.
### Java Analysis using coveralls-maven-plugin
When using the coveralls-maven-plugin, execute the `coveralls:report` Maven goal with the option `-DdryRun=true` to generate a Coveralls JSON file at `./target/coveralls.json`. The Coveralls github-action can then be configured to accept the `raw` file type and the path to the JSON file.

The following example demonstrates how to test your build with both Java 8 and 11, generating and analysing with Coveralls only for Java 11.

```yaml
on: ["push", "pull_request"]
name: Test Coveralls Java and Maven
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
java: [8, 11]
name: Build with JDK ${{matrix.java}}
steps:
- uses: actions/checkout@v2
name: Checkout
- uses: actions/setup-java@v1.3.0
name: Setup JDK ${{matrix.java}}
with:
java-version: ${{matrix.java}}
- name: Maven build
run: mvn -B verify package --file pom.xml
- name: Generate Coveralls File
if: matrix.java == '11'
run: mvn -B coveralls:report -DdryRun=true
- name: Coveralls Analysis
if: matrix.java == '11'
uses: coverallsapp/github-action@master
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
path-to-file: ./target/coveralls.json
coverage-format: raw
```

## Demo

![demo](https://s3.amazonaws.com/assets.coveralls.io/Coveralls%20Github%20Action%20Demo%20-%20trimmed%20-%204.8x720.gif)
Expand Down
10 changes: 9 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,18 @@ author: 'Nick Merwin (Coveralls, Inc.)'
inputs:
github-token:
required: true
path-to-file:
description: 'Path to coverage file'
required: true
default: './coverage/lcov.info'
path-to-lcov:
description: 'Path to lcov file'
description: 'Path to lcov file (Deprecated)'
required: true
default: './coverage/lcov.info'
coverage-format:
description: ' Format of coverage file. Acccepted values are `lcov` and `raw`. Defaults to `lcov`'
required: true
default: 'lcov'
parallel:
description: 'Set to true if you are running parallel jobs, then use "parallel_finished: true" for the last action.'
required: false
Expand Down
93 changes: 79 additions & 14 deletions lib/run.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Expand Down Expand Up @@ -78,28 +79,92 @@ function run() {
return 0;
}
process.env.COVERALLS_PARALLEL = process.env.COVERALLS_PARALLEL || core.getInput('parallel');
const defaultPath = './coverage/lcov.info';
const defaultType = 'lcov';
const pathToFile = core.getInput('path-to-file');
const pathToLcov = core.getInput('path-to-lcov');
if (pathToLcov == '') {
throw new Error("No Lcov path specified.");
const formatInput = core.getInput('coverage-format');
const filetype = formatInput !== defaultType ? formatInput : defaultType;
if (filetype !== defaultType && filetype !== 'raw') {
throw new Error(`Unsupported file format: ${filetype}`);
}
console.log(`Using lcov file: ${pathToLcov}`);
// for compatibility with the name path-to-lcov - go through these steps
// 1. use 'path-to-file' if its not the default path
// 2. use 'path-to-lcov' if its not the default
// 3. use 'path-to-file' (which will be the default at this point in time - but i made it more explicit)
const pathToUse = pathToFile !== defaultPath ? pathToFile : ((pathToLcov !== defaultPath) ? pathToLcov : pathToFile);
if (pathToUse == '') {
throw new Error("No file path specified.");
}
console.log(`Using ${filetype} file: ${pathToUse}`);
let file;
try {
file = fs_1.default.readFileSync(pathToLcov, 'utf8');
file = fs_1.default.readFileSync(pathToUse, 'utf8');
}
catch (err) {
throw new Error("Lcov file not found.");
throw new Error(`${filetype} file not found.`);
}
const basePath = core.getInput('base-path');
const adjustedFile = basePath ? lcov_processor_1.adjustLcovBasePath(file, basePath) : file;
coveralls.handleInput(adjustedFile, (err, body) => {
if (err) {
core.setFailed(err);
}
else {
core.setOutput('coveralls-api-result', body);
}
});
if (filetype === 'raw') {
coveralls.getOptions((err, options) => {
if (err) {
core.setFailed(err);
}
const postJson = JSON.parse(adjustedFile);
if (options.flag_name) {
postJson.flag_name = options.flag_name;
}
if (options.git) {
postJson.git = options.git;
}
if (options.run_at) {
postJson.run_at = options.run_at;
}
if (options.service_name) {
postJson.service_name = options.service_name;
}
if (options.service_number) {
postJson.service_number = options.service_number;
}
if (options.service_job_id) {
postJson.service_job_id = options.service_job_id;
}
if (options.service_pull_request) {
postJson.service_pull_request = options.service_pull_request;
}
if (options.repo_token) {
postJson.repo_token = options.repo_token;
}
if (options.parallel) {
postJson.parallel = options.parallel;
}
if (options.flag_name) {
postJson.flag_name = options.flag_name;
}
coveralls.sendToCoveralls(postJson, (err, response, body) => {
if (response.statusCode >= 400) {
core.setFailed(`Bad response: ${response.statusCode} ${body}`);
}
if (err) {
core.setFailed(err);
}
else {
core.setOutput('coveralls-api-result', body);
}
});
});
}
else {
coveralls.handleInput(adjustedFile, (err, body) => {
if (err) {
core.setFailed(err);
}
else {
core.setOutput('coveralls-api-result', body);
}
});
}
}
catch (error) {
core.setFailed(error.message);
Expand Down
101 changes: 88 additions & 13 deletions src/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,34 +78,109 @@ export async function run() {

process.env.COVERALLS_PARALLEL = process.env.COVERALLS_PARALLEL || core.getInput('parallel');

const defaultPath = './coverage/lcov.info';
const defaultType = 'lcov';

const pathToFile = core.getInput('path-to-file');
const pathToLcov = core.getInput('path-to-lcov');

if (pathToLcov == '') {
throw new Error("No Lcov path specified.");
const formatInput = core.getInput('coverage-format');
const filetype = formatInput !== defaultType ? formatInput : defaultType;

if (filetype !== defaultType && filetype !== 'raw') {
throw new Error(`Unsupported file format: ${filetype}`);
}

console.log(`Using lcov file: ${pathToLcov}`);
// for compatibility with the name path-to-lcov - go through these steps
// 1. use 'path-to-file' if its not the default path
// 2. use 'path-to-lcov' if its not the default
// 3. use 'path-to-file' (which will be the default at this point in time - but i made it more explicit)
const pathToUse = pathToFile !== defaultPath ? pathToFile : ((pathToLcov !== defaultPath) ? pathToLcov : pathToFile);
if (pathToUse == '') {
throw new Error("No file path specified.");
}

console.log(`Using ${filetype} file: ${pathToUse}`);

let file;

try {
file = fs.readFileSync(pathToLcov, 'utf8');
file = fs.readFileSync(pathToUse, 'utf8');
} catch (err) {
throw new Error("Lcov file not found.");
throw new Error(`${filetype} file not found.`);
}


const basePath = core.getInput('base-path');
const adjustedFile = basePath ? adjustLcovBasePath(file, basePath) : file;

coveralls.handleInput(adjustedFile, (err: string, body: string) => {
if(err){
core.setFailed(err);
} else {
core.setOutput('coveralls-api-result', body);
}
});
if (filetype === 'raw') {
coveralls.getOptions((err: string, options: any) => {
if (err) {
core.setFailed(err);
}

const postJson = JSON.parse(adjustedFile);

if (options.flag_name) {
postJson.flag_name = options.flag_name;
}

if (options.git) {
postJson.git = options.git;
}

if (options.run_at) {
postJson.run_at = options.run_at;
}

if (options.service_name) {
postJson.service_name = options.service_name;
}

if (options.service_number) {
postJson.service_number = options.service_number;
}

if (options.service_job_id) {
postJson.service_job_id = options.service_job_id;
}

if (options.service_pull_request) {
postJson.service_pull_request = options.service_pull_request;
}

if (options.repo_token) {
postJson.repo_token = options.repo_token;
}

if (options.parallel) {
postJson.parallel = options.parallel;
}
if (options.flag_name) {
postJson.flag_name = options.flag_name;
}

coveralls.sendToCoveralls(postJson, (err: string, response: any, body: string) => {
if (response.statusCode >= 400) {
core.setFailed(`Bad response: ${response.statusCode} ${body}`);
}

if(err){
core.setFailed(err);
} else {
core.setOutput('coveralls-api-result', body);
}
});
});
} else {
coveralls.handleInput(adjustedFile, (err: string, body: string) => {
if(err){
core.setFailed(err);
} else {
core.setOutput('coveralls-api-result', body);
}
});
}
} catch (error) {
core.setFailed(error.message);
}
Expand Down

0 comments on commit eb405b7

Please sign in to comment.