You've already forked sap-jenkins-library
mirror of
https://github.com/SAP/jenkins-library.git
synced 2025-09-16 09:26:22 +02:00
Merge branch 'master' into anil/kanikoPublishBuildArtifact
This commit is contained in:
12
.github/workflows/release-go.yml
vendored
12
.github/workflows/release-go.yml
vendored
@@ -98,6 +98,18 @@ jobs:
|
||||
${{ github.api_url }}/repos/${{ github.repository }}/releases/${{ steps.release_id.outputs.release_id }}
|
||||
-d '{"prerelease": false, "make_latest": true}'
|
||||
|
||||
# We need to download the shell script because reusable workflows execute
|
||||
# within the context of the workflow that calls them
|
||||
- name: Update/create dynamic tags
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
SCRIPT_RAW_URL: https://raw.githubusercontent.com/SAP/project-piper-action/refs/heads/main/.github/scripts/update_dynamic_tags.sh
|
||||
run: |
|
||||
curl -s -L "$SCRIPT_RAW_URL" -o update-dynamic-tags.sh
|
||||
chmod +x update-dynamic-tags.sh
|
||||
./update-dynamic-tags.sh "${{ env.PIPER_version }}"
|
||||
continue-on-error: true
|
||||
|
||||
# Workaround for https://github.com/SAP/jenkins-library/issues/1723, build only works with jdk8 currently
|
||||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
|
@@ -767,6 +767,7 @@ func collectVulnsAndLibsForProject(
|
||||
if err != nil {
|
||||
errorsOccurred = append(errorsOccurred, fmt.Sprint(err))
|
||||
}
|
||||
log.Entry().Infof("Current influx data : minor_vulnerabilities = %v / major_vulnerabilities = %v / vulnerabilities = %v", influx.whitesource_data.fields.minor_vulnerabilities, influx.whitesource_data.fields.major_vulnerabilities, influx.whitesource_data.fields.vulnerabilities)
|
||||
|
||||
// collect all libraries detected in all related projects and errors
|
||||
libraries, err := sys.GetProjectHierarchy(project.Token, true)
|
||||
@@ -897,9 +898,11 @@ func checkProjectSecurityViolations(config *ScanOptions, cvssSeverityLimit float
|
||||
}
|
||||
|
||||
severeVulnerabilities, nonSevereVulnerabilities := ws.CountSecurityVulnerabilities(&alerts, cvssSeverityLimit)
|
||||
influx.whitesource_data.fields.minor_vulnerabilities = nonSevereVulnerabilities
|
||||
influx.whitesource_data.fields.major_vulnerabilities = severeVulnerabilities
|
||||
influx.whitesource_data.fields.vulnerabilities = nonSevereVulnerabilities + severeVulnerabilities
|
||||
influx.whitesource_data.fields.minor_vulnerabilities += nonSevereVulnerabilities
|
||||
influx.whitesource_data.fields.major_vulnerabilities += severeVulnerabilities
|
||||
influx.whitesource_data.fields.vulnerabilities += (nonSevereVulnerabilities + severeVulnerabilities)
|
||||
log.Entry().Infof("Current influx data : minor_vulnerabilities = %v / major_vulnerabilities = %v / vulnerabilities = %v", influx.whitesource_data.fields.minor_vulnerabilities, influx.whitesource_data.fields.major_vulnerabilities, influx.whitesource_data.fields.vulnerabilities)
|
||||
|
||||
if nonSevereVulnerabilities > 0 {
|
||||
log.Entry().Warnf("WARNING: %v Open Source Software Security vulnerabilities with "+
|
||||
"CVSS score below threshold %.1f detected in project %s.", nonSevereVulnerabilities,
|
||||
@@ -910,11 +913,11 @@ func checkProjectSecurityViolations(config *ScanOptions, cvssSeverityLimit float
|
||||
}
|
||||
// https://github.com/SAP/jenkins-library/blob/master/vars/whitesourceExecuteScan.groovy#L558
|
||||
if severeVulnerabilities > 0 {
|
||||
log.Entry().Infof("%v Open Source Software Security vulnerabilities with CVSS score greater or equal to %.1f detected in project %s", severeVulnerabilities, cvssSeverityLimit, project.Name)
|
||||
if config.FailOnSevereVulnerabilities {
|
||||
log.SetErrorCategory(log.ErrorCompliance)
|
||||
return severeVulnerabilities, alerts, assessedAlerts, fmt.Errorf("%v Open Source Software Security vulnerabilities with CVSS score greater or equal to %.1f detected in project %s", severeVulnerabilities, cvssSeverityLimit, project.Name)
|
||||
}
|
||||
log.Entry().Infof("%v Open Source Software Security vulnerabilities with CVSS score greater or equal to %.1f detected in project %s", severeVulnerabilities, cvssSeverityLimit, project.Name)
|
||||
log.Entry().Info("Step will only create data but not fail due to setting failOnSevereVulnerabilities: false")
|
||||
return severeVulnerabilities, alerts, assessedAlerts, nil
|
||||
}
|
||||
|
@@ -729,6 +729,9 @@ func TestCheckProjectSecurityViolations(t *testing.T) {
|
||||
assert.Equal(t, 0, severeVulnerabilities)
|
||||
assert.Equal(t, 0, len(alerts))
|
||||
assert.Equal(t, 0, len(assessedAlerts))
|
||||
assert.Equal(t, 0, influx.whitesource_data.fields.minor_vulnerabilities)
|
||||
assert.Equal(t, 0, influx.whitesource_data.fields.major_vulnerabilities)
|
||||
assert.Equal(t, 0, influx.whitesource_data.fields.vulnerabilities)
|
||||
})
|
||||
|
||||
t.Run("error - some vulnerabilities", func(t *testing.T) {
|
||||
@@ -744,6 +747,9 @@ func TestCheckProjectSecurityViolations(t *testing.T) {
|
||||
assert.Equal(t, 1, severeVulnerabilities)
|
||||
assert.Equal(t, 2, len(alerts))
|
||||
assert.Equal(t, 0, len(assessedAlerts))
|
||||
assert.Equal(t, 1, influx.whitesource_data.fields.minor_vulnerabilities)
|
||||
assert.Equal(t, 1, influx.whitesource_data.fields.major_vulnerabilities)
|
||||
assert.Equal(t, 2, influx.whitesource_data.fields.vulnerabilities)
|
||||
})
|
||||
|
||||
t.Run("success - assessed vulnerabilities", func(t *testing.T) {
|
||||
@@ -759,6 +765,9 @@ func TestCheckProjectSecurityViolations(t *testing.T) {
|
||||
assert.Equal(t, 0, severeVulnerabilities)
|
||||
assert.Equal(t, 0, len(alerts))
|
||||
assert.Equal(t, 2, len(assessedAlerts))
|
||||
assert.Equal(t, 0, influx.whitesource_data.fields.minor_vulnerabilities)
|
||||
assert.Equal(t, 0, influx.whitesource_data.fields.major_vulnerabilities)
|
||||
assert.Equal(t, 0, influx.whitesource_data.fields.vulnerabilities)
|
||||
})
|
||||
|
||||
t.Run("error - WhiteSource failure", func(t *testing.T) {
|
||||
|
133
documentation/developer_hints/CustomErrorPatterns.md
Normal file
133
documentation/developer_hints/CustomErrorPatterns.md
Normal file
@@ -0,0 +1,133 @@
|
||||
# Custom Error Patterns for Steps
|
||||
|
||||
This document explains how to configure custom error patterns for pipeline steps to improve error detection and provide better user feedback.
|
||||
|
||||
## Overview
|
||||
|
||||
Custom error patterns allow steps to recognize specific error conditions in their output and provide enhanced error messages or categorization.
|
||||
|
||||
## Configuration
|
||||
|
||||
### Step Metadata Configuration
|
||||
|
||||
Error patterns are defined in the step's metadata YAML file under the `errors` section:
|
||||
|
||||
```yaml
|
||||
metadata:
|
||||
name: myStep
|
||||
description: "My custom step"
|
||||
errors:
|
||||
- pattern: "npm error code E401"
|
||||
message: "NPM authentication failed. Check your credentials or token."
|
||||
category: "authentication"
|
||||
- pattern: "npm error 404.*Not Found"
|
||||
message: "NPM package not found. Check package name and registry."
|
||||
category: "dependency"
|
||||
- pattern: "ENOTFOUND"
|
||||
message: "Network error. Check your connection and registry URL."
|
||||
category: "network"
|
||||
```
|
||||
|
||||
### Schema Definition
|
||||
|
||||
Each error pattern consists of:
|
||||
|
||||
- **`pattern`** (required): Regular expression or substring to match against step output
|
||||
- **`message`** (optional): Enhanced error message to show users
|
||||
- **`category`** (required): Error category for automated handling
|
||||
|
||||
## Implementation Details
|
||||
|
||||
### Pattern Matching
|
||||
|
||||
The system supports two matching modes:
|
||||
|
||||
1. **Regular Expression Matching** (preferred): Patterns are first treated as regex patterns
|
||||
2. **Substring Matching** (fallback): If regex compilation fails, falls back to substring matching
|
||||
|
||||
Examples:
|
||||
|
||||
```yaml
|
||||
# Regex pattern with wildcard
|
||||
- pattern: "npm error 404.*Not Found"
|
||||
|
||||
# Exact substring match
|
||||
- pattern: "npm error code E401"
|
||||
|
||||
# Regex with anchoring
|
||||
- pattern: "^ERROR:"
|
||||
```
|
||||
|
||||
### Runtime Behavior
|
||||
|
||||
During step execution:
|
||||
|
||||
1. All log messages are checked against configured error patterns
|
||||
2. When a pattern matches:
|
||||
- The enhanced message is stored for potential use
|
||||
- In GitHub Actions environment, appropriate logging commands are used
|
||||
- The error category can be used for automated handling
|
||||
|
||||
## Example: NPM Step
|
||||
|
||||
The `npmExecuteScripts` step demonstrates comprehensive error pattern usage:
|
||||
|
||||
```yaml
|
||||
metadata:
|
||||
name: npmExecuteScripts
|
||||
errors:
|
||||
# Authentication errors
|
||||
- pattern: "npm error code E401"
|
||||
category: "authentication"
|
||||
- pattern: "npm error Incorrect or missing password"
|
||||
message: "NPM authentication failed. Your password or token is incorrect."
|
||||
category: "authentication"
|
||||
|
||||
# Dependency errors
|
||||
- pattern: "npm error 404.*Not Found"
|
||||
message: "NPM package not found. Check package name and registry."
|
||||
category: "dependency"
|
||||
|
||||
# Network errors
|
||||
- pattern: "npm error ENOTFOUND"
|
||||
message: "NPM registry not reachable. Check network connection and registry URL."
|
||||
category: "network"
|
||||
|
||||
# Permission errors
|
||||
- pattern: "npm error EACCES"
|
||||
message: "NPM permission denied. Check file permissions or registry access rights."
|
||||
category: "permission"
|
||||
|
||||
# PNPM specific errors
|
||||
- pattern: "ERR_PNPM_FETCH_401"
|
||||
message: "PNPM authentication failed. Check your credentials or token."
|
||||
category: "authentication"
|
||||
```
|
||||
|
||||
## Integration with GitHub Actions
|
||||
|
||||
When running in GitHub Actions environment, error patterns leverage GitHub Actions logging commands:
|
||||
|
||||
- `::error::` for error messages
|
||||
- `::warning::` for warning messages
|
||||
- `::notice::` for informational messages
|
||||
|
||||
This provides better integration with GitHub Actions workflow logs and UI.
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Use Specific Patterns**: Make patterns as specific as possible to avoid false matches
|
||||
2. **Provide Helpful Messages**: Include actionable guidance in error messages
|
||||
3. **Categorize Appropriately**: Use consistent categories for similar error types
|
||||
4. **Test Patterns**: Validate regex patterns work correctly with expected error output
|
||||
5. **Document Intent**: Add comments in metadata YAML to explain complex patterns
|
||||
|
||||
## Migration Guide
|
||||
|
||||
To add error patterns to existing steps:
|
||||
|
||||
1. Edit the step's metadata YAML file in `resources/metadata/`
|
||||
2. Add the `errors` section with desired patterns
|
||||
3. Regenerate the step code: `go generate`
|
||||
4. Test the step with scenarios that trigger the error patterns
|
||||
5. Verify enhanced error messages appear correctly
|
@@ -2,6 +2,7 @@ package buildsettings
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"reflect"
|
||||
|
||||
"github.com/SAP/jenkins-library/pkg/log"
|
||||
@@ -32,6 +33,13 @@ type BuildOptions struct {
|
||||
}
|
||||
|
||||
func CreateBuildSettingsInfo(config *BuildOptions, buildTool string) (string, error) {
|
||||
// to have docker image from action inputs or env variable
|
||||
dockerImage := config.DockerImage
|
||||
if envDockerImage := os.Getenv("PIPER_dockerImage"); envDockerImage != "" {
|
||||
log.Entry().Debugf("Overriding DockerImage from env PIPER_dockerImage: '%v'", envDockerImage)
|
||||
dockerImage = envDockerImage
|
||||
}
|
||||
|
||||
currentBuildSettingsInfo := BuildOptions{
|
||||
CreateBOM: config.CreateBOM,
|
||||
GlobalSettingsFile: config.GlobalSettingsFile,
|
||||
@@ -39,7 +47,7 @@ func CreateBuildSettingsInfo(config *BuildOptions, buildTool string) (string, er
|
||||
Profiles: config.Profiles,
|
||||
Publish: config.Publish,
|
||||
DefaultNpmRegistry: config.DefaultNpmRegistry,
|
||||
DockerImage: config.DockerImage,
|
||||
DockerImage: dockerImage,
|
||||
}
|
||||
var jsonMap map[string][]interface{}
|
||||
var jsonResult []byte
|
||||
|
Reference in New Issue
Block a user