name: Docker Build, Scan & Publish on: workflow_call: inputs: images: description: > JSON array of images to build. Each item: { name, context, dockerfile, target, cache_ref } required: true type: string registry_host: required: true type: string default_branch: required: true type: string build_args: required: false type: string default: "" trivy_severity: required: false type: string default: "CRITICAL" secrets: registry_user: required: true registry_password: required: true ci_token: required: true jobs: build: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Determine branch context id: branch run: | if [ "${{ github.ref_name }}" = "${{ inputs.default_branch }}" ]; then echo "is_default=true" >> "$GITHUB_OUTPUT" else echo "is_default=false" >> "$GITHUB_OUTPUT" fi - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Login to registry uses: docker/login-action@v3 with: registry: ${{ inputs.registry_host }} username: ${{ secrets.registry_user }} password: ${{ secrets.registry_password }} - name: Build, scan and push images env: IMAGES: ${{ inputs.images }} BUILD_ARGS: ${{ inputs.build_args }} CI_TOKEN: ${{ secrets.ci_token }} TRIVY_SEVERITY: ${{ inputs.trivy_severity }} run: | set -euo pipefail echo "$IMAGES" | jq -c '.[]' | while read -r img; do NAME=$(echo "$img" | jq -r '.name') CONTEXT=$(echo "$img" | jq -r '.context') DOCKERFILE=$(echo "$img" | jq -r '.dockerfile') TARGET=$(echo "$img" | jq -r '.target') CACHE_REF=$(echo "$img" | jq -r '.cache_ref') echo "==== Building $NAME ====" TAGS=() TAGS+=("$NAME:${{ github.ref_name }}") TAGS+=("$NAME:${{ github.sha }}") if [ "${{ steps.branch.outputs.is_default }}" = "true" ]; then TAGS+=("$NAME:latest") fi TAG_ARGS=$(printf -- "--tag %s " "${TAGS[@]}") docker buildx build \ --file "$DOCKERFILE" \ --target "$TARGET" \ --cache-from "type=registry,ref=$CACHE_REF" \ --cache-to "type=registry,ref=$CACHE_REF,mode=max" \ --load \ $TAG_ARGS \ $(printf -- "--build-arg %s " $BUILD_ARGS) \ "$CONTEXT" echo "==== Trivy scan for $NAME ====" trivy image \ --severity "$TRIVY_SEVERITY" \ --exit-code 1 \ "${TAGS[0]}" echo "==== Pushing $NAME ====" for tag in "${TAGS[@]}"; do docker push "$tag" done done