Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support custom working directory input #57

Merged
merged 7 commits into from
Sep 30, 2022
Merged
Show file tree
Hide file tree
Changes from 6 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
6 changes: 5 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ jobs:
# Remove node_modules to see if this action runs entirely compiled
- name: 'Remove Node Modules'
run: rm -rf node_modules
- name: 'Use this action'
- name: 'Test Working Directory Option'
davelosert marked this conversation as resolved.
Show resolved Hide resolved
uses: ./
with:
working-directory: './test/mockReports'
- name: 'Test Default Action'
# run step also on failure of the previous step
if: always()
uses: ./
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,13 @@ jobs:

### Options

| Option | Description | Default |
| ----------------- | ------------------------------------------------------------------------------------------------ | ---------------------------------- |
| json-summary-path | The path to the json summary file. Uses "coverage/coverage-summary.json" by default. | `./coverage/coverage-summary.json` |
| json-final-path | The path to the json final file. Uses "coverage/coverage-final.json" by default. | `./coverage/coverage-final.json` |
| vite-config-path | The path to the vite config file. Uses "vite.config.js" by default. | `./vitest.config.js` |
| github-token | A github access token with permissions to write to issues. Uses secrets.GITHUB_TOKEN by default. | `./vitest.config.js` |
| Option | Description | Default |
| ------------------- | ----------------------------------------------------------------------------------------------- | ---------------------------------- |
| `json-summary-path` | The path to the json summary file. | `./coverage/coverage-summary.json` |
| `json-final-path` | The path to the json final file. | `./coverage/coverage-final.json` |
| `vite-config-path` | The path to the vite config file. | `./vitest.config.js` |
| `github-token` | A GitHub access token with permissions to write to issues (defaults to `secrets.GITHUB_TOKEN`). | `${{ github.token }}` |
| `working-directory` | Run action within a custom directory (for monorepos). | `./` |

### Coverage Thresholds

Expand Down
4 changes: 4 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ inputs:
required: false
description: 'The path to the json final file. Uses "coverage/coverage-final.json" by default.'
default: coverage/coverage-final.json
working-directory:
required: false
description: 'Custom working directory'
davelosert marked this conversation as resolved.
Show resolved Hide resolved
default: ./
runs:
using: 'node16'
main: 'dist/index.js'
Expand Down
26 changes: 17 additions & 9 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,35 @@
import { generateSummaryTableData } from './generateSummaryTableHtml.js';
import path from 'node:path';
import { parseJsonFinal, parseJsonSummary } from './parseJsonReports.js';
import { parseVitestJsonFinal, parseVitestJsonSummary } from './parseJsonReports.js';
import { writeSummaryToPR } from './writeSummaryToPR.js';
import * as core from '@actions/core';
import { parseThresholds } from './parseThresholds.js';
import { parseCoverageThresholds } from './parseCoverageThresholds.js';
import { generateFileCoverageHtml } from './generateFileCoverageHtml.js';

