Compare commits

..

4 Commits
test-1 ... main

Author SHA1 Message Date
742aef8983 Merge discover and build into single job with shell loop
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
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
1f3d6ce8ce Fix apko tarball extraction with --strip-components=1
Some checks failed
Build and Push .NET Images / discover (release) Successful in 6s
Build and Push .NET Images / build (release) Failing after 9m40s
The binary is nested under apko_VERSION_linux_amd64/apko in the
tarball, not at the root.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 17:53:20 -05:00
7cf9b1b914 Install apko as binary instead of running via Docker
Some checks failed
Build and Push .NET Images / discover (release) Successful in 2s
Build and Push .NET Images / build (release) Failing after 9m32s
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
f5c1c7aadc Fix apko build by removing read-only mount on work directory
Some checks failed
Build and Push .NET Images / discover (release) Successful in 2s
Build and Push .NET Images / build (release) Failing after 11m34s
apko now writes SBOM files next to the config YAML, so the work
directory must be writable.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 17:27:03 -05:00
2 changed files with 127 additions and 210 deletions

View File

@ -18,64 +18,8 @@ env:
RELEASES_INDEX_URL: https://dotnetcli.azureedge.net/dotnet/release-metadata/releases-index.json RELEASES_INDEX_URL: https://dotnetcli.azureedge.net/dotnet/release-metadata/releases-index.json
jobs: 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: build:
runs-on: ubuntu-latest 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: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v4
@ -94,30 +38,59 @@ jobs:
username: ${{ secrets.REGISTRY_USERNAME }} username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }} password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Build apko base images - 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: | run: |
set -euo pipefail 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 VARIANT in runtime runtime-invariant sdk; do
for ARCH in x86_64 aarch64; do for ARCH in x86_64 aarch64; do
echo "::group::Building apko base: $VARIANT ($ARCH)" echo "::group::Building apko base: $VARIANT ($ARCH)"
mkdir -p ${{ github.workspace }}/build-${ARCH}/${VARIANT} mkdir -p build-${ARCH}/${VARIANT}
docker run --rm \ apko build --arch $ARCH \
-v ${{ github.workspace }}/apko:/work:ro \ apko/${VARIANT}.yaml ${VARIANT}:latest build-${ARCH}/${VARIANT}/rootfs.tar.gz
-v ${{ github.workspace }}/build-${ARCH}/${VARIANT}:/output \
cgr.dev/chainguard/apko build \
--arch $ARCH /work/${VARIANT}.yaml ${VARIANT}:latest /output/rootfs.tar.gz
echo "::endgroup::" echo "::endgroup::"
done done
done done
- name: Download .NET binaries # Iterate over each supported .NET version
run: | echo "$SUPPORTED" | jq -r '.[] | "\(.["channel-version"] | split(".")[0]) \(.["latest-runtime"]) \(.["latest-sdk"]) \(.["release-type"])"' | \
set -euo pipefail while read -r MAJOR RUNTIME SDK TYPE; do
echo "============================================="
RUNTIME_VERSION="${{ matrix.runtime }}" echo "Building .NET $MAJOR: runtime=$RUNTIME sdk=$SDK type=$TYPE"
SDK_VERSION="${{ matrix.sdk }}" echo "============================================="
# Download .NET binaries
for ARCH in x86_64 aarch64; do for ARCH in x86_64 aarch64; do
if [ "$ARCH" = "x86_64" ]; then if [ "$ARCH" = "x86_64" ]; then
DOTNET_ARCH="x64" DOTNET_ARCH="x64"
@ -127,41 +100,45 @@ jobs:
PLATFORM_ARCH="arm64" PLATFORM_ARCH="arm64"
fi fi
# Download ASP.NET Core runtime (for runtime and runtime-invariant) echo "::group::Downloading ASP.NET Core runtime $RUNTIME ($DOTNET_ARCH)"
echo "::group::Downloading ASP.NET Core runtime $RUNTIME_VERSION ($DOTNET_ARCH)"
mkdir -p dotnet-${PLATFORM_ARCH}/runtime 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" \ 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 -o /tmp/aspnet-runtime-${PLATFORM_ARCH}.tar.gz
tar xf /tmp/aspnet-runtime-${PLATFORM_ARCH}.tar.gz -C dotnet-${PLATFORM_ARCH}/runtime tar xf /tmp/aspnet-runtime-${PLATFORM_ARCH}.tar.gz -C dotnet-${PLATFORM_ARCH}/runtime
echo "::endgroup::" echo "::endgroup::"
# Download .NET SDK echo "::group::Downloading .NET SDK $SDK ($DOTNET_ARCH)"
echo "::group::Downloading .NET SDK $SDK_VERSION ($DOTNET_ARCH)"
mkdir -p dotnet-${PLATFORM_ARCH}/sdk 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" \ 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 -o /tmp/dotnet-sdk-${PLATFORM_ARCH}.tar.gz
tar xf /tmp/dotnet-sdk-${PLATFORM_ARCH}.tar.gz -C dotnet-${PLATFORM_ARCH}/sdk tar xf /tmp/dotnet-sdk-${PLATFORM_ARCH}.tar.gz -C dotnet-${PLATFORM_ARCH}/sdk
echo "::endgroup::" echo "::endgroup::"
done done
- name: Build and push runtime image # Build and push each variant
run: | for VARIANT in runtime runtime-invariant sdk; do
set -euo pipefail if [ "$VARIANT" = "sdk" ]; then
VERSION="$SDK"
DOTNET_DIR="sdk"
else
VERSION="$RUNTIME"
DOTNET_DIR="runtime"
fi
MAJOR="${{ matrix.major }}" echo "::group::Building $VARIANT-$MAJOR"
VERSION="${{ matrix.runtime }}"
VARIANT="runtime"
# Prepare build context # Prepare build context
mkdir -p context-runtime CONTEXT="context-${VARIANT}-${MAJOR}"
rm -rf "$CONTEXT"
mkdir -p "$CONTEXT"
for ARCH in amd64 arm64; do for ARCH in amd64 arm64; do
APKO_ARCH=$([[ "$ARCH" == "amd64" ]] && echo "x86_64" || echo "aarch64") APKO_ARCH=$([[ "$ARCH" == "amd64" ]] && echo "x86_64" || echo "aarch64")
mkdir -p context-runtime/build-${ARCH}/runtime mkdir -p "$CONTEXT/build-${ARCH}/${VARIANT}"
cp build-${APKO_ARCH}/${VARIANT}/rootfs.tar.gz context-runtime/build-${ARCH}/runtime/ cp "build-${APKO_ARCH}/${VARIANT}/rootfs.tar.gz" "$CONTEXT/build-${ARCH}/${VARIANT}/"
mkdir -p context-runtime/dotnet-${ARCH} mkdir -p "$CONTEXT/dotnet-${ARCH}"
cp -r dotnet-${ARCH}/runtime context-runtime/dotnet-${ARCH}/ cp -r "dotnet-${ARCH}/${DOTNET_DIR}" "$CONTEXT/dotnet-${ARCH}/"
done done
cp dockerfiles/runtime.Dockerfile context-runtime/Dockerfile cp "dockerfiles/${VARIANT}.Dockerfile" "$CONTEXT/Dockerfile"
# Determine tags # Determine tags
TAGS="-t $DOCKER_IMAGE:${VARIANT}-${MAJOR}${TAG_SUFFIX} -t $DOCKER_IMAGE:${VARIANT}-${VERSION}${TAG_SUFFIX}" TAGS="-t $DOCKER_IMAGE:${VARIANT}-${MAJOR}${TAG_SUFFIX} -t $DOCKER_IMAGE:${VARIANT}-${VERSION}${TAG_SUFFIX}"
@ -176,82 +153,18 @@ jobs:
docker buildx build --platform linux/amd64,linux/arm64 --push \ docker buildx build --platform linux/amd64,linux/arm64 --push \
--sbom=true --provenance=mode=max \ --sbom=true --provenance=mode=max \
$TAGS \ $TAGS \
context-runtime/ "$CONTEXT/"
- 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::" echo "::endgroup::"
done 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

