Plugins

Discover, select, pin, enable, and update Evaluation Pipeline plugins in Divekit.

The plugin system is still experimental, but the usage flow documented here reflects the current intended workflow.

What Plugins Do

Evaluation Pipeline plugins add optional CI modules to eval repositories. Typical examples are PMD, Surefire, or JaCoCo/PIT analysis plugins.

Each plugin has two main controls:

  • add (alias use): choose the source or project, optionally pin a ref, and enable the plugin
  • enable or disable: toggle whether the plugin runs after it has been configured

Use pin when you only want to change the Git ref for an already configured plugin.

Typical Workflow

# 1) Inject plugin-capable Evaluation Pipeline CI templates
divekit plugin install

# 2) Discover available plugins from trusted sources
divekit plugin discover

# 3) Add a plugin from the official source and pin a version
divekit plugin add pmd --source official --ref v0.3.0

# 4) Refresh injected templates while preserving plugin state
divekit plugin refresh

Running divekit plugin without subcommands opens an interactive selector for toggling plugin activation. divekit plugin update is kept as a compatibility alias for refresh.

Select A Plugin Repository

There are two supported ways to point a plugin to repository content:

  • --source <name> selects a configured discovery source such as official
  • --project <group>/<repo> points directly to one GitLab project path

Use --source when the plugin should be resolved from a named trusted source. Use --project when you want to test against a specific repository directly, for example a temporary fork or an alternative plugin repository.

Examples:

# Resolve PMD from the default trusted source
divekit plugin add pmd --source official --ref v0.3.0

# Test Surefire from a specific repository directly
divekit plugin add surefire --project my-org/divekit-plugin-surefire-test --ref my-branch

# Use a non-default host alias together with a direct project path
divekit plugin add surefire --project my-org/divekit-plugin-surefire-test --host gitnrw --ref my-branch

--source and --project are alternatives for the same command. Do not combine them in one invocation.

Official Source

Default official source:

  • source name: official
  • host alias: gitnrw
  • source path: divekit/plugins

List configured sources:

divekit plugin source list

The source value is the configured source name, not a raw repository URL or project path.

Additional Sources

You can add your own trusted source:

divekit plugin source add my-team --host gitnrw --group my-org/plugins --trusted

For a single repository instead of a whole group:

divekit plugin source add my-team-surefire --host gitnrw --project my-org/divekit-plugin-surefire-test --trusted

Discover only from that source:

divekit plugin discover --source my-team

Remove it again:

divekit plugin source remove my-team

Where State Is Stored

  • project-level plugin state: .divekit/eval-pipeline/plugins.json
  • distribution-specific plugin state: .divekit/distributions/<distribution>/eval-pipeline/plugins.json
  • managed plugin CI files: .divekit/eval-pipeline/eval/.gitlab/ci/divekit/plugins/<plugin-id>.yml
  • user-level sources: ~/.divekit/plugin-sources.json

plugins.json stores execution-relevant plugin state such as enabled, host, project, and ref. Named discovery sources are stored separately in plugin-sources.json.

When evaluation repositories are generated, managed plugin CI files are placed under .gitlab/ci/divekit/plugins/ in the eval repository and included by the eval CI template. The old eval-plugins.json location is legacy state and may be cleaned up by newer plugin commands.

For stable SemVer refs such as v1.2.3, Divekit materializes plugin files from the plugin’s GitLab release ZIP asset when one is available. Legacy plugin tags without such an asset fall back to the repository tree at that ref. Branch and commit refs continue to read directly from the repository tree, which keeps development and testing flows simple.

Feedback On GitLab Pages

Plugins can publish feedback that appears on the generated GitLab Page of the eval repository. Students only need the Pages link; they do not need access to the eval repository, and Divekit does not write feedback back into student or work repositories.

Feedback may be a concrete failure explanation or a reusable FAQ entry. Plugin jobs publish it as artifacts under plugin-results/<plugin-id>/feedback/. The pages job collects those artifacts automatically when it runs divekit report --report-dir plugin-results.

