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
49 changes: 42 additions & 7 deletions .github/image-matrix.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,44 @@
[
{ "name": "postgres", "package": "postgres-image", "sbomify_component_id": "M8rixM6mMEPe" },
{ "name": "redis", "package": "redis-image", "sbomify_component_id": "ABBCcw2YiYrG" },
{ "name": "minio", "package": "minio-image", "sbomify_component_id": "PLACEHOLDER_MINIO" },
{ "name": "sbomify-app", "package": "sbomify-app-image", "sbomify_component_id": "VP42I4XQgpDE" },
{ "name": "sbomify-keycloak", "package": "sbomify-keycloak-image", "sbomify_component_id": "N4agQD8pvej8" },
{ "name": "sbomify-caddy-dev", "package": "sbomify-caddy-dev-image", "sbomify_component_id": "zYDq6NtrOBuo" },
{ "name": "sbomify-minio-init", "package": "sbomify-minio-init-image", "sbomify_component_id": "PLACEHOLDER_SBOMIFY_MINIO_INIT" }
{
"name": "postgres",
"package": "postgres-image",
"sbomify_component_id": "M8rixM6mMEPe",
"paths": ["common/images/postgres.nix"]
},
{
"name": "redis",
"package": "redis-image",
"sbomify_component_id": "ABBCcw2YiYrG",
"paths": ["common/images/redis.nix"]
},
{
"name": "minio",
"package": "minio-image",
"sbomify_component_id": "PLACEHOLDER_MINIO",
"paths": ["common/images/minio.nix"]
},
{
"name": "sbomify-app",
"package": "sbomify-app-image",
"sbomify_component_id": "VP42I4XQgpDE",
"paths": ["apps/sbomify/images/sbomify-app.nix", "apps/sbomify/deployments/build-support/"]
},
{
"name": "sbomify-keycloak",
"package": "sbomify-keycloak-image",
"sbomify_component_id": "N4agQD8pvej8",
"paths": ["apps/sbomify/images/sbomify-keycloak.nix"]
},
{
"name": "sbomify-caddy-dev",
"package": "sbomify-caddy-dev-image",
"sbomify_component_id": "zYDq6NtrOBuo",
"paths": ["apps/sbomify/images/sbomify-caddy-dev.nix", "apps/sbomify/deployments/compose/Caddyfile.dev"]
},
{
"name": "sbomify-minio-init",
"package": "sbomify-minio-init-image",
"sbomify_component_id": "PLACEHOLDER_SBOMIFY_MINIO_INIT",
"paths": ["apps/sbomify/images/sbomify-minio-init.nix"]
}
]
27 changes: 26 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,35 @@ jobs:
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- id: set
run: echo "matrix=$(jq -c . .github/image-matrix.json)" >> "$GITHUB_OUTPUT"
env:
GH_TOKEN: ${{ github.token }}
run: |
# On workflow_dispatch, build everything
if [ "${{ github.event_name }}" != "pull_request" ]; then
echo "matrix=$(jq -c '[.[] | del(.paths)]' .github/image-matrix.json)" >> "$GITHUB_OUTPUT"
exit 0
fi

# Get changed files from the PR
CHANGED_FILE="$(mktemp)"
gh api "repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files" \
--paginate --jq '.[].filename' > "$CHANGED_FILE"

MATRIX=$(common/lib/scripts/filter-build-matrix .github/image-matrix.json "$CHANGED_FILE")
rm -f "$CHANGED_FILE"
echo "matrix=$MATRIX" >> "$GITHUB_OUTPUT"

- name: Write filtered matrix file
run: echo '${{ steps.set.outputs.matrix }}' > filtered-matrix.json
- name: Upload filtered matrix
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
with:
name: filtered-matrix
path: filtered-matrix.json

build:
needs: load-matrix
if: ${{ needs.load-matrix.outputs.matrix != '[]' }}
runs-on: blacksmith-4vcpu-ubuntu-2404
defaults:
run:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/cleanup-stale-images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- id: set
run: echo "matrix=$(jq -c . .github/image-matrix.json)" >> "$GITHUB_OUTPUT"
run: echo "matrix=$(jq -c '[.[] | del(.paths)]' .github/image-matrix.json)" >> "$GITHUB_OUTPUT"

weekly-sweep:
needs: load-matrix
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pre-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- id: set
run: echo "matrix=$(jq -c . .github/image-matrix.json)" >> "$GITHUB_OUTPUT"
run: echo "matrix=$(jq -c '[.[] | del(.paths)]' .github/image-matrix.json)" >> "$GITHUB_OUTPUT"

resolve-pr:
runs-on: blacksmith-2vcpu-ubuntu-2404
Expand Down
9 changes: 8 additions & 1 deletion .github/workflows/sbom-quality-gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,22 @@ jobs:
head_sha7: ${{ steps.sha.outputs.head_sha7 }}
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- name: Download filtered matrix from build run
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
name: filtered-matrix
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ github.token }}
- id: set
run: echo "matrix=$(jq -c . .github/image-matrix.json)" >> "$GITHUB_OUTPUT"
run: echo "matrix=$(jq -c . filtered-matrix.json)" >> "$GITHUB_OUTPUT"
- id: sha
run: |
HEAD_SHA="${{ github.event.workflow_run.head_sha }}"
echo "head_sha7=${HEAD_SHA::7}" >> "$GITHUB_OUTPUT"

score:
needs: load-matrix
if: ${{ needs.load-matrix.outputs.matrix != '[]' }}
runs-on: blacksmith-2vcpu-ubuntu-2404
defaults:
run:
Expand Down
86 changes: 86 additions & 0 deletions common/lib/scripts/filter-build-matrix
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#!/usr/bin/env bash
set -euo pipefail

# Filter the image build matrix to only images whose paths were changed.
#
# Usage: filter-build-matrix [--jq-cmd CMD] <matrix.json> <changed-files>
#
# Arguments:
# matrix.json Path to the full image matrix JSON (array of objects with .name and .paths)
# changed-files Path to a file with one changed filepath per line
#
# The script checks changed files against two categories:
# 1. "Rebuild-all" paths — changes here trigger a full rebuild of every image:
# flake.nix, flake.lock, common/lib/*, common/pkgs/*, common/images/*,
# .github/workflows/build.yml, .github/image-matrix.json
# 2. Per-image paths — each matrix entry's .paths[] are matched as prefixes
#
# Output (stdout): filtered matrix JSON (array, .paths stripped). Empty array if nothing matched.
# Exit code: 0 always (empty array is valid — the caller decides what to do).

jq_cmd="jq"

while [ $# -gt 0 ]; do
case "$1" in
--jq-cmd) jq_cmd="$2"; shift 2 ;;
-*) echo "Unknown option: $1" >&2; exit 1 ;;
*) break ;;
esac
done

if [ $# -lt 2 ]; then
echo "Usage: filter-build-matrix [--jq-cmd CMD] <matrix.json> <changed-files>" >&2
exit 1
fi

matrix_file="$1"
changed_file="$2"

if [ ! -f "$matrix_file" ]; then
echo "Matrix file not found: $matrix_file" >&2
exit 1
fi

if [ ! -f "$changed_file" ]; then
echo "Changed-files file not found: $changed_file" >&2
exit 1
fi

FULL_MATRIX=$(<"$matrix_file")
CHANGED=$(<"$changed_file")

# Check for paths that should trigger a full rebuild
REBUILD_ALL=false
while IFS= read -r file; do
[ -z "$file" ] && continue
case "$file" in
flake.nix|flake.lock) REBUILD_ALL=true ;;
common/lib/*|common/pkgs/*|common/images/*) REBUILD_ALL=true ;;
.github/workflows/build.yml|.github/image-matrix.json) REBUILD_ALL=true ;;
esac
done <<< "$CHANGED"

if [ "$REBUILD_ALL" = true ]; then
echo "Rebuild-all path changed; building all images" >&2
echo "$FULL_MATRIX" | "$jq_cmd" -c '[.[] | del(.paths)]'
exit 0
fi

# Filter to only images whose paths were touched
CHANGED_JSON=$(echo "$CHANGED" | "$jq_cmd" -R -s 'split("\n") | map(select(. != ""))')
FILTERED=$(echo "$FULL_MATRIX" | "$jq_cmd" -c --argjson changed "$CHANGED_JSON" '
[.[] | select(
.paths as $paths |
any($changed[]; . as $file |
any($paths[]; . as $prefix | $file | startswith($prefix))
)
) | del(.paths)]
')

if [ "$FILTERED" = "[]" ]; then
echo "No image paths changed; nothing to build" >&2
else
echo "Building filtered images: $(echo "$FILTERED" | "$jq_cmd" -r '[.[].name] | join(", ")')" >&2
fi

echo "$FILTERED"
Loading
Loading