Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
fc27fb9
added bom generation scripts
idelcano Mar 9, 2026
3d99e94
added bom generation actions from other repo
idelcano Mar 9, 2026
09236a5
change runner from self-hosted to basic-runner
idelcano Mar 9, 2026
51334d9
Added bom workflows into master
idelcano Mar 9, 2026
ff4ae1d
add dedicated runners for shared workflows and BOM jobs
idelcano Mar 9, 2026
fc3acc8
load shared BOM scripts from central workflows repo
idelcano Mar 9, 2026
77bf445
execute only on PR
idelcano Mar 9, 2026
bd73c17
refactor names
idelcano Mar 10, 2026
7695d3a
change tag name
idelcano Mar 11, 2026
7510d1c
fix job names
idelcano Mar 11, 2026
a45c700
fix runner name in workflow call
idelcano Mar 11, 2026
52a0819
Separate workflows
idelcano Mar 11, 2026
086b2f8
fix tag
idelcano Mar 13, 2026
76ce22c
changed syft latest by 1.42.2 version
idelcano Mar 13, 2026
429e40e
force version
idelcano Mar 13, 2026
af46572
remove workflow_dispatch in master, this should be config in child repo
idelcano Mar 13, 2026
543cb1b
Merge branch 'master' into feature/add_bom_actions
idelcano Mar 18, 2026
23907ca
extract logic to external script
idelcano Mar 18, 2026
076c53b
block report
idelcano Mar 18, 2026
7a26d2b
added todo to future tests
idelcano Mar 18, 2026
363a32a
Update reference for shared workflows repository for test
idelcano Apr 9, 2026
1d6bc5c
update yarn4 for testing proposes
idelcano Apr 9, 2026
0cdbb3a
clean execution at the end of the workflow action inside vm
idelcano Apr 9, 2026
87809b3
replace self-hosted and ubuntu-latest by the new tag general-runner
idelcano Apr 9, 2026
f9e2864
better isolation in podman executions and remove directory after fini…
idelcano Apr 9, 2026
0626d69
test remove only shared workflows and node modules
idelcano Apr 9, 2026
431ecc4
Clean podman before start job and use internal network instead of new…
idelcano Apr 23, 2026
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
2 changes: 1 addition & 1 deletion .github/workflows/app-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
runner:
description: "Specify runner. Defaults to checking visibility"
required: false
default: "ubuntu-latest"
default: "general-runner"
type: string

jobs:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/bundlemon-build-size.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ on:
runner:
description: "Specify runner. Defaults to checking visibility"
required: false
default: "ubuntu-latest"
default: "general-runner"
type: string

jobs:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ on:
runner:
description: "Specify runner. Defaults to checking visibility"
required: false
default: "ubuntu-latest"
default: "general-runner"
type: string

jobs:
Expand Down
240 changes: 240 additions & 0 deletions .github/workflows/dependency-track-syft.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
name: Dependency-Track Syft Scan

on:
workflow_call:
inputs:
runner:
description: "Specify runner for the BOM workflow"
required: false
default: "dependency-track-runner"
type: string
secrets:
DTRACK_API_KEY:
required: true
workflow_dispatch:

concurrency:
group: dtrack-${{ github.workflow }}-syft-${{ github.ref }}
cancel-in-progress: true

jobs:
dependency-track-syft:
runs-on: ${{ inputs.runner }}
permissions:
contents: read
actions: read
security-events: write
steps:
- name: Resolve code scanning target (ref/sha)
id: code_scanning_target
run: |
set -euo pipefail
ref="${GITHUB_REF}"
sha="${GITHUB_SHA}"

pr_head_ref="$(jq -r '.pull_request.head.ref // empty' "$GITHUB_EVENT_PATH")"
pr_head_sha="$(jq -r '.pull_request.head.sha // empty' "$GITHUB_EVENT_PATH")"

if [ -n "$pr_head_ref" ] && [ -n "$pr_head_sha" ]; then
ref="refs/heads/$pr_head_ref"
sha="$pr_head_sha"
fi

