Skip to content

Use artifact types in plugin coverage and adjust the logic #1037

@AndriiSiuta

Description

@AndriiSiuta

User story

As a user of code-pushup plugins I want to have the shared feature artifact generation implemented in the coverage plugin.
It should be aligned with other plugins that use the same feature.


Current Problem:
We don't have artifactOptions for plugin-coverage.
Users have no possibility to add custom generateArtifactsCommand and artifactsPaths.
Also reports type isn't inline:

{
resultPath: string
pathToProject: string
}
Example:
{
    pathToProject: 'packages/plugin-coverage',
    resultsPath: 'coverage\\plugin-coverage\\unit-tests\\lcov.info'
},

Current Config:

// Single coverage report, no caching
// Assumed npm script:
// "test": "npx jest --coverage --coverageReporters=lcov"
await coveragePlugin({
  reports: [
   {
     resultPath: 'coverage/lcov.info'
  }
],
  coverageToolCommand: {
    command: 'npm',
    args: ['run', 'test'],
  },
});

// Multiple coverage report, no caching
// Assumed npm script:
// "unit-test": "npx jest --coverage --coverageReporters=lcov --reportsDirectory=coverage/{{projectName}}/unit-tests
// "int-test": "npx jest --coverage --coverageReporters=lcov --reportsDirectory=coverage/{{projectName}}/init-tests
// "test-all": "npm run int-test && npm run unit-test

await coveragePlugin({
  reports: [{ resultPath: `coverage/${projectName}/unit-tests/lcov.info`}, {resultPath:`coverage/${projectName}/lcov.info`}],
  coverageToolCommand: {
    command: 'npm',
    args: ['run', 'test-all'],
  },
});

// Single coverage report, nx caching
// Assumed nx target:
// "test": "npm run test"

await coveragePlugin({
  reports: [{ resultPath: `coverage/lcov.info`', pathToProject: `${workspaceRoot}/packages/${projectName}` }],
  coverageToolCommand: {
    command: 'npx',
    args: ['nx', 'run', `${projectName}:test`],
  },
});

// Multiple coverage report, nx caching
// Assumed nx targets:
// "unit-test": "npm run unit-test"
// "int-test": "npm run int-test"

await coveragePlugin({
  reports: [{resultPath: `coverage/${projectName}/lcov.info`, pathToProject: `${workspaceRoot}/packages/${projectName}`}, coverage/${projectName}/lcov.info`],
  coverageToolCommand: {
    command: 'npx',
    args: ['nx', 'run-many', '-t', 'unit-test,int-test', '-p', `${projectName}`],
  },
});

Solution:

  1. Remove coverageToolCommand and reports from coveragePluginConfigSchema.
  2. Use merge with pluginArtifactOptionsSchema.
  3. Adjust coverageResultSchema.

Suggested Config:

// Single coverage report, no caching
await coveragePlugin({
  artifactsPaths: ['coverage/lcov.info'],
  generateArtifactsCommand: {
    command: 'npm',
    args: ['run', 'test'],
  },
});

// Multiple coverage report, no caching
await coveragePlugin({
  artifactsPaths: [`coverage/${projectName}/unit-tests/lcov.info`, `coverage/${projectName}/int-test/lcov.info`],
  generateArtifactsCommand: {
    command: 'npm',
    args: ['run', 'test-all'],
  },
});

// Single coverage report, nx caching
await coveragePlugin({
  artifactsPaths: [`coverage/${projectName}/lcov.info`],
  generateArtifactsCommand: {
    command: 'npx',
    args: ['nx', 'run', `${projectName}:test`],
  },
});

// Multiple coverage report, nx caching
await coveragePlugin({
  artifactsPaths: [`coverage/${projectName}/unit-test/lcov.info, coverage/${projectName}/int-test/lcov.info`],
  generateArtifactsCommand: {
    command: 'npx',
    args: ['nx', 'run-many', '-t', 'unit-test,int-test', '-p', `${projectName}`],
  },
  pathToProjects: [`${worksapceRoot}/packages/${projectName}`]
});

Acceptance criteria:

  • Remove coverageToolCommand and reports from coveragePluginConfigSchema.
  • Merge in pluginArtifactOptionsSchema.
  • Adjust coverageResultSchema.
  • New logic is tested.
  • Documentation is updated.
  • Existing configuration is updated.

Implementation details

  1. Merged pluginArtifactOptionsSchema - The coverage plugin now extends the base plugin artifact options schema:
   export const coverageArtifactOptionsSchema = pluginArtifactOptionsSchema.extend({
     artifactsPaths: z.union([
       z.string().includes('lcov', { message: 'Invalid input: must include lcov in file path' }),
       z.array(z.string().includes('lcov', { message: 'Invalid input: must include lcov in file path' })).min(1)
     ]),
     pathToProjects: z
       .array(z.string(), {
         description:
           'Array of paths from workspace root to project roots. Maps to artifactsPaths for LCOV path resolution.',
       })
       .optional(),
   });
  1. Remove legacy properties - Old coverageToolCommand and reports properties have to be removed from the schema.
  2. Enhanced artifact validation - Add LCOV file validation to ensure only valid coverage reports are accepted.
    ✅ Plugin update:
    Updated coveragePlugin() function in packages/plugin-coverage/src/lib/coverage-plugin.ts:
// Extract artifact options from config
const { artifactsPaths, generateArtifactsCommand, pathToProjects, ...pluginConfig } = coverageConfig;
const artifactOptions = artifactsPaths ? {
  artifactsPaths,
  ...(generateArtifactsCommand && { generateArtifactsCommand }),
} : undefined;

// Pass artifact options to runner when available
runner: await createRunnerConfig(
  runnerScriptPath,
  {
    artifactsPaths,
    ...pluginConfig,
  },
  artifactOptions,
),
  1. Update all unit tests in packages/plugin-coverage/src/lib/coverage-plugin.unit.test.ts to use new artifactsPaths property instead of legacy reports.
  2. Run documentation update command.
  3. Update code-pushup-config:
    Single coverage report:
await coveragePlugin({
  artifactsPaths: ['coverage/lcov.info'],
  generateArtifactsCommand: {
    command: 'npm',
    args: ['run', 'test'],
  },
});

Multiple coverage reports with nx:

await coveragePlugin({
  artifactsPaths: [
    `coverage/${projectName}/unit-test/lcov.info`,
    `coverage/${projectName}/int-test/lcov.info`
  ],
  generateArtifactsCommand: {
    command: 'npx',
    args: ['nx', 'run-many', '-t', 'unit-test,int-test', '-p', `${projectName}`],
  },
  pathToProjects: [
    `${workspaceRoot}/packages/${projectName}`,
    `${workspaceRoot}/packages/${projectName}`
  ],
});

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions