name: Docker Scout Analysis on: pull_request: branches: ["**"] permissions: contents: read pull-requests: write env: DOCKER_IMAGE: docker.io/svrnty/dotnet jobs: check-image: runs-on: ubuntu-latest outputs: image_exists: ${{ steps.check.outputs.exists }} steps: - name: Log in to DockerHub uses: docker/login-action@v3 with: username: ${{ secrets.REGISTRY_USERNAME }} password: ${{ secrets.REGISTRY_PASSWORD }} - name: Check if latest runtime-lts image exists id: check run: | if docker manifest inspect ${{ env.DOCKER_IMAGE }}:runtime-lts > /dev/null 2>&1; then echo "exists=true" >> $GITHUB_OUTPUT echo "Latest runtime-lts image found, Scout compare will run" else echo "exists=false" >> $GITHUB_OUTPUT echo "No runtime-lts image found, skipping Scout compare" fi scout: runs-on: ubuntu-latest needs: check-image if: needs.check-image.outputs.image_exists == 'true' strategy: matrix: arch: [amd64, arm64] steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up QEMU if: matrix.arch == 'arm64' uses: docker/setup-qemu-action@v3 with: platforms: arm64 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to DockerHub uses: docker/login-action@v3 with: username: ${{ secrets.REGISTRY_USERNAME }} password: ${{ secrets.REGISTRY_PASSWORD }} - name: Discover latest LTS version id: discover run: | set -euo pipefail RELEASES=$(curl -fsSL https://dotnetcli.azureedge.net/dotnet/release-metadata/releases-index.json) SUPPORTED=$(echo "$RELEASES" | jq -c '[.["releases-index"][] | select(.["support-phase"] == "active" or .["support-phase"] == "go-live")]') # Find highest LTS major LTS_MAJOR=$(echo "$SUPPORTED" | jq -r '[.[] | select(.["release-type"] == "lts")] | sort_by(.["channel-version"] | split(".") | map(tonumber)) | last | .["channel-version"] | split(".")[0]') LTS_RUNTIME=$(echo "$SUPPORTED" | jq -r --arg ch "${LTS_MAJOR}.0" '.[] | select(.["channel-version"] == $ch) | .["latest-runtime"]') echo "lts_major=$LTS_MAJOR" >> $GITHUB_OUTPUT echo "lts_runtime=$LTS_RUNTIME" >> $GITHUB_OUTPUT - name: Build test image (${{ matrix.arch }}) run: | # Build apko base docker run --rm -v ${{ github.workspace }}/apko:/work cgr.dev/chainguard/apko build \ --arch ${{ matrix.arch == 'amd64' && 'x86_64' || 'aarch64' }} \ /work/runtime.yaml runtime:latest /tmp/rootfs.tar.gz # Download .NET runtime DOTNET_ARCH=${{ matrix.arch == 'amd64' && 'x64' || 'arm64' }} RUNTIME_VERSION=${{ steps.discover.outputs.lts_runtime }} curl -fsSL "https://dotnetcli.azureedge.net/dotnet/aspnetcore/Runtime/${RUNTIME_VERSION}/aspnetcore-runtime-${RUNTIME_VERSION}-linux-${DOTNET_ARCH}.tar.gz" \ -o /tmp/dotnet.tar.gz mkdir -p /tmp/dotnet tar xf /tmp/dotnet.tar.gz -C /tmp/dotnet # Build image cat > /tmp/Dockerfile <<'DOCKERFILE' FROM scratch ADD rootfs.tar.gz / COPY dotnet/ /usr/share/dotnet/ ENV DOTNET_ROOT=/usr/share/dotnet ENV PATH="/usr/share/dotnet:${PATH}" WORKDIR /app USER 65532 DOCKERFILE docker build -t ${{ env.DOCKER_IMAGE }}:pr-${{ github.event.pull_request.number }}-${{ matrix.arch }} /tmp/ - name: Install Docker Scout run: | curl -fsSL https://raw.githubusercontent.com/docker/scout-cli/main/install.sh -o install-scout.sh sh install-scout.sh - name: Docker Scout Compare (${{ matrix.arch }}) run: | docker scout compare \ ${{ env.DOCKER_IMAGE }}:pr-${{ github.event.pull_request.number }}-${{ matrix.arch }} \ --to ${{ env.DOCKER_IMAGE }}:runtime-lts \ --ignore-unchanged --only-severity critical,high