echo "code_scanning_ref=$ref" >> "$GITHUB_OUTPUT"
echo "code_scanning_sha=$sha" >> "$GITHUB_OUTPUT"
echo "Resolved code scanning target: ref=$ref sha=$sha"

- name: Checkout caller repository
uses: actions/checkout@v4
with:
ref: ${{ steps.code_scanning_target.outputs.code_scanning_sha }}

- name: Checkout shared workflows repository
uses: actions/checkout@v4
with:
repository: EyeSeeTea/github-workflows
ref: feature/add_bom_actions
path: shared-workflows

- name: Read node version (fallback 20)
run: |
if [ -f .nvmrc ]; then
echo "NODE_VERSION=$(tr -d 'v' < .nvmrc)" >> "$GITHUB_ENV"
else
echo "NODE_VERSION=20" >> "$GITHUB_ENV"
fi

- name: Podman pre-flight cleanup
run: |
podman system migrate
podman container prune -f

- name: Yarn install + SBOM (container)
run: |
podman run --rm \
--network=host \
-v "$GITHUB_WORKSPACE:/work" -w /work \
-v /work/node_modules \
node:${NODE_VERSION}-bullseye \
bash -lc '
set -e
corepack enable
yarn install
Comment thread
tokland marked this conversation as resolved.

# Install syft in the container
curl -sSfL https://raw.githubusercontent.com/anchore/syft/v1.42.2/install.sh \
| sh -s -- -b /usr/local/bin v1.42.2

# Generate CycloneDX JSON SBOM
syft . -o cyclonedx-json=bom_syft.json
'

