docker-dotnet/.gitea/workflows/build.yaml
Mathias Beaulieu-Duncan 7cf9b1b914
Some checks failed
Build and Push .NET Images / discover (release) Successful in 2s
Build and Push .NET Images / build (release) Failing after 9m32s
Install apko as binary instead of running via Docker
The Gitea runner executes inside Docker, so volume mounts from
docker run resolve against the host filesystem where the workspace
path does not exist. Install apko directly on the runner to avoid
the Docker-in-Docker volume mount issue.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 17:39:57 -05:00

260 lines
10 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:
discover:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.discover.outputs.matrix }}
lts_major: ${{ steps.discover.outputs.lts_major }}
sts_major: ${{ steps.discover.outputs.sts_major }}
tag_suffix: ${{ steps.suffix.outputs.tag_suffix }}
steps:
- name: Determine tag suffix
id: suffix
run: |
if [[ "${{ github.event.release.prerelease }}" == "true" ]]; then
echo "tag_suffix=-test" >> $GITHUB_OUTPUT
echo "Prerelease detected — tags will use -test suffix"
else
echo "tag_suffix=" >> $GITHUB_OUTPUT
fi
- name: Discover supported .NET versions
id: discover
run: |
set -euo pipefail
RELEASES=$(curl -fsSL "$RELEASES_INDEX_URL")
# Filter active/go-live versions (excludes EOL automatically)
SUPPORTED=$(echo "$RELEASES" | jq -c '[.["releases-index"][] | select(.["support-phase"] == "active" or .["support-phase"] == "go-live")]')
# Build matrix JSON
MATRIX=$(echo "$SUPPORTED" | jq -c '{include: [.[] | {
major: (.["channel-version"] | split(".")[0]),
runtime: .["latest-runtime"],
sdk: .["latest-sdk"],
type: .["release-type"]
}]}')
# Find highest LTS and STS majors
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 "matrix=$MATRIX" >> $GITHUB_OUTPUT
echo "lts_major=$LTS_MAJOR" >> $GITHUB_OUTPUT
echo "sts_major=$STS_MAJOR" >> $GITHUB_OUTPUT
echo "Matrix: $MATRIX"
echo "LTS major: $LTS_MAJOR"
echo "STS major: $STS_MAJOR"
build:
runs-on: ubuntu-latest
needs: discover
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.discover.outputs.matrix) }}
env:
LTS_MAJOR: ${{ needs.discover.outputs.lts_major }}
STS_MAJOR: ${{ needs.discover.outputs.sts_major }}
TAG_SUFFIX: ${{ needs.discover.outputs.tag_suffix }}
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 -C /usr/local/bin apko
- name: Build apko base images
run: |
set -euo pipefail
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
- name: Download .NET binaries
run: |
set -euo pipefail
RUNTIME_VERSION="${{ matrix.runtime }}"
SDK_VERSION="${{ matrix.sdk }}"
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
# Download ASP.NET Core runtime (for runtime and runtime-invariant)
echo "::group::Downloading ASP.NET Core runtime $RUNTIME_VERSION ($DOTNET_ARCH)"
mkdir -p dotnet-${PLATFORM_ARCH}/runtime
curl -fsSL "https://dotnetcli.azureedge.net/dotnet/aspnetcore/Runtime/${RUNTIME_VERSION}/aspnetcore-runtime-${RUNTIME_VERSION}-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::"
# Download .NET SDK
echo "::group::Downloading .NET SDK $SDK_VERSION ($DOTNET_ARCH)"
mkdir -p dotnet-${PLATFORM_ARCH}/sdk
curl -fsSL "https://dotnetcli.azureedge.net/dotnet/Sdk/${SDK_VERSION}/dotnet-sdk-${SDK_VERSION}-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
- name: Build and push runtime image
run: |
set -euo pipefail
MAJOR="${{ matrix.major }}"
VERSION="${{ matrix.runtime }}"
VARIANT="runtime"
# Prepare build context
mkdir -p context-runtime
for ARCH in amd64 arm64; do
APKO_ARCH=$([[ "$ARCH" == "amd64" ]] && echo "x86_64" || echo "aarch64")
mkdir -p context-runtime/build-${ARCH}/runtime
cp build-${APKO_ARCH}/${VARIANT}/rootfs.tar.gz context-runtime/build-${ARCH}/runtime/
mkdir -p context-runtime/dotnet-${ARCH}
cp -r dotnet-${ARCH}/runtime context-runtime/dotnet-${ARCH}/
done
cp dockerfiles/runtime.Dockerfile context-runtime/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-runtime/
- name: Build and push runtime-invariant image
run: |
set -euo pipefail
MAJOR="${{ matrix.major }}"
VERSION="${{ matrix.runtime }}"
VARIANT="runtime-invariant"
mkdir -p context-runtime-invariant
for ARCH in amd64 arm64; do
APKO_ARCH=$([[ "$ARCH" == "amd64" ]] && echo "x86_64" || echo "aarch64")
mkdir -p context-runtime-invariant/build-${ARCH}/runtime-invariant
cp build-${APKO_ARCH}/${VARIANT}/rootfs.tar.gz context-runtime-invariant/build-${ARCH}/runtime-invariant/
mkdir -p context-runtime-invariant/dotnet-${ARCH}
cp -r dotnet-${ARCH}/runtime context-runtime-invariant/dotnet-${ARCH}/
done
cp dockerfiles/runtime-invariant.Dockerfile context-runtime-invariant/Dockerfile
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-runtime-invariant/
- name: Build and push SDK image
run: |
set -euo pipefail
MAJOR="${{ matrix.major }}"
VERSION="${{ matrix.sdk }}"
VARIANT="sdk"
mkdir -p context-sdk
for ARCH in amd64 arm64; do
APKO_ARCH=$([[ "$ARCH" == "amd64" ]] && echo "x86_64" || echo "aarch64")
mkdir -p context-sdk/build-${ARCH}/sdk
cp build-${APKO_ARCH}/${VARIANT}/rootfs.tar.gz context-sdk/build-${ARCH}/sdk/
mkdir -p context-sdk/dotnet-${ARCH}
cp -r dotnet-${ARCH}/sdk context-sdk/dotnet-${ARCH}/
done
cp dockerfiles/sdk.Dockerfile context-sdk/Dockerfile
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-sdk/
- 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 CVE Scan
run: |
MAJOR="${{ matrix.major }}"
for VARIANT in runtime runtime-invariant sdk; do
echo "::group::Scout scan: ${VARIANT}-${MAJOR}"
docker scout cves ${{ env.DOCKER_IMAGE }}:${VARIANT}-${MAJOR}${TAG_SUFFIX} --only-severity critical,high || true
echo "::endgroup::"
done