Skip to content
Open
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
29 changes: 7 additions & 22 deletions .github/workflows/fossa-oss-pr-scan.yaml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
---
# yamllint disable rule:line-length
name: Fossa-oss PR scan (jenkins)
name: Fossa OSS PR scan

on:
pull_request:
concurrency:
group: ${{ github.event.repository.name }}-fossa-scanning-oss-zuul-${{ github.event.pull_request.number }}
group: ${{ github.event.repository.name }}-fossa-scanning-oss-${{ github.event.pull_request.number }}
cancel-in-progress: true
jobs:
fossa:
fossa-native:
runs-on:
group: infra1-runners-arc
labels: runners-small
Expand All @@ -17,23 +17,8 @@ jobs:
id-token: write
pull-requests: write
steps:
- name: Call Jenkins trigger
id: call-jenkins
uses: gooddata/github-actions-public/jenkins/trigger@master
- uses: gooddata/github-actions-public/fossa/pr-scan@master
with:
server: ${{ secrets.JENKINS_ADDRESS }}
folder: compliance
job-name: "${{ github.event.repository.name }}-fossa-scanning-oss-zuul"
vault-url: ${{ secrets.VAULT_ADDRESS }}
params: |-
{
"GH_BRANCH":"${{ github.base_ref }}",
"GH_REF":"${{ github.ref }}",
"GH_COMMIT":"${{ github.event.pull_request.head.sha }}",
"GH_URL":"git@github.com:",
"GH_CHANGE":"${{ github.event.pull_request.number }}",
"GH_PROJECT":"${{ github.repository }}",
"GH_PR_NUMBER":"${{ github.event.pull_request.number }}",
"BUILD_BY_GITHUB":"true",
"GH_PIPELINE":"gate"
}
fossa-api-key: ${{ secrets.FOSSA_API_KEY }}
npm-auth-token: ${{ secrets.NPM_TOKEN }}
github-token: ${{ secrets.TOKEN_GITHUB_YENKINS }}
Comment on lines +20 to +24

@coderabbitai coderabbitai Bot Jun 26, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if the fossa/pr-scan directory exists
fd -t d "fossa" --max-depth 2
# Check the full workflow file for existing checkout steps
cat -n .github/workflows/fossa-oss-pr-scan.yaml

Repository: gooddata/github-actions-public

Length of output: 1010


Use the local in-repo action instead of @master and correct the checkout version.

uses: {owner}/{repo}/{path}@{ref} fetches the action from the remote reference, bypassing the new fossa/pr-scan files added in this PR. Since this PR introduces the local action, the workflow must check out the PR branch and run the local action to validate the changes. Additionally, actions/checkout@v7 does not exist; use the stable actions/checkout@v4.

Suggested change
     steps:
+      - uses: actions/checkout@v4
       - uses: gooddata/github-actions-public/fossa/pr-scan@master
+        with:
+          fossa-api-key: ${{ secrets.FOSSA_API_KEY }}
+          npm-auth-token: ${{ secrets.NPM_TOKEN }}
+          github-token: ${{ secrets.TOKEN_GITHUB_YENKINS }}

Replace the remote uses with the local path:

-      uses: gooddata/github-actions-public/fossa/pr-scan@master
+      uses: ./fossa/pr-scan
📝 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.

Suggested change
- uses: gooddata/github-actions-public/fossa/pr-scan@master
with:
server: ${{ secrets.JENKINS_ADDRESS }}
folder: compliance
job-name: "${{ github.event.repository.name }}-fossa-scanning-oss-zuul"
vault-url: ${{ secrets.VAULT_ADDRESS }}
params: |-
{
"GH_BRANCH":"${{ github.base_ref }}",
"GH_REF":"${{ github.ref }}",
"GH_COMMIT":"${{ github.event.pull_request.head.sha }}",
"GH_URL":"git@github.com:",
"GH_CHANGE":"${{ github.event.pull_request.number }}",
"GH_PROJECT":"${{ github.repository }}",
"GH_PR_NUMBER":"${{ github.event.pull_request.number }}",
"BUILD_BY_GITHUB":"true",
"GH_PIPELINE":"gate"
}
fossa-api-key: ${{ secrets.FOSSA_API_KEY }}
npm-auth-token: ${{ secrets.NPM_TOKEN }}
github-token: ${{ secrets.TOKEN_GITHUB_YENKINS }}
- uses: actions/checkout@v4
- uses: ./fossa/pr-scan
with:
fossa-api-key: ${{ secrets.FOSSA_API_KEY }}
npm-auth-token: ${{ secrets.NPM_TOKEN }}
github-token: ${{ secrets.TOKEN_GITHUB_YENKINS }}
🧰 Tools
🪛 zizmor (1.26.1)