- name: Upload BOM, analyze, and fetch metrics
id: dtrack_syft
env:
DTRACK_URL: ${{ vars.DTRACK_URL }}
DTRACK_API_KEY: ${{ secrets.DTRACK_API_KEY }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
set -euo pipefail
bash shared-workflows/scripts/upload_bom_and_fetch_metrics.sh \
--bom-file bom_syft.json \
--project-suffix syft

- name: Export SARIF findings (syft)
env:
DTRACK_URL: ${{ vars.DTRACK_URL }}
DTRACK_API_KEY: ${{ secrets.DTRACK_API_KEY }}
PROJECT_UUID: ${{ steps.dtrack_syft.outputs.project_uuid }}
run: |
set -euo pipefail

curl -sSf "$DTRACK_URL/api/v1/finding/project/$PROJECT_UUID?suppressed=false" \
-H "X-Api-Key: $DTRACK_API_KEY" \
-H "Accept: application/sarif+json" \
-o dtrack-syft.sarif

test -s dtrack-syft.sarif || { echo "::error::dtrack-syft.sarif is missing or empty"; exit 1; }
jq -e '.runs and (.runs | type == "array")' dtrack-syft.sarif >/dev/null

- name: Export VEX and VDR JSON for SARIF mapping (syft)
env:
DTRACK_URL: ${{ vars.DTRACK_URL }}
DTRACK_API_KEY: ${{ secrets.DTRACK_API_KEY }}
PROJECT_UUID: ${{ steps.dtrack_syft.outputs.project_uuid }}
run: |
set -euo pipefail

curl -sSf "$DTRACK_URL/api/v1/vex/cyclonedx/project/$PROJECT_UUID" \
-H "X-Api-Key: $DTRACK_API_KEY" \
-o vex_syft.json

curl -sSf "$DTRACK_URL/api/v1/bom/cyclonedx/project/$PROJECT_UUID?variant=vdr&format=JSON" \
-H "X-Api-Key: $DTRACK_API_KEY" \
-o vdr_syft.json

test -s vex_syft.json || { echo "::error::vex_syft.json is missing or empty"; exit 1; }
test -s vdr_syft.json || { echo "::error::vdr_syft.json is missing or empty"; exit 1; }

- name: Normalize SARIF for GitHub Code Scanning (syft)
run: |
set -euo pipefail

python3 shared-workflows/scripts/normalize_sarif.py \
--input-sarif dtrack-syft.sarif \
--output-sarif dtrack-syft.sarif \
--vdr vdr_syft.json \
--vex vex_syft.json \
--source syft \
--tool-name "OWASP Dependency-Track (syft)" \
--rule-id-namespace "syft::" \
--location-mode fallback \
--fallback-uri bom.json \
Comment thread
tokland marked this conversation as resolved.
--fallback-line 1

jq -e '.runs[0].results[0].locations[0].physicalLocation.artifactLocation.uri' dtrack-syft.sarif >/dev/null

- name: Upload SARIF to GitHub Code Scanning (syft)
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: dtrack-syft.sarif
category: dependency-track-syft
ref: ${{ steps.code_scanning_target.outputs.code_scanning_ref }}
sha: ${{ steps.code_scanning_target.outputs.code_scanning_sha }}

- name: Compare with GitHub open alert instances (syft)
id: open_alerts_syft
env:
GH_TOKEN: ${{ github.token }}
TOOL_NAME: OWASP Dependency-Track (syft)
BASE_REF: ${{ github.base_ref }}
HEAD_REF_NAME: ${{ github.head_ref }}
run: |
set -euo pipefail
bash shared-workflows/scripts/report_open_code_scanning_alert_instances.sh \
--repo "$GITHUB_REPOSITORY" \
--tool-name "$TOOL_NAME" \
--head-ref "refs/heads/${HEAD_REF_NAME:-${GITHUB_REF_NAME}}" \
--base-ref "refs/heads/${BASE_REF:-${GITHUB_REF_NAME}}" \
--output-prefix "syft_open_alerts"

- name: Report code scanning summary (syft)
env:
OPEN_ALERTS_OUTPUTS_JSON: ${{ toJson(steps.open_alerts_syft.outputs) }}
run: |
set -euo pipefail
bash shared-workflows/scripts/report_code_scanning_summary.sh \
--sarif-file dtrack-syft.sarif \
--tool-name "OWASP Dependency-Track (syft)" \
--summary-title "Dependency-Track Syft code scanning" \
--output-prefix syft_open_alerts

- name: Enforce newly introduced vulnerability gate (critical/high)
run: |
set -euo pipefail

crit="${{ steps.open_alerts_syft.outputs.syft_open_alerts_introduced_instances_critical_count }}"
high="${{ steps.open_alerts_syft.outputs.syft_open_alerts_introduced_instances_high_count }}"
med="${{ steps.open_alerts_syft.outputs.syft_open_alerts_introduced_instances_medium_count }}"
low="${{ steps.open_alerts_syft.outputs.syft_open_alerts_introduced_instances_low_count }}"
branch_name="${GITHUB_HEAD_REF:-$GITHUB_REF_NAME}"
query="is:open branch:${branch_name} tool:\"OWASP Dependency-Track (syft)\""
branch_url="https://github.com/${GITHUB_REPOSITORY}/security/code-scanning?query=$(jq -rn --arg value "$query" '$value|@uri')"

crit="${crit:-0}"
high="${high:-0}"
med="${med:-0}"
low="${low:-0}"

echo "New alert instances detected vs base (head - base): critical=$crit high=$high medium=$med low=$low"

if [ "$crit" -gt 0 ] || [ "$high" -gt 0 ]; then
echo "::error::New critical/high alert instances detected vs base (critical=$crit, high=$high, medium=$med, low=$low). Review: $branch_url"
exit 1
fi

echo "No new critical/high alert instances detected vs base"

- name: Runner cleanup (always)
if: ${{ always() }}
run: |
set +e

# Remove generated files from workspace to keep self-hosted runners clean.
rm -f \
bom_syft.json \
vdr_syft.json \
vex_syft.json \
dtrack-syft.sarif \
syft_open_alerts_report.md \
syft_open_alerts_counts.tsv \
syft_open_alerts_details.tsv

# Best-effort podman cleanup for containers/images created during SBOM generation.
podman container prune -f >/dev/null 2>&1 || true
podman image prune -f >/dev/null 2>&1 || true
podman volume prune -f >/dev/null 2>&1 || true

# Clean specific directories that accumulate between runs (dependency tree, caches), but preserve workspace structure for post-job cleanup.
rm -rf "$GITHUB_WORKSPACE/node_modules" \
"$GITHUB_WORKSPACE/shared-workflows"
Loading