The generated Page shows feedback next to the plugin report section. For tools that need a machine-readable export, the same information is written to public/feedback.json. public/export.json remains the regular report-data export and does not include feedback content. Feedback items declared in feedback/index.json can set defaultOpen to control whether they are expanded initially.

Individual report entries in plugin-results/<plugin-id>/report.json may also include notices. Notices are short plain-text annotations rendered above that report body, for example to explain that a plugin accepted a partial result by policy. They are part of the report entry itself, not global feedback.

For build failures or plugin execution problems, plugins can publish plugin-results/<plugin-id>/issues/index.json plus Markdown/log files. Those issues are shown separately from tests and exported to public/issues.json.

Manual Report Overrides

Course staff can force selected plugin report results to a different status in evaluation repositories. The common use case is marking a failed report result as successful after a manual review.

The interactive flow is the preferred way to create an override:

divekit plugin override -d ST2M4

The wizard asks for:

  • the plugin
  • the scope: stable testId, category + name, a complete category, or all report results from that plugin
  • the target eval repositories: group IDs, all eval repositories, or members
  • an optional reason

Group IDs are the UUIDs from members.json/remotes.json. They identify the individualized group across the target repositories. The interactive flow creates successful overrides. Use the non-interactive --status flag when you need to force another status.

The non-interactive form is useful for repeatable operations:

# One stable report result for selected groups
divekit plugin override add jacoco-pit -d ST2M4 \
  --test-id coverage-threshold \
  --group-ids b8520e99-2bad-c0de-b61c-1249a10f7a5a,a70decaf-bad7-4c95-b211-d0bc95f48204

# One report result by rendered category and name
divekit plugin override add jacoco-pit -d ST2M4 \
  --category Coverages \
  --name CoverageResult \
  --group-ids b8520e99-2bad-c0de-b61c-1249a10f7a5a \
  --reason "Accepted after manual review"

# A complete category
divekit plugin override add jacoco-pit -d ST2M4 \
  --category Coverages \
  --group-ids b8520e99-2bad-c0de-b61c-1249a10f7a5a

# Everything produced by one plugin
divekit plugin override add jacoco-pit -d ST2M4 \
  --all-tests \
  --group-ids b8520e99-2bad-c0de-b61c-1249a10f7a5a

# Force a warning instead of the default success status
divekit plugin override add jacoco-pit -d ST2M4 \
  --test-id coverage-threshold \
  --members alice,bob \
  --status warning

Overrides are stored in eval repositories under .divekit/overrides/. Older eval repositories may still contain the legacy .divekit/plugin/overrides/ path; divekit report keeps reading it for compatibility. divekit report applies them after collecting plugin results. The report page shows that a result was manually overridden and keeps the original result body visible for review.

Target eval repositories with exactly one of:

  • --group-ids, repeated or comma-separated group UUIDs
  • --members, repeated or comma-separated member names
  • --members-file, one member name per line
  • --all, every eval repository in the distribution

Supported forced statuses are success, warning, failure, and fatal. warning is treated as successful by the report result calculation, but still marks the result visibly as a warning. Use --dry-run to preview the patch without writing override files.

Remove an override by id:

divekit plugin override remove jacoco-pit-coverage-threshold-20260529t091500z \
  -d ST2M4 \
  --group-ids b8520e99-2bad-c0de-b61c-1249a10f7a5a

Patch Existing Repositories

After changing plugin configuration for repositories that already exist, refresh the generated origin-side artifacts and patch the plugin state path:

divekit plugin refresh
divekit patch ci -d ST2M4

When you want to move all configured plugins to their newest stable versions first, upgrade them before patching:

divekit plugin refresh
divekit plugin upgrade --all
divekit patch ci -d ST2M4

For distribution-specific plugin state, target the distribution and patch its state file:

divekit plugin refresh -d ST2M4
divekit plugin upgrade --all -d ST2M4
divekit patch ci -d ST2M4

divekit patch ci collects the authored Evaluation Pipeline files from .divekit/eval-pipeline/ and the selected distribution override directory, then patches the generated runtime files into the existing distributed repositories. Use divekit patch ci -d ST2M4 --dry-run to inspect the plan first.