Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
105 changes: 105 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Repository Guidelines

## Project Purpose & Structure

The **Sysdig Secure Jenkins Plugin** integrates Sysdig Secure image scanning into Jenkins pipelines and freestyle jobs. It enables automated security scans and policy evaluations for container images.

### Module Organization
The codebase follows a **Hexagonal Architecture (Ports & Adapters)** to decouple the core domain from external dependencies (Jenkins, Sysdig API).

- **`src/main/java/com/sysdig/jenkins/plugins/sysdig/`**:
- **`domain/`**: Core business logic (e.g., `ImageScanner`, `ScanResult`). Pure Java, no external dependencies.
- **`application/`**: Use cases and orchestration (e.g., `ImageScanningService`).
- **`infrastructure/`**: Implementations of ports (e.g., `jenkins/` for Jenkins integration, `scanner/` for Sysdig CLI).
- **`src/main/resources/`**: Jelly files for Jenkins UI (`index.jelly`) and other resources.
- **`src/test/java/`**: Unit and integration tests, mirroring the package structure.

## Build, Test, & Development

This project uses **Maven** for build management and optionally **Nix** for a consistent environment.

### Key Commands

- **Build Plugin**: `mvn clean package` (generates `target/sysdig-secure.hpi`).
- **Run Tests**: `mvn clean verify` (runs unit and integration tests).
- **Run Locally**: `mvn hpi:run` (starts a local Jenkins instance with the plugin installed).
- **Format Code**: `make format` (applies Spotless formatting).
- **Verify All**: `make verify` (runs formatting check + tests).
- **Dev Shell**: `nix develop` (enters a shell with Java/Maven pre-configured).

## Coding Style & Naming

- **Architecture**: Strictly adhere to Hexagonal Architecture. Do not leak Jenkins or Sysdig API dependencies into the `domain` package.
- **Formatting**:
- **Java**: 4 spaces indentation.
- **XML/JS**: 2 spaces indentation.
- Enforced via **Spotless**. Always run `make format` before committing.
- **Naming**: Use descriptive, standard Java naming conventions (CamelCase for classes, camelCase for methods/variables).

## Testing Guidelines

- **Frameworks**: JUnit, Mockito.
- **Coverage**: Aim for high coverage in `domain` logic.
- **Conventions**:
- Unit tests should mock external dependencies (ports).
- Integration tests (in `infrastructure/` or `e2e/`) verify interactions with Jenkins or real APIs.
- **Execution**: Run specific tests via Maven or all tests with `mvn clean verify`.

## Commit & Pull Request Guidelines

### Commit Messages
Follow **Conventional Commits**:
- Format: `<type>(<scope>): <description>`
- Types: `feat`, `fix`, `refactor`, `chore`, `test`, `docs`.
- Examples:
- `feat(ui): add image diff table`
- `fix(scanner): respect accepted risks in policy evaluation`
- `refactor(domain): split policy rules`

### Pull Requests
- Link relevant issues (e.g., "Fixes #149").
- Include a summary of changes.
- For UI changes, attach screenshots.
- Ensure `make verify` passes locally.

## Documentation Updates

The agent must keep this file (`AGENTS.md`) and `README.md` updated as the project evolves.
- If a new build tool or key command is added, update this guide.
- Suggest documentation improvements to the user if existing docs are unclear or outdated.

## Maintenance Guidelines

This project includes a `Makefile` to simplify common maintenance tasks. **It is highly recommended to run `make update`** to perform a complete project update, as it orchestrates all maintenance tasks (Jenkins version, Parent POM, dependencies, etc.) in the correct order.

### Updating Dependencies & Parent POM
Regularly update the parent POM and project dependencies to ensure security and compatibility.