const run = async () => {
const jsonSummaryPath = path.resolve(core.getInput('json-summary-path'));
const jsonFinalPath = path.resolve(core.getInput('json-final-path'));
const viteConfigPath = path.resolve(core.getInput('vite-config-path'));
// Working directory can be used to modify all default/provided paths (for monorepos, etc)
const workingDirectory = core.getInput('working-directory');

const jsonSummary = await parseJsonSummary(jsonSummaryPath);
const jsonFinal = await parseJsonFinal(jsonFinalPath);
const thresholds = await parseThresholds(viteConfigPath);
const jsonSummaryPath = path.resolve(workingDirectory, core.getInput('json-summary-path'));
const jsonFinalPath = path.resolve(workingDirectory, core.getInput('json-final-path'));
const viteConfigPath = path.resolve(workingDirectory, core.getInput('vite-config-path'));

const jsonSummary = await parseVitestJsonSummary(jsonSummaryPath);
const jsonFinal = await parseVitestJsonFinal(jsonFinalPath);
const thresholds = await parseCoverageThresholds(viteConfigPath);

const tableData = generateSummaryTableData(jsonSummary.total, thresholds);
const fileTable = generateFileCoverageHtml({
jsonSummary, jsonFinal
});

let summaryHeading = "Coverage Summary";
if (workingDirectory) {
summaryHeading += ` for \`${workingDirectory}\``;
davelosert marked this conversation as resolved.
Show resolved Hide resolved
}

const summary = core.summary
.addHeading('Coverage Summary')
.addHeading(summaryHeading, 2)
davelosert marked this conversation as resolved.
Show resolved Hide resolved
.addRaw(tableData)
.addDetails('File Coverage', fileTable)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
import { describe, it, expect } from 'vitest';
import path from 'path';
import { parseThresholds } from './parseThresholds';
import { parseCoverageThresholds } from './parseCoverageThresholds';

describe('generateTableData', () => {
const mockConfigPath = path.resolve(__dirname, '..', 'test', 'mockConfig');
const getConfig = (configName: string) => path.resolve(mockConfigPath, configName)

it('returns no thresholds if config file can not be found.', async (): Promise<void> => {
const thresholds = await parseThresholds(getConfig('doesNotExist'));
const thresholds = await parseCoverageThresholds(getConfig('doesNotExist'));

expect(thresholds).toEqual({});
});

it('returns no thresholds if non are provided in the config file', async (): Promise<void> => {
const thresholds = await parseThresholds(getConfig('vitest.config.none.js'));
const thresholds = await parseCoverageThresholds(getConfig('vitest.config.none.js'));

expect(thresholds).toEqual({});
});

it('reads all the thresholds from the given configuration file.', async (): Promise<void> => {
const thresholds = await parseThresholds(getConfig('vitest.config.all.js'));
const thresholds = await parseCoverageThresholds(getConfig('vitest.config.all.js'));

expect(thresholds).toEqual({
lines: 60,
Expand All @@ -30,7 +30,7 @@ describe('generateTableData', () => {
});

it('sets thresholds to 100 if 100 property is true.', async (): Promise<void> => {
const thresholds = await parseThresholds(getConfig('vitest.config.100.js'));
const thresholds = await parseCoverageThresholds(getConfig('vitest.config.100.js'));

expect(thresholds).toEqual({
lines: 100,
Expand Down
5 changes: 2 additions & 3 deletions src/parseThresholds.ts → src/parseCoverageThresholds.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import path from 'node:path';
import * as core from '@actions/core';
import { promises as fs } from 'fs';
import { Thresholds } from './types/Threshold';

Expand All @@ -9,7 +8,7 @@ const regexLines = /lines:\s*(\d+)/;
const regexBranches = /branches\s*:\s*(\d+)/;
const regexFunctions = /functions\s*:\s*(\d+)/;

const parseThresholds = async (vitestConfigPath: string): Promise<Thresholds> => {
const parseCoverageThresholds = async (vitestConfigPath: string): Promise<Thresholds> => {
try {
const resolvedViteConfigPath = path.resolve(process.cwd(), vitestConfigPath);
const rawContent = await fs.readFile(resolvedViteConfigPath, 'utf8');
Expand Down Expand Up @@ -45,5 +44,5 @@ const parseThresholds = async (vitestConfigPath: string): Promise<Thresholds> =>
}

export {
parseThresholds,
parseCoverageThresholds,
};
20 changes: 10 additions & 10 deletions src/parseJsonReports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,33 @@ import { JsonFinal } from './types/JsonFinal';
import { JsonSummary } from './types/JsonSummary';
import { stripIndent } from 'common-tags';

const parseJsonReport = async <type extends JsonSummary | JsonFinal>(jsonSummaryPath: string): Promise<type> => {
const resolvedJsonSummaryPath = path.resolve(process.cwd(), jsonSummaryPath);
const parseVitestCoverageReport = async <type extends JsonSummary | JsonFinal>(jsonPath: string): Promise<type> => {
const resolvedJsonSummaryPath = path.resolve(process.cwd(), jsonPath);
const jsonSummaryRaw = await readFile(resolvedJsonSummaryPath);
return JSON.parse(jsonSummaryRaw.toString()) as type;
}

const parseJsonSummary = async (jsonSummaryPath: string): Promise<JsonSummary> => {
const parseVitestJsonSummary = async (jsonSummaryPath: string): Promise<JsonSummary> => {
try {
return await parseJsonReport<JsonSummary>(jsonSummaryPath);
return await parseVitestCoverageReport<JsonSummary>(jsonSummaryPath);
} catch (err: any) {
core.setFailed(stripIndent`
Failed to parse the json-summary at path "${jsonSummaryPath}."
Make sure to run vitest before this action and to include the "json-summay" reporter.
Make sure to run vitest before this action and to include the "json-summary" reporter.

Original Error:
${err.stack}
`);

// rethrow to abort everything
// Rethrow to abort the entire workflow
throw err;

}
}

const parseJsonFinal = async (jsonFinalPath: string): Promise<JsonFinal> => {
const parseVitestJsonFinal = async (jsonFinalPath: string): Promise<JsonFinal> => {
try {
return await parseJsonReport<JsonFinal>(jsonFinalPath);
return await parseVitestCoverageReport<JsonFinal>(jsonFinalPath);
} catch (err: any) {
core.warning(stripIndent`
Failed to parse JSON Final at path "${jsonFinalPath}".
Expand All @@ -45,6 +45,6 @@ const parseJsonFinal = async (jsonFinalPath: string): Promise<JsonFinal> => {
};

export {
parseJsonSummary,
parseJsonFinal
parseVitestJsonSummary,
parseVitestJsonFinal,
};
12 changes: 12 additions & 0 deletions test/mockReports/vite.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { defineConfig } from 'vite';

export default defineConfig({
test: {
coverage: {
all: true,
reporter: ['text', 'json-summary', 'json'],
include: ['src'],
exclude: ['src/types'],
}
}
});