diff --git a/.gitea/workflows/publish.yaml b/.gitea/workflows/publish.yaml index e4869d4..7173023 100644 --- a/.gitea/workflows/publish.yaml +++ b/.gitea/workflows/publish.yaml @@ -3,7 +3,9 @@ name: Build and Push Base Distro Images on: release: types: [published, prereleased] - workflow_dispatch: + push: + paths: + - '.gitea/workflows/publish.yaml' permissions: contents: read @@ -31,7 +33,7 @@ jobs: - name: Checkout code uses: actions/checkout@v3 - - name: Determine tag + - name: Determine tag type id: tag run: | if [[ "${{ github.event.release.prerelease }}" == "true" ]]; then @@ -64,16 +66,69 @@ jobs: username: ${{ secrets.REGISTRY_USERNAME }} password: ${{ secrets.REGISTRY_PASSWORD }} + - name: Determine upstream version + id: version + run: | + VARIANT="${{ matrix.variant }}" + + case "$VARIANT" in + base|build) + UPSTREAM=$(apko resolve ${{ matrix.config }} 2>&1 | grep -oP 'glibc-\K[0-9]+\.[0-9]+' | head -1 || echo "0.0") + if [ "$UPSTREAM" = "" ] || [ "$UPSTREAM" = "0.0" ]; then + UPSTREAM=$(apko resolve ${{ matrix.config }} 2>&1 | grep -oP 'glibc \(\K[0-9]+\.[0-9]+' | head -1 || echo "2.42") + fi + ;; + dotnet-runtime) + UPSTREAM=$(curl -fsSL "https://dotnetcli.azureedge.net/dotnet/release-metadata/releases-index.json" \ + | jq -r '[."releases-index"[] | select(."support-phase" == "active" or ."support-phase" == "go-live") | ."latest-runtime"] | sort_by(. | split(".") | map(tonumber)) | last') + ;; + dotnet-sdk) + UPSTREAM=$(curl -fsSL "https://dotnetcli.azureedge.net/dotnet/release-metadata/releases-index.json" \ + | jq -r '[."releases-index"[] | select(."support-phase" == "active" or ."support-phase" == "go-live") | ."latest-sdk"] | sort_by(. | split(".") | map(tonumber)) | last') + ;; + flutter-sdk) + UPSTREAM=$(curl -fsSL "https://storage.googleapis.com/flutter_infra_release/releases/releases_linux.json" \ + | jq -r '.current_release.stable as $hash | .releases[] | select(.hash == $hash and .channel == "stable") | .version') + ;; + esac + + echo "upstream=${UPSTREAM}" >> "$GITHUB_OUTPUT" + echo "Upstream version for ${VARIANT}: ${UPSTREAM}" + + # Query DockerHub for existing tags to determine build increment + REPO_NAME="${{ env.IMAGE_NAME }}" + REGISTRY_URL="${{ secrets.REGISTRY_URL }}" + NAMESPACE=$(echo "$REGISTRY_URL" | sed 's|.*://||; s|.*\.io/||; s|/$||') + + EXISTING_TAGS=$(curl -s "https://hub.docker.com/v2/repositories/${NAMESPACE}/${REPO_NAME}/tags?page_size=100&name=${VARIANT}-${UPSTREAM}." \ + | jq -r '.results[]?.name // empty' 2>/dev/null || echo "") + + MAX_BUILD=0 + for tag in $EXISTING_TAGS; do + BUILD_NUM=$(echo "$tag" | grep -oP "\.\K[0-9]+$" || echo "0") + if [ "$BUILD_NUM" -gt "$MAX_BUILD" ] 2>/dev/null; then + MAX_BUILD=$BUILD_NUM + fi + done + + NEXT_BUILD=$((MAX_BUILD + 1)) + VERSION_TAG="${VARIANT}-${UPSTREAM}.${NEXT_BUILD}" + echo "version_tag=${VERSION_TAG}" >> "$GITHUB_OUTPUT" + echo "Next version tag: ${VERSION_TAG}" + - name: Build and push image id: publish run: | - IMAGE_REF=${{ secrets.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ matrix.variant }}-${{ steps.tag.outputs.suffix }} + IMAGE_LATEST=${{ secrets.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ matrix.variant }}-${{ steps.tag.outputs.suffix }} + IMAGE_VERSIONED=${{ secrets.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version_tag }} mkdir -p /tmp/sbom apko publish ${{ matrix.config }} \ --sbom-path /tmp/sbom \ --image-refs /tmp/image-refs.txt \ - "${IMAGE_REF}" - echo "image_ref=${IMAGE_REF}" >> "$GITHUB_OUTPUT" + "${IMAGE_LATEST}" \ + "${IMAGE_VERSIONED}" + echo "image_ref=${IMAGE_LATEST}" >> "$GITHUB_OUTPUT" + echo "image_versioned=${IMAGE_VERSIONED}" >> "$GITHUB_OUTPUT" DIGEST=$(head -1 /tmp/image-refs.txt | sed 's/.*@//') echo "digest=${DIGEST}" >> "$GITHUB_OUTPUT" @@ -82,7 +137,6 @@ jobs: COSIGN_YES: "true" run: | IMAGE_DIGEST="${{ secrets.REGISTRY_URL }}/${{ env.IMAGE_NAME }}@${{ steps.publish.outputs.digest }}" - # Attach SPDX SBOM SBOM_FILE=$(ls /tmp/sbom/*.spdx.json 2>/dev/null | head -1) if [ -n "$SBOM_FILE" ]; then cosign attach sbom --sbom "${SBOM_FILE}" "${IMAGE_DIGEST}" @@ -100,7 +154,7 @@ jobs: jq -n \ --arg type "https://in-toto.io/Statement/v0.1" \ --arg predType "https://slsa.dev/provenance/v0.2" \ - --arg name "${{ steps.publish.outputs.image_ref }}" \ + --arg name "${{ steps.publish.outputs.image_versioned }}" \ --arg sha "$DIGEST_SHA" \ --arg builder "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \ --arg buildType "https://apko.dev/build/v1" \ diff --git a/.gitea/workflows/rebuild.yaml b/.gitea/workflows/rebuild.yaml index 5102246..01ba040 100644 --- a/.gitea/workflows/rebuild.yaml +++ b/.gitea/workflows/rebuild.yaml @@ -58,16 +58,76 @@ jobs: username: ${{ secrets.REGISTRY_USERNAME }} password: ${{ secrets.REGISTRY_PASSWORD }} + - name: Determine upstream version + id: version + run: | + VARIANT="${{ matrix.variant }}" + + case "$VARIANT" in + base|build) + # Use Wolfi glibc version as base version + UPSTREAM=$(apko resolve ${{ matrix.config }} 2>&1 | grep -oP 'glibc-\K[0-9]+\.[0-9]+' | head -1 || echo "0.0") + if [ "$UPSTREAM" = "" ] || [ "$UPSTREAM" = "0.0" ]; then + UPSTREAM=$(apko resolve ${{ matrix.config }} 2>&1 | grep -oP 'glibc \(\K[0-9]+\.[0-9]+' | head -1 || echo "2.42") + fi + ;; + dotnet-runtime) + # Use latest .NET runtime version + UPSTREAM=$(curl -fsSL "https://dotnetcli.azureedge.net/dotnet/release-metadata/releases-index.json" \ + | jq -r '[."releases-index"[] | select(."support-phase" == "active" or ."support-phase" == "go-live") | ."latest-runtime"] | sort_by(. | split(".") | map(tonumber)) | last') + ;; + dotnet-sdk) + # Use latest .NET SDK version + UPSTREAM=$(curl -fsSL "https://dotnetcli.azureedge.net/dotnet/release-metadata/releases-index.json" \ + | jq -r '[."releases-index"[] | select(."support-phase" == "active" or ."support-phase" == "go-live") | ."latest-sdk"] | sort_by(. | split(".") | map(tonumber)) | last') + ;; + flutter-sdk) + # Use latest Flutter stable version + UPSTREAM=$(curl -fsSL "https://storage.googleapis.com/flutter_infra_release/releases/releases_linux.json" \ + | jq -r '.current_release.stable as $hash | .releases[] | select(.hash == $hash and .channel == "stable") | .version') + ;; + esac + + echo "upstream=${UPSTREAM}" >> "$GITHUB_OUTPUT" + echo "Upstream version for ${VARIANT}: ${UPSTREAM}" + + # Query DockerHub for existing tags to determine build increment + REPO_NAME="${{ env.IMAGE_NAME }}" + REGISTRY_URL="${{ secrets.REGISTRY_URL }}" + # Extract namespace/repo from registry URL (e.g. docker.io/svrnty -> svrnty) + NAMESPACE=$(echo "$REGISTRY_URL" | sed 's|.*://||; s|.*\.io/||; s|/$||') + + # Query DockerHub API for tags matching this variant and version + EXISTING_TAGS=$(curl -s "https://hub.docker.com/v2/repositories/${NAMESPACE}/${REPO_NAME}/tags?page_size=100&name=${VARIANT}-${UPSTREAM}." \ + | jq -r '.results[]?.name // empty' 2>/dev/null || echo "") + + # Find highest build number + MAX_BUILD=0 + for tag in $EXISTING_TAGS; do + BUILD_NUM=$(echo "$tag" | grep -oP "\.\K[0-9]+$" || echo "0") + if [ "$BUILD_NUM" -gt "$MAX_BUILD" ] 2>/dev/null; then + MAX_BUILD=$BUILD_NUM + fi + done + + NEXT_BUILD=$((MAX_BUILD + 1)) + VERSION_TAG="${VARIANT}-${UPSTREAM}.${NEXT_BUILD}" + echo "version_tag=${VERSION_TAG}" >> "$GITHUB_OUTPUT" + echo "Next version tag: ${VERSION_TAG}" + - name: Rebuild and push with latest Wolfi packages id: publish run: | - IMAGE_REF=${{ secrets.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ matrix.variant }}-latest + IMAGE_LATEST=${{ secrets.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ matrix.variant }}-latest + IMAGE_VERSIONED=${{ secrets.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version_tag }} mkdir -p /tmp/sbom apko publish ${{ matrix.config }} \ --sbom-path /tmp/sbom \ --image-refs /tmp/image-refs.txt \ - "${IMAGE_REF}" - echo "image_ref=${IMAGE_REF}" >> "$GITHUB_OUTPUT" + "${IMAGE_LATEST}" \ + "${IMAGE_VERSIONED}" + echo "image_ref=${IMAGE_LATEST}" >> "$GITHUB_OUTPUT" + echo "image_versioned=${IMAGE_VERSIONED}" >> "$GITHUB_OUTPUT" DIGEST=$(head -1 /tmp/image-refs.txt | sed 's/.*@//') echo "digest=${DIGEST}" >> "$GITHUB_OUTPUT" @@ -93,7 +153,7 @@ jobs: jq -n \ --arg type "https://in-toto.io/Statement/v0.1" \ --arg predType "https://slsa.dev/provenance/v0.2" \ - --arg name "${{ steps.publish.outputs.image_ref }}" \ + --arg name "${{ steps.publish.outputs.image_versioned }}" \ --arg sha "$DIGEST_SHA" \ --arg builder "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \ --arg buildType "https://apko.dev/build/v1" \ diff --git a/.gitea/workflows/update-check.yaml b/.gitea/workflows/update-check.yaml index 387e9cd..8f2ee16 100644 --- a/.gitea/workflows/update-check.yaml +++ b/.gitea/workflows/update-check.yaml @@ -148,16 +148,68 @@ jobs: username: ${{ secrets.REGISTRY_USERNAME }} password: ${{ secrets.REGISTRY_PASSWORD }} + - name: Determine upstream version + id: version + run: | + VARIANT="${{ matrix.variant }}" + + case "$VARIANT" in + base|build) + UPSTREAM=$(apko resolve ${{ matrix.config }} 2>&1 | grep -oP 'glibc-\K[0-9]+\.[0-9]+' | head -1 || echo "0.0") + if [ "$UPSTREAM" = "" ] || [ "$UPSTREAM" = "0.0" ]; then + UPSTREAM=$(apko resolve ${{ matrix.config }} 2>&1 | grep -oP 'glibc \(\K[0-9]+\.[0-9]+' | head -1 || echo "2.42") + fi + ;; + dotnet-runtime) + UPSTREAM=$(curl -fsSL "https://dotnetcli.azureedge.net/dotnet/release-metadata/releases-index.json" \ + | jq -r '[."releases-index"[] | select(."support-phase" == "active" or ."support-phase" == "go-live") | ."latest-runtime"] | sort_by(. | split(".") | map(tonumber)) | last') + ;; + dotnet-sdk) + UPSTREAM=$(curl -fsSL "https://dotnetcli.azureedge.net/dotnet/release-metadata/releases-index.json" \ + | jq -r '[."releases-index"[] | select(."support-phase" == "active" or ."support-phase" == "go-live") | ."latest-sdk"] | sort_by(. | split(".") | map(tonumber)) | last') + ;; + flutter-sdk) + UPSTREAM=$(curl -fsSL "https://storage.googleapis.com/flutter_infra_release/releases/releases_linux.json" \ + | jq -r '.current_release.stable as $hash | .releases[] | select(.hash == $hash and .channel == "stable") | .version') + ;; + esac + + echo "upstream=${UPSTREAM}" >> "$GITHUB_OUTPUT" + echo "Upstream version for ${VARIANT}: ${UPSTREAM}" + + REPO_NAME="${{ env.IMAGE_NAME }}" + REGISTRY_URL="${{ secrets.REGISTRY_URL }}" + NAMESPACE=$(echo "$REGISTRY_URL" | sed 's|.*://||; s|.*\.io/||; s|/$||') + + EXISTING_TAGS=$(curl -s "https://hub.docker.com/v2/repositories/${NAMESPACE}/${REPO_NAME}/tags?page_size=100&name=${VARIANT}-${UPSTREAM}." \ + | jq -r '.results[]?.name // empty' 2>/dev/null || echo "") + + MAX_BUILD=0 + for tag in $EXISTING_TAGS; do + BUILD_NUM=$(echo "$tag" | grep -oP "\.\K[0-9]+$" || echo "0") + if [ "$BUILD_NUM" -gt "$MAX_BUILD" ] 2>/dev/null; then + MAX_BUILD=$BUILD_NUM + fi + done + + NEXT_BUILD=$((MAX_BUILD + 1)) + VERSION_TAG="${VARIANT}-${UPSTREAM}.${NEXT_BUILD}" + echo "version_tag=${VERSION_TAG}" >> "$GITHUB_OUTPUT" + echo "Next version tag: ${VERSION_TAG}" + - name: Build and push image id: publish run: | - IMAGE_REF=${{ secrets.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ matrix.variant }}-latest + IMAGE_LATEST=${{ secrets.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ matrix.variant }}-latest + IMAGE_VERSIONED=${{ secrets.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version_tag }} mkdir -p /tmp/sbom apko publish ${{ matrix.config }} \ --sbom-path /tmp/sbom \ --image-refs /tmp/image-refs.txt \ - "${IMAGE_REF}" - echo "image_ref=${IMAGE_REF}" >> "$GITHUB_OUTPUT" + "${IMAGE_LATEST}" \ + "${IMAGE_VERSIONED}" + echo "image_ref=${IMAGE_LATEST}" >> "$GITHUB_OUTPUT" + echo "image_versioned=${IMAGE_VERSIONED}" >> "$GITHUB_OUTPUT" DIGEST=$(head -1 /tmp/image-refs.txt | sed 's/.*@//') echo "digest=${DIGEST}" >> "$GITHUB_OUTPUT" @@ -183,7 +235,7 @@ jobs: jq -n \ --arg type "https://in-toto.io/Statement/v0.1" \ --arg predType "https://slsa.dev/provenance/v0.2" \ - --arg name "${{ steps.publish.outputs.image_ref }}" \ + --arg name "${{ steps.publish.outputs.image_versioned }}" \ --arg sha "$DIGEST_SHA" \ --arg builder "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \ --arg buildType "https://apko.dev/build/v1" \