1. **Update Parent POM**:
Run `make update-parent-pom` (executes `mvn versions:update-parent`).
*Reference: [Update parent POM](https://www.jenkins.io/doc/developer/tutorial-improve/update-parent-pom/)*

2. **Update Dependencies**:
Run `make update-dependencies` (executes `mvn versions:use-latest-versions`).

3. **Update All (Recommended)**:
Run `make update` to update the parent POM, dependencies, flake, and the Sysdig CLI version in one go.

### Updating Base Jenkins Version
**Important:** Update the base Jenkins version **before** updating the parent POM or other dependencies.

1. **Run Automation**:
Run `make update-jenkins-version`. This command:
- Fetches the latest **unmaintained LTS version** from [endoflife.date](https://endoflife.date/jenkins).
- Calculates the corresponding baseline (e.g., `2.516`).
- Fetches the latest available **Bill of Materials (BOM)** version for that baseline.
- Updates `jenkins.baseline`, `jenkins.version`, and the BOM dependency in `pom.xml` automatically using `sed`.

2. **Verify**:
Run `make verify` to ensure the plugin builds and tests pass with the new version.

### Updating Sysdig CLI Version
To update the embedded Sysdig CLI version used by the scanner:

1. Run `make update-sysdig-cli-version`.
This fetches the latest version from Sysdig and updates `RemoteSysdigImageScanner.java`.
15 changes: 14 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@

update: update-parent-pom update-dependencies update-flake update-sysdig-cli-version
update: update-jenkins-version update-parent-pom update-dependencies update-flake update-sysdig-cli-version

update-jenkins-version:
@echo "Fetching latest unmaintained LTS Jenkins version..."
@version=$$(curl -s https://endoflife.date/api/v1/products/jenkins/ | jq -r '.result.releases | map(select(.isMaintained == false)) | first | .latest.name') && \
baseline=$$(echo $$version | cut -d. -f1-2) && \
echo "Found Jenkins version: $$version (Baseline: $$baseline)" && \
echo "Fetching latest BOM version for bom-$$baseline.x..." && \
bom_version=$$(curl -s "https://repo.jenkins-ci.org/public/io/jenkins/tools/bom/bom-$$baseline.x/maven-metadata.xml" | grep -oPm1 "(?<=<latest>)[^<]+") && \
echo "Found BOM version: $$bom_version" && \
sed -i 's|<jenkins.baseline>.*</jenkins.baseline>|<jenkins.baseline>'$$baseline'</jenkins.baseline>|' pom.xml && \
sed -i 's|<jenkins.version>.*</jenkins.version>|<jenkins.version>'$$version'</jenkins.version>|' pom.xml && \
sed -i "/<artifactId>bom-\$${jenkins.baseline}.x<\/artifactId>/,+2 s|<version>.*</version>|<version>$$bom_version</version>|" pom.xml && \
echo "Updated pom.xml to Jenkins $$version, Baseline $$baseline, BOM $$bom_version"

update-parent-pom:
mvn versions:update-parent -DgenerateBackupPoms=false
Expand Down
6 changes: 3 additions & 3 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>5.27</version>
<version>6.2111.v8b_6a_1d599df3</version>
<relativePath />
</parent>

Expand Down Expand Up @@ -41,8 +41,8 @@
<properties>
<!-- You can check out which versions are being used per version in https://stats.jenkins.io/pluginversions/sysdig-secure.html -->
<!-- https://www.jenkins.io/doc/developer/plugin-development/choosing-jenkins-baseline/ -->
<jenkins.baseline>2.479</jenkins.baseline>
<jenkins.version>${jenkins.baseline}.3</jenkins.version>
<jenkins.baseline>2.516</jenkins.baseline>
<jenkins.version>2.516.3</jenkins.version>
<ban-junit4-imports.skip>false</ban-junit4-imports.skip>
<!-- https://www.jenkins.io/doc/developer/plugin-development/mark-a-plugin-incompatible/ -->
<hpi.compatibleSinceVersion>3.0</hpi.compatibleSinceVersion>
Expand All @@ -57,7 +57,7 @@
<groupId>io.jenkins.tools.bom</groupId>
<artifactId>bom-${jenkins.baseline}.x</artifactId>
<!-- You can find your version for the selected baseline in: https://repo.jenkins-ci.org/public/io/jenkins/tools/bom/ -->
<version>5054.v620b_5d2b_d5e6</version>
<version>5857.vb_f3dd0731f44</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.sysdig.jenkins.plugins.sysdig.domain.vm.scanresult;

import com.sysdig.jenkins.plugins.sysdig.domain.vm.scanresult.diff.ScanResultDiff;
import edu.umd.cs.findbugs.annotations.Nullable;
import java.io.Serializable;
import java.math.BigInteger;
import java.util.*;
import javax.annotation.Nullable;

public class ScanResult implements Serializable {
private final EvaluationResult globalEvaluationResult;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.sysdig.jenkins.plugins.sysdig.domain.vm.scanresult;

import com.sysdig.jenkins.plugins.sysdig.domain.AggregateChild;
import edu.umd.cs.findbugs.annotations.Nullable;
import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;
import javax.annotation.Nullable;

public class Vulnerability implements AggregateChild<ScanResult>, Serializable {
private final String cve;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
import java.net.URL;

public class RemoteSysdigImageScanner {
private static final String FIXED_SCANNED_VERSION = "1.23.0";
private static final String FIXED_SCANNED_VERSION = "1.24.2";
private final ScannerPaths scannerPaths;
private final String imageName;
private final RetriableRemoteDownloader retriableRemoteDownloader;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ void testPolicyEvaluationSummaryIsGeneratedCorrectly() throws IOException {
// Then
// FIXME(fede): the "URL" part should be the rule description, currently it's empty in sysdig-cli-scanner
// 1.22.3. I expect this will be fixed in newer versions.
JsonElement expectedJson = JsonParser.parseString(
"""
JsonElement expectedJson = JsonParser.parseString("""
{
"columns":[
{"title":"Tag"},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ void testPipelineWithCredentialsAndAssertLogOutput() throws Exception {

@Test
void testPipelineWithAllConfigs() throws Exception {
var job = helpers.createPipelineJobWithScript(
"""
var job = helpers.createPipelineJobWithScript("""
sysdigImageScan engineCredentialsId: 'sysdig-secure',
engineURL: 'https://custom-engine-url.com',
engineVerify: false,
Expand All @@ -56,8 +55,7 @@ void testPipelineWithAllConfigs() throws Exception {
cliVersionToApply: 'custom',
policiesToApply: 'custom-policy-name',
bailOnFail: false,
bailOnPluginFail: false""")
.buildWithRemoteExecution();
bailOnPluginFail: false""").buildWithRemoteExecution();

var build = jenkins.buildAndAssertSuccess(job);

Expand Down Expand Up @@ -105,8 +103,7 @@ void testPipelineWithMinimalConfigButAlsoGlobalConfig() throws Exception {

@Test
void testPipelineWithImageToCompareConfig() throws Exception {
var job = helpers.createPipelineJobWithScript(
"""
var job = helpers.createPipelineJobWithScript("""
sysdigImageScan engineCredentialsId: 'sysdig-secure',
engineURL: 'https://custom-engine-url.com',
engineVerify: false,
Expand All @@ -115,8 +112,7 @@ void testPipelineWithImageToCompareConfig() throws Exception {
customCliVersion: '2.0.0',
cliVersionToApply: 'custom',
bailOnFail: false,
bailOnPluginFail: false""")
.buildWithRemoteExecution();
bailOnPluginFail: false""").buildWithRemoteExecution();

var build = jenkins.buildAndAssertSuccess(job);

Expand Down
Loading