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,164 +38,133 @@ 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: | run: |
set -euo pipefail 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
for VARIANT in runtime runtime-invariant sdk; do
for ARCH in x86_64 aarch64; do
echo "::group::Building apko base: $VARIANT ($ARCH)"
mkdir -p ${{ github.workspace }}/build-${ARCH}/${VARIANT}
docker run --rm \
-v ${{ github.workspace }}/apko:/work:ro \
-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::"
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 - name: Install Docker Scout
run: | run: |
curl -fsSL https://raw.githubusercontent.com/docker/scout-cli/main/install.sh -o install-scout.sh curl -fsSL https://raw.githubusercontent.com/docker/scout-cli/main/install.sh -o install-scout.sh
sh install-scout.sh sh install-scout.sh
- name: Docker Scout CVE Scan - name: Determine tag suffix
id: suffix
run: | run: |
MAJOR="${{ matrix.major }}" 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 VARIANT in runtime runtime-invariant sdk; do
echo "::group::Scout scan: ${VARIANT}-${MAJOR}" for ARCH in x86_64 aarch64; do
docker scout cves ${{ env.DOCKER_IMAGE }}:${VARIANT}-${MAJOR}${TAG_SUFFIX} --only-severity critical,high || true echo "::group::Building apko base: $VARIANT ($ARCH)"
echo "::endgroup::" 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 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' }}