From 3db33249cfde909cc47159a6d52662a67572dfb8 Mon Sep 17 00:00:00 2001 From: Viktor Petersson Date: Sun, 8 Mar 2026 15:11:49 +0000 Subject: [PATCH 1/2] Add local SBOM pipeline runner and disable automatic workflow triggers Switch from GitHub Actions-driven execution to local run.sh script that handles the full SBOM pipeline (fetch, augment, dedup, upload, cleanup). All per-app and scheduled workflow triggers are disabled (kept as workflow_dispatch only) while the pipeline stabilizes. Lint workflow remains active. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/_sbom-template.yml | 13 +- .github/workflows/ci.yml | 10 +- .github/workflows/sbom-alpine.yml | 7 - .github/workflows/sbom-amazonlinux.yml | 7 - .github/workflows/sbom-bash.yml | 7 - .github/workflows/sbom-caddy.yml | 7 - .github/workflows/sbom-cassandra.yml | 7 - .github/workflows/sbom-debian.yml | 7 - .../sbom-dependency-track-frontend.yml | 7 - .github/workflows/sbom-dependency-track.yml | 7 - .github/workflows/sbom-drupal.yml | 7 - .github/workflows/sbom-eclipse-mosquitto.yml | 7 - .github/workflows/sbom-eclipse-temurin.yml | 7 - .github/workflows/sbom-elixir.yml | 7 - .github/workflows/sbom-erlang.yml | 7 - .github/workflows/sbom-fedora.yml | 7 - .github/workflows/sbom-ghost.yml | 7 - .github/workflows/sbom-golang.yml | 7 - .github/workflows/sbom-gradle.yml | 7 - .github/workflows/sbom-haproxy.yml | 7 - .github/workflows/sbom-haskell.yml | 7 - .github/workflows/sbom-httpd.yml | 7 - .github/workflows/sbom-influxdb.yml | 7 - .github/workflows/sbom-julia.yml | 7 - .github/workflows/sbom-keycloak-js.yml | 7 - .github/workflows/sbom-keycloak.yml | 8 - .github/workflows/sbom-kong.yml | 7 - .github/workflows/sbom-mariadb.yml | 7 - .github/workflows/sbom-maven.yml | 7 - .github/workflows/sbom-memcached.yml | 7 - .github/workflows/sbom-mongo-express.yml | 7 - .github/workflows/sbom-mongo.yml | 7 - .github/workflows/sbom-mysql.yml | 7 - .github/workflows/sbom-neo4j.yml | 7 - .github/workflows/sbom-nginx.yml | 7 - .github/workflows/sbom-node.yml | 7 - .github/workflows/sbom-oraclelinux.yml | 7 - .github/workflows/sbom-osv-scanner.yml | 8 - .github/workflows/sbom-perl.yml | 7 - .github/workflows/sbom-php.yml | 7 - .github/workflows/sbom-postgres.yml | 7 - .github/workflows/sbom-python.yml | 7 - .github/workflows/sbom-r-base.yml | 7 - .github/workflows/sbom-rabbitmq.yml | 7 - .github/workflows/sbom-redis.yml | 7 - .github/workflows/sbom-registry.yml | 7 - .github/workflows/sbom-rockylinux.yml | 7 - .github/workflows/sbom-ruby.yml | 7 - .github/workflows/sbom-rust.yml | 7 - .github/workflows/sbom-solr.yml | 7 - .github/workflows/sbom-sonarqube.yml | 7 - .github/workflows/sbom-swift.yml | 7 - .github/workflows/sbom-syft.yml | 7 - .github/workflows/sbom-telegraf.yml | 7 - .github/workflows/sbom-tomcat.yml | 7 - .github/workflows/sbom-traefik.yml | 7 - .github/workflows/sbom-trivy.yml | 7 - .github/workflows/sbom-ubuntu.yml | 7 - .github/workflows/sbom-wordpress.yml | 7 - .github/workflows/sbom-zookeeper.yml | 7 - .github/workflows/tea-sync.yml | 2 - CLAUDE.md | 17 +- scripts/run.sh | 508 ++++++++++++++++++ 63 files changed, 523 insertions(+), 435 deletions(-) create mode 100755 scripts/run.sh diff --git a/.github/workflows/_sbom-template.yml b/.github/workflows/_sbom-template.yml index 973e3dc..b6836e2 100644 --- a/.github/workflows/_sbom-template.yml +++ b/.github/workflows/_sbom-template.yml @@ -5,21 +5,12 @@ # 2. Replace all occurrences of 'example-app' with your app name # 3. Commit and push # -# The workflow will trigger when: -# - The config.yaml is modified (including version bumps) -# - The workflow file itself is modified +# The workflow will trigger on manual dispatch only. +# Automatic triggers are disabled while using local run.sh. name: "SBOM: example-app" on: - push: - branches: - - master - paths: - - 'apps/example-app/config.yaml' - - '.github/workflows/sbom-example-app.yml' - - # Allow manual triggering workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 042eb1d..55f4c8c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,15 +6,7 @@ name: CI on: - schedule: - - cron: '0 6 * * *' # Daily at 6:00 AM UTC - - pull_request: - paths: - - 'apps/**' - - 'scripts/**' - - '.github/workflows/sbom-builder.yml' - - '.github/workflows/ci.yml' + workflow_dispatch: {} jobs: # Find which apps have changed diff --git a/.github/workflows/sbom-alpine.yml b/.github/workflows/sbom-alpine.yml index 2a3f997..b9951d7 100644 --- a/.github/workflows/sbom-alpine.yml +++ b/.github/workflows/sbom-alpine.yml @@ -9,13 +9,6 @@ name: "SBOM: alpine" on: - push: - branches: - - master - paths: - - 'apps/alpine/config.yaml' - - '.github/workflows/sbom-alpine.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-amazonlinux.yml b/.github/workflows/sbom-amazonlinux.yml index 4881391..0c16a6c 100644 --- a/.github/workflows/sbom-amazonlinux.yml +++ b/.github/workflows/sbom-amazonlinux.yml @@ -9,13 +9,6 @@ name: "SBOM: amazonlinux" on: - push: - branches: - - master - paths: - - 'apps/amazonlinux/config.yaml' - - '.github/workflows/sbom-amazonlinux.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-bash.yml b/.github/workflows/sbom-bash.yml index fc560d3..06eafe1 100644 --- a/.github/workflows/sbom-bash.yml +++ b/.github/workflows/sbom-bash.yml @@ -9,13 +9,6 @@ name: "SBOM: bash" on: - push: - branches: - - master - paths: - - 'apps/bash/config.yaml' - - '.github/workflows/sbom-bash.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-caddy.yml b/.github/workflows/sbom-caddy.yml index 0472523..0ee12aa 100644 --- a/.github/workflows/sbom-caddy.yml +++ b/.github/workflows/sbom-caddy.yml @@ -8,13 +8,6 @@ name: "SBOM: caddy" on: - push: - branches: - - master - paths: - - 'apps/caddy/config.yaml' - - '.github/workflows/sbom-caddy.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-cassandra.yml b/.github/workflows/sbom-cassandra.yml index 3884e4d..f154282 100644 --- a/.github/workflows/sbom-cassandra.yml +++ b/.github/workflows/sbom-cassandra.yml @@ -9,13 +9,6 @@ name: "SBOM: cassandra" on: - push: - branches: - - master - paths: - - 'apps/cassandra/config.yaml' - - '.github/workflows/sbom-cassandra.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-debian.yml b/.github/workflows/sbom-debian.yml index 372d5fc..bd68940 100644 --- a/.github/workflows/sbom-debian.yml +++ b/.github/workflows/sbom-debian.yml @@ -9,13 +9,6 @@ name: "SBOM: debian" on: - push: - branches: - - master - paths: - - 'apps/debian/config.yaml' - - '.github/workflows/sbom-debian.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-dependency-track-frontend.yml b/.github/workflows/sbom-dependency-track-frontend.yml index 14c306f..ebb8d8e 100644 --- a/.github/workflows/sbom-dependency-track-frontend.yml +++ b/.github/workflows/sbom-dependency-track-frontend.yml @@ -8,13 +8,6 @@ name: "SBOM: dependency-track-frontend" on: - push: - branches: - - master - paths: - - 'apps/dependency-track-frontend/config.yaml' - - '.github/workflows/sbom-dependency-track-frontend.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-dependency-track.yml b/.github/workflows/sbom-dependency-track.yml index 48d2837..a8d7da5 100644 --- a/.github/workflows/sbom-dependency-track.yml +++ b/.github/workflows/sbom-dependency-track.yml @@ -8,13 +8,6 @@ name: "SBOM: dependency-track" on: - push: - branches: - - master - paths: - - 'apps/dependency-track/config.yaml' - - '.github/workflows/sbom-dependency-track.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-drupal.yml b/.github/workflows/sbom-drupal.yml index 17e5af1..eb12108 100644 --- a/.github/workflows/sbom-drupal.yml +++ b/.github/workflows/sbom-drupal.yml @@ -9,13 +9,6 @@ name: "SBOM: drupal" on: - push: - branches: - - master - paths: - - 'apps/drupal/config.yaml' - - '.github/workflows/sbom-drupal.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-eclipse-mosquitto.yml b/.github/workflows/sbom-eclipse-mosquitto.yml index 92409cd..c5e841a 100644 --- a/.github/workflows/sbom-eclipse-mosquitto.yml +++ b/.github/workflows/sbom-eclipse-mosquitto.yml @@ -9,13 +9,6 @@ name: "SBOM: eclipse-mosquitto" on: - push: - branches: - - master - paths: - - 'apps/eclipse-mosquitto/config.yaml' - - '.github/workflows/sbom-eclipse-mosquitto.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-eclipse-temurin.yml b/.github/workflows/sbom-eclipse-temurin.yml index af2a989..b2fb2f3 100644 --- a/.github/workflows/sbom-eclipse-temurin.yml +++ b/.github/workflows/sbom-eclipse-temurin.yml @@ -9,13 +9,6 @@ name: "SBOM: eclipse-temurin" on: - push: - branches: - - master - paths: - - 'apps/eclipse-temurin/config.yaml' - - '.github/workflows/sbom-eclipse-temurin.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-elixir.yml b/.github/workflows/sbom-elixir.yml index 9b54d85..debac55 100644 --- a/.github/workflows/sbom-elixir.yml +++ b/.github/workflows/sbom-elixir.yml @@ -9,13 +9,6 @@ name: "SBOM: elixir" on: - push: - branches: - - master - paths: - - 'apps/elixir/config.yaml' - - '.github/workflows/sbom-elixir.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-erlang.yml b/.github/workflows/sbom-erlang.yml index adef0e7..16b4005 100644 --- a/.github/workflows/sbom-erlang.yml +++ b/.github/workflows/sbom-erlang.yml @@ -9,13 +9,6 @@ name: "SBOM: erlang" on: - push: - branches: - - master - paths: - - 'apps/erlang/config.yaml' - - '.github/workflows/sbom-erlang.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-fedora.yml b/.github/workflows/sbom-fedora.yml index e9d4ffe..cf2809f 100644 --- a/.github/workflows/sbom-fedora.yml +++ b/.github/workflows/sbom-fedora.yml @@ -9,13 +9,6 @@ name: "SBOM: fedora" on: - push: - branches: - - master - paths: - - 'apps/fedora/config.yaml' - - '.github/workflows/sbom-fedora.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-ghost.yml b/.github/workflows/sbom-ghost.yml index f945259..ef3a1dd 100644 --- a/.github/workflows/sbom-ghost.yml +++ b/.github/workflows/sbom-ghost.yml @@ -9,13 +9,6 @@ name: "SBOM: ghost" on: - push: - branches: - - master - paths: - - 'apps/ghost/config.yaml' - - '.github/workflows/sbom-ghost.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-golang.yml b/.github/workflows/sbom-golang.yml index 5d19253..dad48f7 100644 --- a/.github/workflows/sbom-golang.yml +++ b/.github/workflows/sbom-golang.yml @@ -9,13 +9,6 @@ name: "SBOM: golang" on: - push: - branches: - - master - paths: - - 'apps/golang/config.yaml' - - '.github/workflows/sbom-golang.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-gradle.yml b/.github/workflows/sbom-gradle.yml index 8fd0b21..6b1a030 100644 --- a/.github/workflows/sbom-gradle.yml +++ b/.github/workflows/sbom-gradle.yml @@ -9,13 +9,6 @@ name: "SBOM: gradle" on: - push: - branches: - - master - paths: - - 'apps/gradle/config.yaml' - - '.github/workflows/sbom-gradle.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-haproxy.yml b/.github/workflows/sbom-haproxy.yml index f6cd492..dd3a412 100644 --- a/.github/workflows/sbom-haproxy.yml +++ b/.github/workflows/sbom-haproxy.yml @@ -9,13 +9,6 @@ name: "SBOM: haproxy" on: - push: - branches: - - master - paths: - - 'apps/haproxy/config.yaml' - - '.github/workflows/sbom-haproxy.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-haskell.yml b/.github/workflows/sbom-haskell.yml index 7a8498c..1c40a11 100644 --- a/.github/workflows/sbom-haskell.yml +++ b/.github/workflows/sbom-haskell.yml @@ -9,13 +9,6 @@ name: "SBOM: haskell" on: - push: - branches: - - master - paths: - - 'apps/haskell/config.yaml' - - '.github/workflows/sbom-haskell.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-httpd.yml b/.github/workflows/sbom-httpd.yml index faa8701..968ddf6 100644 --- a/.github/workflows/sbom-httpd.yml +++ b/.github/workflows/sbom-httpd.yml @@ -9,13 +9,6 @@ name: "SBOM: httpd" on: - push: - branches: - - master - paths: - - 'apps/httpd/config.yaml' - - '.github/workflows/sbom-httpd.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-influxdb.yml b/.github/workflows/sbom-influxdb.yml index f177521..73c230a 100644 --- a/.github/workflows/sbom-influxdb.yml +++ b/.github/workflows/sbom-influxdb.yml @@ -9,13 +9,6 @@ name: "SBOM: influxdb" on: - push: - branches: - - master - paths: - - 'apps/influxdb/config.yaml' - - '.github/workflows/sbom-influxdb.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-julia.yml b/.github/workflows/sbom-julia.yml index 0ff15c2..27c2056 100644 --- a/.github/workflows/sbom-julia.yml +++ b/.github/workflows/sbom-julia.yml @@ -9,13 +9,6 @@ name: "SBOM: julia" on: - push: - branches: - - master - paths: - - 'apps/julia/config.yaml' - - '.github/workflows/sbom-julia.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-keycloak-js.yml b/.github/workflows/sbom-keycloak-js.yml index edfbc19..5363e7d 100644 --- a/.github/workflows/sbom-keycloak-js.yml +++ b/.github/workflows/sbom-keycloak-js.yml @@ -8,13 +8,6 @@ name: "SBOM: keycloak-js" on: - push: - branches: - - master - paths: - - 'apps/keycloak-js/config.yaml' - - '.github/workflows/sbom-keycloak-js.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-keycloak.yml b/.github/workflows/sbom-keycloak.yml index be312d6..950abb5 100644 --- a/.github/workflows/sbom-keycloak.yml +++ b/.github/workflows/sbom-keycloak.yml @@ -5,14 +5,6 @@ name: "SBOM: keycloak" on: - push: - branches: - - master - paths: - - 'apps/keycloak/config.yaml' - - '.github/workflows/sbom-keycloak.yml' - - # Allow manual triggering workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-kong.yml b/.github/workflows/sbom-kong.yml index b4fb509..53d0732 100644 --- a/.github/workflows/sbom-kong.yml +++ b/.github/workflows/sbom-kong.yml @@ -9,13 +9,6 @@ name: "SBOM: kong" on: - push: - branches: - - master - paths: - - 'apps/kong/config.yaml' - - '.github/workflows/sbom-kong.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-mariadb.yml b/.github/workflows/sbom-mariadb.yml index 84992a1..87e7d6f 100644 --- a/.github/workflows/sbom-mariadb.yml +++ b/.github/workflows/sbom-mariadb.yml @@ -9,13 +9,6 @@ name: "SBOM: mariadb" on: - push: - branches: - - master - paths: - - 'apps/mariadb/config.yaml' - - '.github/workflows/sbom-mariadb.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-maven.yml b/.github/workflows/sbom-maven.yml index ca60735..0d6a7f9 100644 --- a/.github/workflows/sbom-maven.yml +++ b/.github/workflows/sbom-maven.yml @@ -9,13 +9,6 @@ name: "SBOM: maven" on: - push: - branches: - - master - paths: - - 'apps/maven/config.yaml' - - '.github/workflows/sbom-maven.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-memcached.yml b/.github/workflows/sbom-memcached.yml index 429fb85..c647ac8 100644 --- a/.github/workflows/sbom-memcached.yml +++ b/.github/workflows/sbom-memcached.yml @@ -9,13 +9,6 @@ name: "SBOM: memcached" on: - push: - branches: - - master - paths: - - 'apps/memcached/config.yaml' - - '.github/workflows/sbom-memcached.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-mongo-express.yml b/.github/workflows/sbom-mongo-express.yml index 5f5cb9c..f5588fc 100644 --- a/.github/workflows/sbom-mongo-express.yml +++ b/.github/workflows/sbom-mongo-express.yml @@ -9,13 +9,6 @@ name: "SBOM: mongo-express" on: - push: - branches: - - master - paths: - - 'apps/mongo-express/config.yaml' - - '.github/workflows/sbom-mongo-express.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-mongo.yml b/.github/workflows/sbom-mongo.yml index b483a15..3ab0233 100644 --- a/.github/workflows/sbom-mongo.yml +++ b/.github/workflows/sbom-mongo.yml @@ -9,13 +9,6 @@ name: "SBOM: mongo" on: - push: - branches: - - master - paths: - - 'apps/mongo/config.yaml' - - '.github/workflows/sbom-mongo.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-mysql.yml b/.github/workflows/sbom-mysql.yml index 16d2594..ee63c0f 100644 --- a/.github/workflows/sbom-mysql.yml +++ b/.github/workflows/sbom-mysql.yml @@ -9,13 +9,6 @@ name: "SBOM: mysql" on: - push: - branches: - - master - paths: - - 'apps/mysql/config.yaml' - - '.github/workflows/sbom-mysql.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-neo4j.yml b/.github/workflows/sbom-neo4j.yml index 4b07b56..10484ec 100644 --- a/.github/workflows/sbom-neo4j.yml +++ b/.github/workflows/sbom-neo4j.yml @@ -9,13 +9,6 @@ name: "SBOM: neo4j" on: - push: - branches: - - master - paths: - - 'apps/neo4j/config.yaml' - - '.github/workflows/sbom-neo4j.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-nginx.yml b/.github/workflows/sbom-nginx.yml index d4120ed..607e56a 100644 --- a/.github/workflows/sbom-nginx.yml +++ b/.github/workflows/sbom-nginx.yml @@ -9,13 +9,6 @@ name: "SBOM: nginx" on: - push: - branches: - - master - paths: - - 'apps/nginx/config.yaml' - - '.github/workflows/sbom-nginx.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-node.yml b/.github/workflows/sbom-node.yml index f569990..5b0151e 100644 --- a/.github/workflows/sbom-node.yml +++ b/.github/workflows/sbom-node.yml @@ -9,13 +9,6 @@ name: "SBOM: node" on: - push: - branches: - - master - paths: - - 'apps/node/config.yaml' - - '.github/workflows/sbom-node.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-oraclelinux.yml b/.github/workflows/sbom-oraclelinux.yml index 5202df3..1274592 100644 --- a/.github/workflows/sbom-oraclelinux.yml +++ b/.github/workflows/sbom-oraclelinux.yml @@ -9,13 +9,6 @@ name: "SBOM: oraclelinux" on: - push: - branches: - - master - paths: - - 'apps/oraclelinux/config.yaml' - - '.github/workflows/sbom-oraclelinux.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-osv-scanner.yml b/.github/workflows/sbom-osv-scanner.yml index 634d958..48ef952 100644 --- a/.github/workflows/sbom-osv-scanner.yml +++ b/.github/workflows/sbom-osv-scanner.yml @@ -5,14 +5,6 @@ name: "SBOM: osv-scanner" on: - push: - branches: - - master - paths: - - 'apps/osv-scanner/config.yaml' - - '.github/workflows/sbom-osv-scanner.yml' - - # Allow manual triggering workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-perl.yml b/.github/workflows/sbom-perl.yml index 3eb3b63..5b11eee 100644 --- a/.github/workflows/sbom-perl.yml +++ b/.github/workflows/sbom-perl.yml @@ -9,13 +9,6 @@ name: "SBOM: perl" on: - push: - branches: - - master - paths: - - 'apps/perl/config.yaml' - - '.github/workflows/sbom-perl.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-php.yml b/.github/workflows/sbom-php.yml index 6152e4a..e31d9de 100644 --- a/.github/workflows/sbom-php.yml +++ b/.github/workflows/sbom-php.yml @@ -9,13 +9,6 @@ name: "SBOM: php" on: - push: - branches: - - master - paths: - - 'apps/php/config.yaml' - - '.github/workflows/sbom-php.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-postgres.yml b/.github/workflows/sbom-postgres.yml index 65052ba..8deaac9 100644 --- a/.github/workflows/sbom-postgres.yml +++ b/.github/workflows/sbom-postgres.yml @@ -9,13 +9,6 @@ name: "SBOM: postgres" on: - push: - branches: - - master - paths: - - 'apps/postgres/config.yaml' - - '.github/workflows/sbom-postgres.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-python.yml b/.github/workflows/sbom-python.yml index 1477e53..b6055d0 100644 --- a/.github/workflows/sbom-python.yml +++ b/.github/workflows/sbom-python.yml @@ -9,13 +9,6 @@ name: "SBOM: python" on: - push: - branches: - - master - paths: - - 'apps/python/config.yaml' - - '.github/workflows/sbom-python.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-r-base.yml b/.github/workflows/sbom-r-base.yml index 50d6364..91f28a6 100644 --- a/.github/workflows/sbom-r-base.yml +++ b/.github/workflows/sbom-r-base.yml @@ -9,13 +9,6 @@ name: "SBOM: r-base" on: - push: - branches: - - master - paths: - - 'apps/r-base/config.yaml' - - '.github/workflows/sbom-r-base.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-rabbitmq.yml b/.github/workflows/sbom-rabbitmq.yml index b143d67..fe78014 100644 --- a/.github/workflows/sbom-rabbitmq.yml +++ b/.github/workflows/sbom-rabbitmq.yml @@ -9,13 +9,6 @@ name: "SBOM: rabbitmq" on: - push: - branches: - - master - paths: - - 'apps/rabbitmq/config.yaml' - - '.github/workflows/sbom-rabbitmq.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-redis.yml b/.github/workflows/sbom-redis.yml index 8aa3ed3..7c5626b 100644 --- a/.github/workflows/sbom-redis.yml +++ b/.github/workflows/sbom-redis.yml @@ -9,13 +9,6 @@ name: "SBOM: redis" on: - push: - branches: - - master - paths: - - 'apps/redis/config.yaml' - - '.github/workflows/sbom-redis.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-registry.yml b/.github/workflows/sbom-registry.yml index 68d1546..1505f44 100644 --- a/.github/workflows/sbom-registry.yml +++ b/.github/workflows/sbom-registry.yml @@ -9,13 +9,6 @@ name: "SBOM: registry" on: - push: - branches: - - master - paths: - - 'apps/registry/config.yaml' - - '.github/workflows/sbom-registry.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-rockylinux.yml b/.github/workflows/sbom-rockylinux.yml index fb596e6..191004c 100644 --- a/.github/workflows/sbom-rockylinux.yml +++ b/.github/workflows/sbom-rockylinux.yml @@ -9,13 +9,6 @@ name: "SBOM: rockylinux" on: - push: - branches: - - master - paths: - - 'apps/rockylinux/config.yaml' - - '.github/workflows/sbom-rockylinux.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-ruby.yml b/.github/workflows/sbom-ruby.yml index 6e36de0..cc3587c 100644 --- a/.github/workflows/sbom-ruby.yml +++ b/.github/workflows/sbom-ruby.yml @@ -9,13 +9,6 @@ name: "SBOM: ruby" on: - push: - branches: - - master - paths: - - 'apps/ruby/config.yaml' - - '.github/workflows/sbom-ruby.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-rust.yml b/.github/workflows/sbom-rust.yml index 4322626..6e60bcc 100644 --- a/.github/workflows/sbom-rust.yml +++ b/.github/workflows/sbom-rust.yml @@ -9,13 +9,6 @@ name: "SBOM: rust" on: - push: - branches: - - master - paths: - - 'apps/rust/config.yaml' - - '.github/workflows/sbom-rust.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-solr.yml b/.github/workflows/sbom-solr.yml index 053261b..52d340f 100644 --- a/.github/workflows/sbom-solr.yml +++ b/.github/workflows/sbom-solr.yml @@ -9,13 +9,6 @@ name: "SBOM: solr" on: - push: - branches: - - master - paths: - - 'apps/solr/config.yaml' - - '.github/workflows/sbom-solr.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-sonarqube.yml b/.github/workflows/sbom-sonarqube.yml index f47048e..8400530 100644 --- a/.github/workflows/sbom-sonarqube.yml +++ b/.github/workflows/sbom-sonarqube.yml @@ -9,13 +9,6 @@ name: "SBOM: sonarqube" on: - push: - branches: - - master - paths: - - 'apps/sonarqube/config.yaml' - - '.github/workflows/sbom-sonarqube.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-swift.yml b/.github/workflows/sbom-swift.yml index 1173eca..4d8affb 100644 --- a/.github/workflows/sbom-swift.yml +++ b/.github/workflows/sbom-swift.yml @@ -9,13 +9,6 @@ name: "SBOM: swift" on: - push: - branches: - - master - paths: - - 'apps/swift/config.yaml' - - '.github/workflows/sbom-swift.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-syft.yml b/.github/workflows/sbom-syft.yml index 33f9284..432fa5f 100644 --- a/.github/workflows/sbom-syft.yml +++ b/.github/workflows/sbom-syft.yml @@ -8,13 +8,6 @@ name: "SBOM: syft" on: - push: - branches: - - master - paths: - - 'apps/syft/config.yaml' - - '.github/workflows/sbom-syft.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-telegraf.yml b/.github/workflows/sbom-telegraf.yml index 943cd76..cbfe8e4 100644 --- a/.github/workflows/sbom-telegraf.yml +++ b/.github/workflows/sbom-telegraf.yml @@ -9,13 +9,6 @@ name: "SBOM: telegraf" on: - push: - branches: - - master - paths: - - 'apps/telegraf/config.yaml' - - '.github/workflows/sbom-telegraf.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-tomcat.yml b/.github/workflows/sbom-tomcat.yml index 4b99d8a..3488e26 100644 --- a/.github/workflows/sbom-tomcat.yml +++ b/.github/workflows/sbom-tomcat.yml @@ -9,13 +9,6 @@ name: "SBOM: tomcat" on: - push: - branches: - - master - paths: - - 'apps/tomcat/config.yaml' - - '.github/workflows/sbom-tomcat.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-traefik.yml b/.github/workflows/sbom-traefik.yml index daa528f..e16261d 100644 --- a/.github/workflows/sbom-traefik.yml +++ b/.github/workflows/sbom-traefik.yml @@ -9,13 +9,6 @@ name: "SBOM: traefik" on: - push: - branches: - - master - paths: - - 'apps/traefik/config.yaml' - - '.github/workflows/sbom-traefik.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-trivy.yml b/.github/workflows/sbom-trivy.yml index f746946..34d2e81 100644 --- a/.github/workflows/sbom-trivy.yml +++ b/.github/workflows/sbom-trivy.yml @@ -8,13 +8,6 @@ name: "SBOM: trivy" on: - push: - branches: - - master - paths: - - 'apps/trivy/config.yaml' - - '.github/workflows/sbom-trivy.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-ubuntu.yml b/.github/workflows/sbom-ubuntu.yml index b7dfcca..4fa0786 100644 --- a/.github/workflows/sbom-ubuntu.yml +++ b/.github/workflows/sbom-ubuntu.yml @@ -9,13 +9,6 @@ name: "SBOM: ubuntu" on: - push: - branches: - - master - paths: - - 'apps/ubuntu/config.yaml' - - '.github/workflows/sbom-ubuntu.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-wordpress.yml b/.github/workflows/sbom-wordpress.yml index 2115753..beb8fc8 100644 --- a/.github/workflows/sbom-wordpress.yml +++ b/.github/workflows/sbom-wordpress.yml @@ -9,13 +9,6 @@ name: "SBOM: wordpress" on: - push: - branches: - - master - paths: - - 'apps/wordpress/config.yaml' - - '.github/workflows/sbom-wordpress.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/sbom-zookeeper.yml b/.github/workflows/sbom-zookeeper.yml index c26b5e9..db9d4a5 100644 --- a/.github/workflows/sbom-zookeeper.yml +++ b/.github/workflows/sbom-zookeeper.yml @@ -9,13 +9,6 @@ name: "SBOM: zookeeper" on: - push: - branches: - - master - paths: - - 'apps/zookeeper/config.yaml' - - '.github/workflows/sbom-zookeeper.yml' - workflow_dispatch: inputs: dry_run: diff --git a/.github/workflows/tea-sync.yml b/.github/workflows/tea-sync.yml index ce71275..81a89ef 100644 --- a/.github/workflows/tea-sync.yml +++ b/.github/workflows/tea-sync.yml @@ -8,8 +8,6 @@ name: TEA Sync on: - schedule: - - cron: '0 * * * *' workflow_dispatch: {} env: diff --git a/CLAUDE.md b/CLAUDE.md index 5edd5e0..4923b41 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -26,20 +26,27 @@ sbomify SBOM Library — automates Software Bill of Materials (SBOM) extraction ## Common Commands ```bash -# Fetch SBOM for an app +# Run full SBOM pipeline for an app (fetch, build, dedup, upload) +./scripts/run.sh +./scripts/run.sh --dry-run +./scripts/run.sh --all +./scripts/run.sh --all --parallel 5 +./scripts/run.sh --type docker +./scripts/run.sh --app redis,trivy + +# Fetch SBOM only (no augment/upload) ./scripts/fetch-sbom.sh -# Dry-run (no actual fetch/upload) -./scripts/fetch-sbom.sh --dry-run - # Debug logging -LOG_LEVEL=DEBUG ./scripts/fetch-sbom.sh +LOG_LEVEL=DEBUG ./scripts/run.sh # Lint shellcheck scripts/**/*.sh yamllint . ``` +> **Note:** Per-app workflow triggers (`sbom-*.yml`) are disabled (dispatch-only). Use `run.sh` for local execution. The lint workflow remains active on PRs. + ## Adding a New App 1. Copy `apps/.template/` to `apps//` diff --git a/scripts/run.sh b/scripts/run.sh new file mode 100755 index 0000000..7af0ea0 --- /dev/null +++ b/scripts/run.sh @@ -0,0 +1,508 @@ +#!/usr/bin/env bash +# run.sh - Local SBOM pipeline runner +# +# Processes apps through the full SBOM pipeline locally: +# fetch SBOM, build augmented SBOM, dedup check, upload, cleanup. +# +# Usage: +# ./scripts/run.sh # Single app +# ./scripts/run.sh --all # All apps +# ./scripts/run.sh --type docker # Filter by source type +# ./scripts/run.sh --app redis,trivy # Specific apps +# ./scripts/run.sh --dry-run # No upload +# ./scripts/run.sh --all --parallel 5 # Parallel execution +# +# shellcheck source-path=SCRIPTDIR +# shellcheck source=lib/common.sh + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# shellcheck source=lib/common.sh +source "${SCRIPT_DIR}/lib/common.sh" +# shellcheck source=lib/sbomify-api.sh +source "${SCRIPT_DIR}/lib/sbomify-api.sh" + +# ============================================================================= +# Constants +# ============================================================================= + +MAX_PARALLEL=5 + +# ============================================================================= +# Argument Parsing +# ============================================================================= + +RUN_ALL=false +FILTER_TYPE="" +FILTER_APPS="" +SINGLE_APP="" +PARALLEL_COUNT="" + +print_run_usage() { + cat >&2 </dev/null || true) + if [[ -n "$result" && "$result" != "{}" && "$result" != "null" ]]; then + log_info "Version already published on TEA, skipping upload" + should_upload=false + else + log_info "Version not found on TEA, will upload" + fi + fi + fi + fi + + # ------------------------------------------------------------------------- + # Step 5: Upload (if new + not dry-run) + # ------------------------------------------------------------------------- + if is_dry_run; then + log_info "[DRY RUN] Would upload SBOM for $app" + elif [[ "$should_upload" == true ]]; then + # Build product release array + local product_id bundle_product_id product_release="" + product_id=$(get_config "$app" ".sbomify.product_id" "") + bundle_product_id=$(get_config "$app" ".sbomify.bundle_product_id" "") + + if [[ -n "$product_id" && -n "$version" ]]; then + product_release="\"${product_id}:${version}\"" + if [[ -n "$bundle_product_id" ]]; then + product_release="${product_release},\"${bundle_product_id}:${version}\"" + fi + product_release="[${product_release}]" + fi + + log_info "Uploading SBOM..." + local upload_env=( + "TOKEN=${SBOMIFY_TOKEN:-}" + "COMPONENT_ID=${component_id}" + "COMPONENT_NAME=${component_name}" + "COMPONENT_VERSION=${component_version}" + "COMPONENT_PURL=${component_purl}" + "SBOM_FILE=${work_dir}/sbom-output.json" + "OUTPUT_FILE=${work_dir}/sbom-final.json" + "UPLOAD=true" + ) + if [[ -n "$product_release" ]]; then + upload_env+=("PRODUCT_RELEASE=${product_release}") + fi + + env "${upload_env[@]}" uvx --from sbomify-action sbomify-action + log_info "Upload complete for $app" + else + log_info "Skipping upload for $app (already exists)" + fi + + # ------------------------------------------------------------------------- + # Step 6: Cleanup (docker/chainguard only) + # ------------------------------------------------------------------------- + if ! is_dry_run && [[ "$source_type" == "docker" || "$source_type" == "chainguard" ]]; then + if [[ "$should_upload" == true ]]; then + log_info "Cleaning up old SBOMs..." + sbomify_cleanup_old_sboms "$component_id" "$image_digest" + + local product_id_cleanup + product_id_cleanup=$(get_config "$app" ".sbomify.product_id" "") + if [[ -n "$product_id_cleanup" ]]; then + sbomify_cleanup_versioned_releases "$product_id_cleanup" + fi + fi + fi + + log_info "=== Done: $app ===" +} + +# ============================================================================= +# Tool Checks +# ============================================================================= + +check_tools() { + local apps=("$@") + + require_cmd "yq" "Install with: brew install yq" + require_cmd "jq" "Install with: brew install jq" + + # Check uvx (needed for sbomify-action and tea-cli) + if ! command -v uvx &>/dev/null; then + die "Required command 'uvx' not found. Install with: pip install uv" + fi + + # Check source-type-specific tools + local needs_crane=false needs_cosign=false + for app in "${apps[@]}"; do + local src_type + src_type=$(get_source_type "$app") + case "$src_type" in + docker) needs_crane=true ;; + chainguard) needs_cosign=true ;; + esac + done + + if [[ "$needs_crane" == true ]]; then + require_cmd "crane" "Install with: go install github.com/google/go-containerregistry/cmd/crane@latest" + fi + if [[ "$needs_cosign" == true ]]; then + require_cmd "cosign" "Install from: https://github.com/sigstore/cosign" + fi + + # Validate SBOMIFY_TOKEN for non-dry-run + if ! is_dry_run && [[ -z "${SBOMIFY_TOKEN:-}" ]]; then + die "SBOMIFY_TOKEN is required for upload. Set it or use --dry-run." + fi +} + +# ============================================================================= +# App List Builder +# ============================================================================= + +build_app_list() { + local apps=() + + if [[ -n "$SINGLE_APP" ]]; then + apps=("$SINGLE_APP") + elif [[ -n "$FILTER_APPS" ]]; then + IFS=',' read -ra apps <<< "$FILTER_APPS" + else + for config in "${APPS_DIR}"/*/config.yaml; do + local app_dir app + app_dir="$(dirname "$config")" + app="$(basename "$app_dir")" + + # Skip template + [[ "$app" == ".template" ]] && continue + + # Apply type filter + if [[ -n "$FILTER_TYPE" ]]; then + local src_type + src_type=$(yq -r '.source.type' "$config") + [[ "$src_type" != "$FILTER_TYPE" ]] && continue + fi + + apps+=("$app") + done + fi + + # Validate all apps exist + for app in "${apps[@]}"; do + validate_app_dir "$app" + done + + if [[ ${#apps[@]} -eq 0 ]]; then + die "No apps found matching filters." + fi + + echo "${apps[@]}" +} + +# ============================================================================= +# Main +# ============================================================================= + +main() { + parse_args "$@" + + # Build app list + local app_list + app_list=$(build_app_list) + local apps=() + read -ra apps <<< "$app_list" + + # Check required tools + check_tools "${apps[@]}" + + local total=${#apps[@]} + log_info "Processing ${total} app(s)..." + + if [[ $total -eq 1 ]]; then + # Single app — run directly + process_app "${apps[0]}" + else + # Multiple apps — run in parallel + local running=0 + local pids=() + local failed=0 + + for app in "${apps[@]}"; do + ( + # Clear inherited EXIT trap so child doesn't remove parent's temp dir + trap - EXIT + _SBOM_TEMP_DIRS=() + process_app "$app" + ) & + pids+=($!) + running=$(( running + 1 )) + + if [[ $running -ge $MAX_PARALLEL ]]; then + wait -n 2>/dev/null || failed=$(( failed + 1 )) + running=$(( running - 1 )) + fi + done + + # Wait for remaining jobs + for pid in "${pids[@]}"; do + wait "$pid" 2>/dev/null || failed=$(( failed + 1 )) + done + + if [[ $failed -gt 0 ]]; then + log_warn "${failed} app(s) failed" + exit 1 + fi + fi + + log_info "All done." +} + +main "$@" From 4cbe825f5b641375cb592198e1f3bb785fee6f74 Mon Sep 17 00:00:00 2001 From: Viktor Petersson Date: Sun, 8 Mar 2026 15:12:36 +0000 Subject: [PATCH 2/2] Hardcode linux/amd64 platform for container image pulls Ignore per-app platform config and always pull x86_64 images for deterministic SBOM extraction across all environments. Co-Authored-By: Claude Opus 4.6 --- scripts/check-updates.sh | 2 +- scripts/sources/chainguard.sh | 2 +- scripts/sources/docker-attestation.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/check-updates.sh b/scripts/check-updates.sh index 05197b8..bccc700 100755 --- a/scripts/check-updates.sh +++ b/scripts/check-updates.sh @@ -163,7 +163,7 @@ get_latest_docker_version() { local registry image current platform registry=$(get_config "$app" ".source.registry" "docker.io") image=$(get_config "$app" ".source.image") - platform=$(get_config "$app" ".source.platform" "linux/amd64") + platform="linux/amd64" current=$(yq -r '.version' "${APPS_DIR}/${app}/config.yaml") local image_ref="${registry}/${image}:latest" diff --git a/scripts/sources/chainguard.sh b/scripts/sources/chainguard.sh index 579781b..970eadc 100755 --- a/scripts/sources/chainguard.sh +++ b/scripts/sources/chainguard.sh @@ -13,7 +13,7 @@ app="$1" version=$(get_latest_version "$app") registry=$(get_config "$app" ".source.registry" "cgr.dev/chainguard") image=$(get_config "$app" ".source.image") -platform=$(get_config "$app" ".source.platform" "linux/amd64") +platform="linux/amd64" image_ref="${registry}/${image}:${version}" log_info "Downloading attestation: $image_ref" diff --git a/scripts/sources/docker-attestation.sh b/scripts/sources/docker-attestation.sh index 5af6776..6f0025d 100755 --- a/scripts/sources/docker-attestation.sh +++ b/scripts/sources/docker-attestation.sh @@ -13,7 +13,7 @@ app="$1" version=$(get_latest_version "$app") registry=$(get_config "$app" ".source.registry" "docker.io") image=$(get_config "$app" ".source.image") -platform=$(get_config "$app" ".source.platform" "linux/amd64") +platform="linux/amd64" image_ref="${registry}/${image}:${version}" log_info "Extracting SBOM: $image_ref"