View File

@ -74,12 +74,16 @@ jobs:
echo "lts_major=$LTS_MAJOR" >> $GITHUB_OUTPUT echo "lts_major=$LTS_MAJOR" >> $GITHUB_OUTPUT
echo "lts_runtime=$LTS_RUNTIME" >> $GITHUB_OUTPUT echo "lts_runtime=$LTS_RUNTIME" >> $GITHUB_OUTPUT
- 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: Build test image (${{ matrix.arch }}) - name: Build test image (${{ matrix.arch }})
run: | run: |
# Build apko base # Build apko base
docker run --rm -v ${{ github.workspace }}/apko:/work cgr.dev/chainguard/apko build \ apko build --arch ${{ matrix.arch == 'amd64' && 'x86_64' || 'aarch64' }} \
--arch ${{ matrix.arch == 'amd64' && 'x86_64' || 'aarch64' }} \ apko/runtime.yaml runtime:latest /tmp/rootfs.tar.gz
/work/runtime.yaml runtime:latest /tmp/rootfs.tar.gz
# Download .NET runtime # Download .NET runtime
DOTNET_ARCH=${{ matrix.arch == 'amd64' && 'x64' || 'arm64' }} DOTNET_ARCH=${{ matrix.arch == 'amd64' && 'x64' || 'arm64' }}