[error] 20-20: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 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/workflows/fossa-oss-pr-scan.yaml around lines 20 - 24, The workflow
is still invoking the remote fossa/pr-scan action via the
gooddata/github-actions-public reference, so it won’t validate the local action
files introduced in this PR. Update the fossa-oss-pr-scan workflow to use the
in-repo fossa/pr-scan action after checking out the PR branch, and change the
checkout step from the nonexistent actions/checkout@v7 to the stable
actions/checkout@v4. Use the existing workflow job and fossa/pr-scan action
reference to locate the change.

Source: Linters/SAST tools

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actions/checkout@v7 actually exists https://github.com/actions/checkout/releases/tag/v7.0.0

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@petr-klemsinsky You're right — actions/checkout@v7 does exist now. That part of my comment was incorrect; thanks for the correction.

The remaining concern is just the action reference itself: uses: gooddata/github-actions-public/fossa/pr-scan@master will still resolve the remote action, so it won't exercise the new in-repo fossa/pr-scan files added by this PR. If the goal is to validate the action introduced here, it should use the local path instead.

(・×・)


✏️ Learnings added
Learnt from: petr-klemsinsky
Repo: gooddata/github-actions-public PR: 29
File: .github/workflows/fossa-oss-pr-scan.yaml:20-24
Timestamp: 2026-06-29T06:52:10.706Z
Learning: `actions/checkoutv7` exists (released publicly), so future reviews should not flag `actions/checkoutv7` as a nonexistent action version.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

41 changes: 41 additions & 0 deletions fossa/pr-scan/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
name: "FOSSA PR scan"
description: "Run a native FOSSA analyze+test scan for a PR, reusing the gdc-fossa-cli container (no Jenkins)."
inputs:
branch:
description: "Branch reported to FOSSA for the analyze upload"
required: false
default: ${{ github.head_ref }}
scan-image:
description: "Default FOSSA scan container image (per-repo gdc_fossa.yaml scan_image overrides this)"
required: false
default: "020413372491.dkr.ecr.us-east-1.amazonaws.com/tools/gdc-fossa-cli:latest"
fossa-api-key:
description: "FOSSA API key (org GitHub secret FOSSA_API_KEY)"
required: true
npm-auth-token:
description: "NPM read token for private dependency resolution (org GitHub secret NPM_TOKEN)"
required: false
default: ""
github-token:
description: "GitHub PAT for private-repo dependency resolution (org GitHub secret TOKEN_GITHUB_YENKINS)"
required: false
default: ""
runs:
using: "composite"
steps:
- name: Checkout the PR
uses: actions/checkout@v7
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
- name: Run FOSSA scan
shell: bash
env:
FOSSA_API_KEY: ${{ inputs.fossa-api-key }}
NPM_AUTH_TOKEN: ${{ inputs.npm-auth-token }}
GITHUB_PULL_TOKEN: ${{ inputs.github-token }}
SCAN_IMAGE_DEFAULT: ${{ inputs.scan-image }}
FOSSA_BRANCH: ${{ inputs.branch }}
REPO_NAME: ${{ github.event.repository.name }}
run: bash ${{ github.action_path }}/scan.sh
103 changes: 103 additions & 0 deletions fossa/pr-scan/scan.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#!/usr/bin/env bash
# Native port of `cish fossa-scanning` scan loop. Reproduces the Jenkins
# docker-run invocation of fossa_scanning_tool inside the gdc-fossa-cli image.
#
# Auth uses org GitHub Actions secrets (no Vault): NPM_AUTH_TOKEN for npm, and a
# GitHub PAT (GITHUB_PULL_TOKEN) wired through a git insteadOf rewrite so the
# in-container dependency resolution can fetch private gooddata repos over HTTPS
# (replaces the Jenkins SSH-agent approach).
set -euo pipefail

: "${FOSSA_API_KEY:?FOSSA_API_KEY is required}"
: "${REPO_NAME:?REPO_NAME is required}"
NPM_AUTH_TOKEN="${NPM_AUTH_TOKEN:-}"
GITHUB_PULL_TOKEN="${GITHUB_PULL_TOKEN:-}"
SCAN_IMAGE_DEFAULT="${SCAN_IMAGE_DEFAULT:?SCAN_IMAGE_DEFAULT is required}"
FOSSA_BRANCH="${FOSSA_BRANCH:-}"

src_dir="${GITHUB_WORKSPACE:-$PWD}"
work_dir="${RUNNER_TEMP:-$PWD}/fossa-pr-scan"
mkdir -p "${PWD}/build-output" "${work_dir}"

# --- npm auth (mounted into the container as ~/.npmrc) ---
# Jenkins used the public registry with an auth token; npm interpolates the
# NPM_AUTH_TOKEN env var (also passed into the container) at runtime.
npmrc="${work_dir}/npmrc"
if [ -n "${NPM_AUTH_TOKEN}" ]; then
printf '//registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN}\n' > "${npmrc}"
else
: > "${npmrc}"
fi

