ci: add Trivy security scan to PR pipeline - #92
Conversation
|
Warning Review limit reached
Next review available in: 44 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
WalkthroughAdds a composite Trivy action that installs and caches Trivy, resolves Maven dependencies when needed, scans repository dependencies and Dockerfile base images, groups findings, and fails on HIGH or CRITICAL vulnerabilities. Adds a pull-request workflow job with read-only permissions and includes it in 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/steps/trivy/action.yml:
- Around line 37-39: Remove the -fn fail-never flag from the margs array used by
the Maven dependency:go-offline invocation, while preserving the remaining Maven
arguments and existing warning handling.
- Around line 56-67: Update the image-processing loop around the img variable to
track unresolved “$VAR” references and failed trivy image scans as skipped
images, while continuing to process the remaining entries. After the imgs.txt
loop completes, exit nonzero when any image was skipped; retain successful
scanning and alias/scratch filtering behavior.
- Around line 21-23: Remove the maven-token export as GITHUB_TOKEN in
.github/steps/trivy/action.yml lines 21-23, and prevent credentialed Maven
execution from loading the PR-controlled .mvn/settings.xml at lines 37-39 by
using a trusted settings file when credentials are required. In
.github/workflows/test.yml lines 40-48, remove packages: read from the untrusted
PR scan or otherwise ensure no credentials reach PR-controlled Maven execution.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: babf883c-dadc-41a7-8cd8-1ef148f05a8c
📒 Files selected for processing (3)
.github/steps/trivy/action.yml.github/workflows/test.yml.trivyignore
| env: | ||
| GITHUB_TOKEN: ${{ inputs.maven-token }} | ||
| GITHUB_ACTOR: ${{ github.actor }} |
There was a problem hiding this comment.
🔒 Security & Privacy | 🔴 Critical | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Repository files of interest:"
git ls-files | grep -E '^\.(github/(steps/trivy/action\.yml|workflows/test\.yml)|mvn/settings\.xml|pom\.xml)' || true
echo
echo "test.yml excerpt:"
if [ -f .github/workflows/test.yml ]; then
nl -ba .github/workflows/test.yml | sed -n '1,120p'
fi
echo
echo "trivy action.yml excerpt:"
if [ -f .github/steps/trivy/action.yml ]; then
nl -ba .github/steps/trivy/action.yml | sed -n '1,120p'
fi
echo
echo "Search for maven-token / package permission / settings usage:"
rg -n "maven-token|GITHUB_TOKEN|permissions:|packages:|persist-credentials|\.mvn/settings\.xml|settings\.xml|mvn\s+-|dependency:go-offline" .github pom.xml || trueRepository: flamingo-stack/fleetmdm
Length of output: 309
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "test.yml excerpt:"
if [ -f .github/workflows/test.yml ]; then
awk '{printf "%6d\t%s\n", NR, $0}' .github/workflows/test.yml | sed -n '1,140p'
fi
echo
echo "trivy action.yml excerpt:"
if [ -f .github/steps/trivy/action.yml ]; then
awk '{printf "%6d\t%s\n", NR, $0}' .github/steps/trivy/action.yml | sed -n '1,120p'
fi
echo
echo "Search for relevant identifiers:"
rg -n "maven-token|GITHUB_TOKEN|permissions:|packages:|persist-credentials|\.mvn/settings\.xml|settings\.xml|mvn\s|dependency:go-offline|github\.event\.pull_request" .github pom.xml || trueRepository: flamingo-stack/fleetmdm
Length of output: 12620
🌐 Web query:
Maven Settings reference -s settings and -gs global settings can invoke code plugin extensions
💡 Result:
Maven's settings.xml and global settings files cannot directly invoke or register code plugin extensions [1][2][3]. The Maven settings files (~/.m2/settings.xml and ${MAVEN_HOME}/conf/settings.xml) are designed for environment-specific configuration, such as local repository paths, authentication credentials, proxies, and profile definitions [2][4][3]. They do not possess the capability to load or activate Maven extensions [1][5]. Maven extensions, which adjust build behavior or add functionality to the Maven Core, are instead configured through the following dedicated mechanisms [5][6]: 1..mvn/extensions.xml: The standard, project-level approach for registering extensions [1][5]. You define the extension using its Maven coordinates (groupId, artifactId, version) within this file located in the project's root .mvn/ directory [1][7]. 2. Project-level Build Extensions: Configured within a project's pom.xml under <build><extensions> or by setting <extensions>true</extensions> within a specific plugin configuration [5]. 3. Command Line: Extensions can be loaded temporarily using the -Dmaven.ext.class.path=extension.jar argument [1][5][6]. While settings files can define plugin groups (via the <pluginGroups> element) to simplify command-line execution by allowing Maven to resolve plugin group IDs automatically, this is distinct from invoking or loading code extensions [2][8].
Citations:
- 1: https://maven.apache.org/configure
- 2: https://maven.apache.org/settings.html
- 3: https://maven.apache.org/ref/4-LATEST/api/maven-api-settings/settings.html
- 4: https://maven.apache.org/guides/mini/guide-configuring-maven.html
- 5: https://maven.apache.org/guides/mini/guide-using-extensions.html
- 6: https://github.com/apache/maven-site/blob/master/content/markdown/reference/maven-classloading.md
- 7: https://github.com/apache/maven-site/blob/HEAD/content/markdown/configure.md
- 8: https://maven.apache.org/settings
🌐 Web query:
Maven dependency plugin lifecycle phases extensions settings include extensions in dependency tree documentation
💡 Result:
The Apache Maven Dependency Plugin does not have a dedicated configuration setting or lifecycle phase parameter to explicitly "include extensions" in the dependency tree. In Maven, extensions (artifacts with the type maven-extension) are typically loaded at the start of the build process to extend core Maven functionality and are generally not managed as standard project dependencies that appear in the typical mvn dependency:tree output [1][2][3]. Key points regarding dependency tree and plugin configuration: 1. Dependency Tree Filtering: The dependency:tree goal allows filtering by group ID, artifact ID, type, and version using the includes and excludes parameters [1][4][5]. Because extensions have a specific maven-extension type, you can attempt to include them in the tree output by specifying this type in your filter pattern if they are present in the project's dependency graph [1][4]. The filter syntax follows the pattern [groupId]:[artifactId]:[type]:[version] [1][4]. 2. Dependency Tree Scope: You can use the scope parameter to filter the dependency tree resolution by a specific scope (e.g., compile, runtime, test), or leave it empty to include all scopes [1][2]. 3. Plugin Lifecycle: The Maven Dependency Plugin goals (like tree, list, copy-dependencies) can be bound to any lifecycle phase via the standard Maven plugin configuration in your pom.xml [6]. However, they do not inherently alter how extensions are loaded or reported [1][7]. If you are trying to view or verify build extensions, these are usually defined in the <build><extensions> section of the pom.xml or via project-level metadata, rather than as standard dependencies that the dependency:tree goal is designed to visualize [3].
Citations:
- 1: https://maven.apache.org/plugins/maven-dependency-plugin/tree-mojo.html
- 2: https://maven.apache.org/components/plugins/maven-dependency-plugin/tree-mojo.html
- 3: https://maven.apache.org/plugins-archives/maven-dependency-plugin-LATEST/examples/tree-mojo.html
- 4: https://maven.apache.org/plugins/maven-dependency-plugin/examples/filtering-the-dependency-tree.html
- 5: https://maven.apache.org/plugins/maven-dependency-plugin/xref/org/apache/maven/plugins/dependency/tree/TreeMojo.html
- 6: https://maven.apache.org/components/plugins/maven-dependency-plugin/examples/copying-project-dependencies.html
- 7: https://maven.apache.org/plugins/maven-dependency-plugin/
🌐 Web query:
search.maven.org metadata maven extension type artifact extensions repository documentation
💡 Result:
In Apache Maven, the term "extension" is used in two distinct, unrelated contexts that are often confused [1]. 1. Maven Build Extensions (Functional Extensions) These are JAR artifacts used to extend Maven's core functionality (e.g., adding wagon providers for repository transport or lifecycle enhancements) [2]. They are not defined by a "type" in the dependency sense, but are instead loaded via specific configurations in the project POM or command line [2]. - Configuration: Declared in the section of the pom.xml or via.mvn/extensions.xml [2][3]. - Documentation: Refer to the Maven guide on Using Extensions [2]. 2. Artifact Types and Extensions (File Extensions) In the context of repository metadata and dependency declarations, "extension" refers to the file format of an artifact (e.g., jar, pom, war) [1]. - Type: The element in a dependency declaration is used to determine the artifact's file extension, classifier, and how it is handled in the build (e.g., whether it is added to the classpath) [1][4][5]. - Mapping: Maven core defines default handlers that map specific "types" to their corresponding file extensions (e.g., the 'java-source' type maps to a 'jar' extension with a 'sources' classifier) [1][5]. Regarding search.maven.org: - Status: This service has been superseded by https://central.sonatype.com [6]. While the web interface has been redirected, the API remains available for programmatic access [6]. - Metadata: Repository metadata, including artifact file extensions, can be explored via the Central Repository REST API [7][8]. When searching, you can filter by artifact characteristics, though the distinction between a "build extension" and an "artifact extension" (file type) remains essential for interpreting results correctly [1][8].
Citations:
- 1: https://svn.apache.org/repos/asf/maven/website/content/repositories/artifacts.html
- 2: https://maven.apache.org/guides/mini/guide-using-extensions.html
- 3: https://maven.apache.org/ref/4-LATEST/api/maven-api-cli/core-extensions.html
- 4: https://maven.apache.org/ref/4-LATEST/api/maven-api-core/apidocs/org/apache/maven/api/Type.html
- 5: https://maven.apache.org/components/ref/3-LATEST/maven-core/artifact-handlers.html
- 6: https://central.sonatype.org/faq/what-happened-to-search-maven-org/
- 7: https://central.sonatype.org/search/example-urls/
- 8: https://skills.sh/partme-ai/full-stack-skills/maven-search
Remove package credentials from the pull-request scan.
trivy_scan checks out PR code, grants packages: read, and passes the GitHub token into Maven while also loading .mvn/settings.xml from the PR. Treat the packages scope as untrusted for this workflow and do not expose the token to untrusted Maven configuration.
.github/steps/trivy/action.yml#L21-L23: do not exportmaven-tokenasGITHUB_TOKENfor pull-request scans..github/steps/trivy/action.yml#L37-L39: do not load.mvn/settings.xmlfrom the pull request when a credential is available; use a trusted settings file if credentials are required..github/workflows/test.yml#L40-L42: removepackages: readfrom the untrusted PR scan or keep credentials out of untrusted Maven execution.
📍 Affects 2 files
.github/steps/trivy/action.yml#L21-L23(this comment).github/steps/trivy/action.yml#L37-L39.github/workflows/test.yml#L40-L48
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/steps/trivy/action.yml around lines 21 - 23, Remove the maven-token
export as GITHUB_TOKEN in .github/steps/trivy/action.yml lines 21-23, and
prevent credentialed Maven execution from loading the PR-controlled
.mvn/settings.xml at lines 37-39 by using a trusted settings file when
credentials are required. In .github/workflows/test.yml lines 40-48, remove
packages: read from the untrusted PR scan or otherwise ensure no credentials
reach PR-controlled Maven execution.
Source: Linters/SAST tools
| margs=(-B -q -fn -DskipTests -gs /tmp/central-mirror.xml dependency:go-offline) | ||
| [ -f .mvn/settings.xml ] && margs+=(-s .mvn/settings.xml) | ||
| mvn "${margs[@]}" || echo "::warning::Maven dependency resolution incomplete; pom.xml scan depth may be reduced" |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== Locate action =="
fd -a 'action.yml' .github 2>/dev/null | sed 's#^\./##' || true
echo "== Inspect target snippet =="
cat -n .github/steps/trivy/action.yml | sed -n '1,120p'
echo "== Search fail-never usage =="
rg -n '\-fn|fail-never|go-offline|continueOnError|exitCode' .github -S || true
echo "== Relevant git diff stat =="
git diff --stat HEAD~..HEAD 2>/dev/null || true
git diff -- .github/steps/trivy/action.yml 2>/dev/null | sed -n '1,160p' || trueRepository: flamingo-stack/fleetmdm
Length of output: 5799
🌐 Web query:
Apache Maven Maven reactor skip failures mvn -fn fail at end behavior exit code dependency resolution fails
💡 Result:
When using the Maven reactor with the --fail-at-end (or -fae) flag, the build behavior and exit code are as follows: Behavior and Exit Code When a module build fails, the --fail-at-end option instructs Maven to continue building the remaining modules in the reactor that are not dependent on the failed project [1][2]. After attempting to build all independent modules, Maven will report all failures encountered during the process [1][2]. Because at least one failure occurred, the overall Maven process will exit with a non-zero exit code (indicating a build failure) once all possible modules have been processed [3][2]. Dependency Resolution Failures The --fail-at-end flag is intended to allow for continued execution after a build error, but it does not resolve or bypass fundamental dependency resolution issues [4][5]. 1. Reactor Ordering and Skipping: Maven constructs a dependency graph to determine the build order [6]. If a project in the reactor fails to build, any other projects that depend on that failed module will be automatically skipped, as their dependencies cannot be satisfied [3]. 2. Resolution Failures: If a module fails due to an inability to resolve a dependency (e.g., a missing artifact), the reactor will stop that module's build, skip any downstream dependents, and continue with other independent branches [1][5]. 3. Debugging vs. Fixing: Using --fail-at-end is primarily a diagnostic tool to identify all failures in a multi-module build at once, rather than stopping at the first error [5][7]. It will not fix incorrect dependency configurations, race conditions in concurrent builds, or missing artifacts in your repositories [4][8][9]. If you are consistently experiencing dependency resolution failures, these should be addressed by ensuring project dependencies are correctly defined, verifying that modules are correctly included in the reactor, or resolving configuration issues (such as incorrect version management or aggregator plugin misuse) rather than relying on --fail-at-end to bypass them [4][10][6].
Citations:
- 1: https://maven.apache.org/guides/mini/guide-multiple-modules.html
- 2: https://www.sonatype.com/maven-complete-reference/running-maven
- 3: https://maven.apache.org/core-its/core-it-suite/testapidocs/org/apache/maven/it/MavenITmng0095ReactorFailureBehaviorTest.html
- 4: https://stackoverflow.com/questions/40463737/how-fail-at-end-works-in-maven
- 5: Maven: mvn clean install --fail-at-end jwenjian/ghiblog#33
- 6: https://stackoverflow.com/questions/30631988/maven-reactor-builds-in-order-that-doesnt-satisfy-all-dependencies
- 7: https://www.mail-archive.com/users@maven.apache.org/msg144758.html
- 8: https://issues.apache.org/jira/browse/MNG-8096
- 9: [MNG-8096] Inconsistent dependency resolution behaviour for concurrent multi-module build can cause failures apache/maven#10778
- 10: https://stackoverflow.com/questions/55308956/maven-could-not-resolve-dependencies-from-reactor
🌐 Web query:
Apache Maven fail-never flag -fn dependency-missing resolver-plugin dependency resolution failure exit code
💡 Result:
The Apache Maven --fail-never flag (or -fn) is designed to instruct Maven to continue the build execution even if one or more projects in the reactor fail [1][2]. However, it does not bypass or ignore mandatory dependency resolution failures [3][4]. In Apache Maven, dependencies are considered core requirements for the build to proceed [4]. If a dependency cannot be resolved (e.g., artifact not found in repositories, connection failure, or invalid checksums), Maven considers the project unbuildable [3][4]. Even when --fail-never is enabled, Maven will attempt to resolve all required dependencies; if a critical dependency resolution fails, the build process for that specific project will halt because it cannot satisfy its classpath requirements [3]. Key points regarding this behavior include: 1. Mandatory Resolution: Maven's architecture requires that all declared dependencies be resolvable for a build to succeed [3][4]. There is no native flag or configuration option to "ignore" a missing dependency during the resolution phase [3]. 2. Scope of --fail-never: This flag affects the reactor's behavior when a project fails to build (e.g., compilation error, test failure). It allows subsequent, non-impacted projects in the reactor to continue building rather than aborting the entire process immediately [2]. It does not turn off dependency verification [3]. 3. Exit Code: When using --fail-never, Maven may still exit with a non-zero exit code depending on the severity of the failure and the Maven version, as the flag specifically manages reactor failure behavior rather than ensuring a "success" exit status for all possible failure types [5]. 4. Workarounds: If you must handle optional or environment-specific dependencies, the standard approach is to use Maven Profiles [3]. You can define a dependency within a profile that is only activated under specific conditions (e.g., presence of a file or property), preventing it from being required in environments where it is unavailable [3]. There is no specific "maven-resolver-plugin" flag that overrides this fundamental requirement, as dependency resolution is handled by the core Maven engine to ensure build reproducibility and integrity [4].
Citations:
- 1: https://maven.apache.org/ref/4.0.0-rc-3/apidocs/org/apache/maven/api/cli/mvn/MavenOptions.html
- 2: https://maven.apache.org/shared/maven-invoker/apidocs/org/apache/maven/shared/invoker/InvocationRequest.ReactorFailureBehavior.html
- 3: https://stackoverflow.com/questions/5126223/how-to-tell-maven-to-ignore-a-dependency-if-failed-to-resolve-it
- 4: https://maveniverse.eu/blog/2025/03/17/never-say-never/
- 5: https://jira.atlassian.com/browse/BAM-9108
Remove Maven fail-never mode.
-fn lets Maven exit successfully after reactor failures, so dependency-resolution failures can leave partial ~/.m2 metadata while the || echo warning path does not run. The action can then scan incomplete data and pass. Remove -fn so failed dependency:go-offline resolution is reported and the workflow can fail appropriately.
Proposed fix
- margs=(-B -q -fn -DskipTests -gs /tmp/central-mirror.xml dependency:go-offline)
+ margs=(-B -q -DskipTests -gs /tmp/central-mirror.xml dependency:go-offline)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| margs=(-B -q -fn -DskipTests -gs /tmp/central-mirror.xml dependency:go-offline) | |
| [ -f .mvn/settings.xml ] && margs+=(-s .mvn/settings.xml) | |
| mvn "${margs[@]}" || echo "::warning::Maven dependency resolution incomplete; pom.xml scan depth may be reduced" | |
| margs=(-B -q -DskipTests -gs /tmp/central-mirror.xml dependency:go-offline) | |
| [ -f .mvn/settings.xml ] && margs+=(-s .mvn/settings.xml) | |
| mvn "${margs[@]}" || echo "::warning::Maven dependency resolution incomplete; pom.xml scan depth may be reduced" |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/steps/trivy/action.yml around lines 37 - 39, Remove the -fn
fail-never flag from the margs array used by the Maven dependency:go-offline
invocation, while preserving the remaining Maven arguments and existing warning
handling.
| while IFS= read -r img; do | ||
| [ -z "$img" ] && continue | ||
| [ "$img" = "scratch" ] && continue | ||
| case "$img" in *'$'*) continue ;; esac | ||
| grep -qxF "$img" aliases.txt && continue | ||
| echo "Scanning base image ${img}" | ||
| if trivy image --scanners vuln --severity HIGH,CRITICAL --ignore-unfixed --format json -o img.json "$img"; then | ||
| jq --arg s "$img" '.Results = ((.Results // []) | map(. + {ScanSrc: ("image " + $s)}))' img.json > img2.json | ||
| jq -s '{Results: (.[0].Results + (.[1].Results // []))}' combined.json img2.json > tmp.json && mv tmp.json combined.json | ||
| else | ||
| echo "skip ${img}" | ||
| fi |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== files =="
fd -a 'action\.ya?ml|Dockerfile|entrypoint|workflows' . | sed 's#^\./##' | head -200
echo "== relevant action excerpt =="
if [ -f .github/steps/trivy/action.yml ]; then
nl -ba .github/steps/trivy/action.yml | sed -n '1,140p'
fi
echo "== search trivy steps/workflows =="
rg -n "trivy|Scanning base image|skip .*|combined\.json|imgs\.txt|aliases\.txt|scan" .github -S || trueRepository: flamingo-stack/fleetmdm
Length of output: 2864
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== repository tracked action =="
git ls-files .github/steps/trivy/action.yml || true
if [ -f .github/steps/trivy/action.yml ]; then
echo "== action excerpt =="
awk '{ printf "%6d\t%s\n", NR, $0 }' .github/steps/trivy/action.yml | sed -n '1,140p'
fi
echo "== workflow references to trivy action =="
rg -n "trivy-actions|steps/trivy|uses: .*trivy|image_scan_failed|skip .*|Scanning base image|combined\.json" .github -S || trueRepository: flamingo-stack/fleetmdm
Length of output: 6269
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== Bash conditional behavior probe =="
bash -c '
set -euo pipefail
image_scan_failed=0
skip_count=0
for img in a "$b" c "" scratch "scratch"; do
[ -z "$img" ] && continue
[ "$img" = "scratch" ] && continue
case "$img" in
*'"$"'* ) skip_count=$((skip_count+1)); continue ;;
esac
[ "$img" = "a" ] && continue
true
if false; then
printf "scan %s\n" "$img"
else
printf "skip %s\n" "$img"
skip_count=$((skip_count+1))
fi
done
printf "final_failed=%s skip_count=%s\n" "$image_scan_failed" "$skip_count"
[ "$image_scan_failed" -eq 0 ] || printf "action would fail\n"
'
echo "== workflow excerpt =="
git ls-files .github/workflows/test.yml && awk '{ printf "%6d\t%s\n", NR, $0 }' .github/workflows/test.yml | sed -n '1,90p'Repository: flamingo-stack/fleetmdm
Length of output: 233
🏁 Script executed:
#!/bin/bash
set +u
set -e
echo "== Bash conditional behavior probe =="
bash -c '
set -euo pipefail
image_scan_failed=0
skip_count=0
for img in a "$b" c "" scratch "scratch"; do
[ -z "$img" ] && continue
[ "$img" = "scratch" ] && continue
case "$img" in
*'"$"'* ) skip_count=$((skip_count+1)); continue ;;
esac
[ "$img" = "a" ] && continue
true
if false; then
printf "scan %s\n" "$img"
else
printf "skip %s\n" "$img"
skip_count=$((skip_count+1))
fi
done
printf "final_failed=%s skip_count=%s\n" "$image_scan_failed" "$skip_count"
[ "$image_scan_failed" -eq 0 ] || printf "action would fail\n"
' <<-'EOF'
:
EOF
b="not_an_image"
sh -euo pipefail <<'SH'
image_scan_failed=0
skip_count=0
for img in a "$b" c "" scratch "scratch"; do
[ -z "$img" ] && continue
[ "$img" = "scratch" ] && continue
case "$img" in *' '$'*' ) continue ;; esac
[ "$img" = "a" ] && continue
true
if false; then
printf "scan %s\n" "$img"
else
printf "skip %s\n" "$img"
skip_count=$((skip_count+1))
fi
done
printf "final_failed=%s skip_count=%s\n" "$image_scan_failed" "$skip_count"
[ "$image_scan_failed" -eq 0 ] || exit 1
SHRepository: flamingo-stack/fleetmdm
Length of output: 233
🏁 Script executed:
#!/bin/bash
set +u
echo "== Bash image filtering behavior probe =="
b="not_an_image"
bash -euo pipefail <<'SH'
image_scan_failed=0
skip_count=0
for img in a "$b" c "" scratch "scratch"; do
[ -z "$img" ] && continue
[ "$img" = "scratch" ] && continue
case "$img" in *' '$'*' ) continue ;; esac
[ "$img" = "a" ] && continue
if false; then
printf "scan %s\n" "$img"
else
printf "skip %s\n" "$img"
skip_count=$((skip_count+1))
fi
done
printf "without explicit failure tracking: final_failed=%s skip_count=%s\n" "$image_scan_failed" "$skip_count"
[ "$image_scan_failed" -eq 0 ] || printf "failed\n"
image_scan_failed=0
for img in a "$b" c "" scratch "scratch"; do
[ -z "$img" ] && continue
[ "$img" = "scratch" ] && continue
case "$img" in
*' '$'*' )
printf "unresolvable: %s\n" "$img"
image_scan_failed=1
continue
;;
esac
[ "$img" = "a" ] && continue
if false; then
printf "scan %s\n" "$img"
else
printf "skip %s\n" "$img"
image_scan_failed=1
fi
done
printf "with explicit failure tracking: failed=%s skip_count=%s\n" "$image_scan_failed" "$skip_count"
[ "$image_scan_failed" -eq 0 ] || printf "failed\n"
SHRepository: flamingo-stack/fleetmdm
Length of output: 237
🏁 Script executed:
#!/bin/bash
set +u
echo "== Bash image filtering behavior probe =="
b="not_an_image"
(
set -euo pipefail
image_scan_failed=0
for img in a "$b" c "" scratch "scratch"; do
[ -z "$img" ] && continue
[ "$img" = "scratch" ] && continue
case "$img" in *'$'*) continue ;; esac
[ "$img" = "a" ] && continue
if false; then
printf "scan %s\n" "$img"
else
printf "skip %s\n" "$img"
fi
done
printf "with current code variables unset/interpolated: final_failed=%s\n" "$image_scan_failed"
[ "$image_scan_failed" -eq 0 ] || exit 1
)
(
set -euo pipefail
image_scan_failed=0
for img in a "$b" c "" scratch "scratch"; do
[ -z "$img" ] && continue
[ "$img" = "scratch" ] && continue
case "$img" in
*'$'*)
printf "unresolvable: %s\n" "$img"
image_scan_failed=1
continue
;;
esac
[ "$img" = "a" ] && continue
if false; then
printf "scan %s\n" "$img"
else
printf "skip %s\n" "$img"
image_scan_failed=1
fi
done
[ "$image_scan_failed" -eq 0 ] || exit 1
printf "final_ok\n"
)Repository: flamingo-stack/fleetmdm
Length of output: 316
Fail when a Dockerfile base image is skipped.
The image loop silently skips unresolved $VAR refs and nonzero trivy image results. Track these skips and exit nonzero after processing imgs.txt, or the required trivy job can pass even with unscanned base images.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/steps/trivy/action.yml around lines 56 - 67, Update the
image-processing loop around the img variable to track unresolved “$VAR”
references and failed trivy image scans as skipped images, while continuing to
process the remaining entries. After the imgs.txt loop completes, exit nonzero
when any image was skipped; retain successful scanning and alias/scratch
filtering behavior.
…s for skipped scans
Adds a Trivy-based PR security gate:
Summary by CodeRabbit
New Features
Documentation