docker-dotnet/.gitea/workflows/build.yaml
Mathias Beaulieu-Duncan 742aef8983
Some checks failed
Build and Push .NET Images / build (release) Failing after 11m26s
Build and Push .NET Images / build (push) Failing after 9m32s
Daily .NET Version Check / check-versions (push) Failing after 7s
Merge discover and build into single job with shell loop
Gitea Actions does not pass dynamic matrix values from fromJson
cross-job outputs correctly, causing empty variables. Replace the
two-job matrix strategy with a single job that discovers versions
and iterates in bash.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 18:04:33 -05:00

171 lines
6.9 KiB
YAML

name: Build and Push .NET Images
on:
release:
types: [published, prereleased]
workflow_dispatch:
schedule:
# Weekly rebuild for CVE patches (Sunday 6am UTC)
- cron: "0 6 * * 0"
permissions:
id-token: write
contents: read
packages: write
env:
DOCKER_IMAGE: docker.io/svrnty/dotnet
RELEASES_INDEX_URL: https://dotnetcli.azureedge.net/dotnet/release-metadata/releases-index.json
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up QEMU
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: Install apko
run: |
curl -fsSL https://github.com/chainguard-dev/apko/releases/latest/download/apko_$(curl -fsSL https://api.github.com/repos/chainguard-dev/apko/releases/latest | jq -r .tag_name | sed 's/^v//')_linux_amd64.tar.gz \
| tar xz --strip-components=1 -C /usr/local/bin
- 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: Determine tag suffix
id: suffix
run: |
if [[ "${{ github.event.release.prerelease }}" == "true" ]]; then
echo "TAG_SUFFIX=-test" >> $GITHUB_ENV
echo "Prerelease detected — tags will use -test suffix"
else
echo "TAG_SUFFIX=" >> $GITHUB_ENV
fi
- name: Discover versions and build all images
run: |
set -euo pipefail
# Discover supported .NET versions
RELEASES=$(curl -fsSL "$RELEASES_INDEX_URL")
SUPPORTED=$(echo "$RELEASES" | jq -c '[.["releases-index"][] | select(.["support-phase"] == "active" or .["support-phase"] == "go-live")]')
LTS_MAJOR=$(echo "$SUPPORTED" | jq -r '[.[] | select(.["release-type"] == "lts")] | sort_by(.["channel-version"] | split(".") | map(tonumber)) | last | .["channel-version"] | split(".")[0]')
STS_MAJOR=$(echo "$SUPPORTED" | jq -r '[.[] | select(.["release-type"] == "sts")] | sort_by(.["channel-version"] | split(".") | map(tonumber)) | last | .["channel-version"] | split(".")[0] // ""')
echo "LTS major: $LTS_MAJOR"
echo "STS major: $STS_MAJOR"
# Build apko base images (shared across all .NET versions)
for VARIANT in runtime runtime-invariant sdk; do
for ARCH in x86_64 aarch64; do
echo "::group::Building apko base: $VARIANT ($ARCH)"
mkdir -p build-${ARCH}/${VARIANT}
apko build --arch $ARCH \
apko/${VARIANT}.yaml ${VARIANT}:latest build-${ARCH}/${VARIANT}/rootfs.tar.gz
echo "::endgroup::"
done
done
# Iterate over each supported .NET version
echo "$SUPPORTED" | jq -r '.[] | "\(.["channel-version"] | split(".")[0]) \(.["latest-runtime"]) \(.["latest-sdk"]) \(.["release-type"])"' | \
while read -r MAJOR RUNTIME SDK TYPE; do
echo "============================================="
echo "Building .NET $MAJOR: runtime=$RUNTIME sdk=$SDK type=$TYPE"
echo "============================================="
# Download .NET binaries
for ARCH in x86_64 aarch64; do
if [ "$ARCH" = "x86_64" ]; then
DOTNET_ARCH="x64"
PLATFORM_ARCH="amd64"
else
DOTNET_ARCH="arm64"
PLATFORM_ARCH="arm64"
fi
echo "::group::Downloading ASP.NET Core runtime $RUNTIME ($DOTNET_ARCH)"
mkdir -p dotnet-${PLATFORM_ARCH}/runtime
curl -fsSL "https://dotnetcli.azureedge.net/dotnet/aspnetcore/Runtime/${RUNTIME}/aspnetcore-runtime-${RUNTIME}-linux-${DOTNET_ARCH}.tar.gz" \
-o /tmp/aspnet-runtime-${PLATFORM_ARCH}.tar.gz
tar xf /tmp/aspnet-runtime-${PLATFORM_ARCH}.tar.gz -C dotnet-${PLATFORM_ARCH}/runtime
echo "::endgroup::"
echo "::group::Downloading .NET SDK $SDK ($DOTNET_ARCH)"
mkdir -p dotnet-${PLATFORM_ARCH}/sdk
curl -fsSL "https://dotnetcli.azureedge.net/dotnet/Sdk/${SDK}/dotnet-sdk-${SDK}-linux-${DOTNET_ARCH}.tar.gz" \
-o /tmp/dotnet-sdk-${PLATFORM_ARCH}.tar.gz
tar xf /tmp/dotnet-sdk-${PLATFORM_ARCH}.tar.gz -C dotnet-${PLATFORM_ARCH}/sdk
echo "::endgroup::"
done
# Build and push each variant
for VARIANT in runtime runtime-invariant sdk; do
if [ "$VARIANT" = "sdk" ]; then
VERSION="$SDK"
DOTNET_DIR="sdk"
else
VERSION="$RUNTIME"
DOTNET_DIR="runtime"
fi
echo "::group::Building $VARIANT-$MAJOR"
# Prepare build context
CONTEXT="context-${VARIANT}-${MAJOR}"
rm -rf "$CONTEXT"
mkdir -p "$CONTEXT"
for ARCH in amd64 arm64; do
APKO_ARCH=$([[ "$ARCH" == "amd64" ]] && echo "x86_64" || echo "aarch64")
mkdir -p "$CONTEXT/build-${ARCH}/${VARIANT}"
cp "build-${APKO_ARCH}/${VARIANT}/rootfs.tar.gz" "$CONTEXT/build-${ARCH}/${VARIANT}/"
mkdir -p "$CONTEXT/dotnet-${ARCH}"
cp -r "dotnet-${ARCH}/${DOTNET_DIR}" "$CONTEXT/dotnet-${ARCH}/"
done
cp "dockerfiles/${VARIANT}.Dockerfile" "$CONTEXT/Dockerfile"
# Determine tags
TAGS="-t $DOCKER_IMAGE:${VARIANT}-${MAJOR}${TAG_SUFFIX} -t $DOCKER_IMAGE:${VARIANT}-${VERSION}${TAG_SUFFIX}"
if [ "$MAJOR" = "$LTS_MAJOR" ]; then
TAGS="$TAGS -t $DOCKER_IMAGE:${VARIANT}-lts${TAG_SUFFIX}"
fi
if [ "$MAJOR" = "$STS_MAJOR" ]; then
TAGS="$TAGS -t $DOCKER_IMAGE:${VARIANT}-sts${TAG_SUFFIX}"
fi
echo "Building $VARIANT with tags: $TAGS"
docker buildx build --platform linux/amd64,linux/arm64 --push \
--sbom=true --provenance=mode=max \
$TAGS \
"$CONTEXT/"
echo "::endgroup::"
done
# Docker Scout CVE scan
for VARIANT in runtime runtime-invariant sdk; do
echo "::group::Scout scan: ${VARIANT}-${MAJOR}"
docker scout cves "$DOCKER_IMAGE:${VARIANT}-${MAJOR}${TAG_SUFFIX}" --only-severity critical,high || true
echo "::endgroup::"
done
# Clean up .NET binaries for this version before next iteration
rm -rf dotnet-amd64 dotnet-arm64
done