# --- git auth for private gooddata deps (mounted into the container) ---
# Rewrite ssh/https gooddata URLs to token-authenticated HTTPS so go/npm/maven
# can resolve private dependencies in-container. The token is embedded in a
# throwaway gitconfig on the ephemeral runner.
gitconfig="${work_dir}/gitconfig"
: > "${gitconfig}"
if [ -n "${GITHUB_PULL_TOKEN}" ]; then
cat > "${gitconfig}" <<EOF
[url "https://oauth2:${GITHUB_PULL_TOKEN}@github.com/gooddata/"]
insteadOf = ssh://git@github.com/gooddata/
insteadOf = git@github.com:gooddata/
insteadOf = https://github.com/gooddata/
EOF
fi

# --- m2 settings (optional; only mounted if present) ---
m2_settings="${HOME}/.m2/settings.xml"

docker_pull() { docker pull "$1" >/dev/null; }

run_scan() {
local scan_img="$1" gdc_conf="$2"
local java_version="" conf_arg=()
local mount_args=()

if [ -n "${gdc_conf}" ] && [ -f "${gdc_conf}" ]; then
local img_override
img_override="$(yq -r '.scan_image | select(. != null)' "${gdc_conf}")"
[ -n "${img_override}" ] && scan_img="${img_override}"
java_version="$(yq -r '.java_version | select(. != null)' "${gdc_conf}")"
conf_arg=(--gdc-conf "$(basename "${gdc_conf}")")
fi
Comment on lines +57 to +63

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Preserve the config path relative to the repo root.

The loop deliberately finds gdc_fossa*.yaml anywhere under src_dir, but conf_arg drops each match to basename(...). Any config in a subdirectory—or two configs sharing the same filename—will be passed to fossa_scanning_tool with the wrong path or collide on the same name, so the wrong module gets scanned.

Suggested change
 run_scan() {
   local scan_img="$1" gdc_conf="$2"
   local java_version="" conf_arg=()
   local mount_args=()
 
   if [ -n "${gdc_conf}" ] && [ -f "${gdc_conf}" ]; then
+    local rel_conf="${gdc_conf#${src_dir}/}"
     local img_override
     img_override="$(yq -r '.scan_image | select(. != null)' "${gdc_conf}")"
     [ -n "${img_override}" ] && scan_img="${img_override}"
     java_version="$(yq -r '.java_version | select(. != null)' "${gdc_conf}")"
-    conf_arg=(--gdc-conf "$(basename "${gdc_conf}")")
+    conf_arg=(--gdc-conf "${rel_conf}")
   fi

Also applies to: 88-95

🤖 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 `@fossa/pr-scan/scan.sh` around lines 57 - 63, The config handling in scan.sh
is stripping gdc_conf down to basename, which loses the path discovered under
src_dir and can collide across duplicate filenames. Update the gdc_conf handling
in the config-loading block and the later fossa_scanning_tool invocation to
preserve the path relative to the repo root instead of basename, using the
existing gdc_conf variable so each matched gdc_fossa*.yaml maps to the correct
module.


docker_pull "${scan_img}"

mount_args=(
-v "${npmrc}:/home/fossa/.npmrc"
-v "${gitconfig}:/home/fossa/.gitconfig"
-v "${src_dir}:/home/fossa/sources/${REPO_NAME}"
-v "${PWD}/build-output:/home/fossa/build-output"
)
if [ -f "${m2_settings}" ]; then
mount_args+=(-v "${m2_settings}:/home/fossa/.m2/settings.xml")
fi

docker run --rm \
"${mount_args[@]}" \
-e USER_UID="$(id -u)" \
-e FOSSA_API_KEY -e NPM_AUTH_TOKEN \
-e JAVA_VERSION="${java_version}" \
"${scan_img}" \
fossa_scanning_tool -r "${REPO_NAME}" -o "not_found" -v -c analyze test \
${FOSSA_BRANCH:+-b "${FOSSA_BRANCH}"} \
"${conf_arg[@]}"
}

# --- find gdc_fossa*.yaml configs; loop, or single scan if none ---
mapfile -t confs < <(find "${src_dir}" -type f -name "gdc_fossa*.yaml" | sort)
if [ "${#confs[@]}" -eq 0 ]; then
run_scan "${SCAN_IMAGE_DEFAULT}" ""
else
for conf in "${confs[@]}"; do
run_scan "${SCAN_IMAGE_DEFAULT}" "${conf}"
done
fi

# fossa_scanning_tool writes build-output/analyze_failed.txt on analyze failure
if [ -f "./build-output/analyze_failed.txt" ]; then
echo "ERROR: FOSSA analyze failed for some module(s); see logs above."
exit 1
fi
echo "FOSSA scan completed."
Loading