Publish GardenLinux Images #54
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Publish GardenLinux Image | |
| on: | |
| schedule: | |
| # Run weekly on Sundays at 00:00 UTC | |
| - cron: '0 0 * * 0' | |
| workflow_dispatch: | |
| jobs: | |
| check-release: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| latest_version: ${{ steps.get-latest.outputs.latest_version }} | |
| should_publish: ${{ steps.check-published.outputs.should_publish }} | |
| steps: | |
| - name: Get Latest GardenLinux Release | |
| id: get-latest | |
| run: | | |
| LATEST_RELEASE=$(curl -s https://api.github.com/repos/gardenlinux/gardenlinux/releases/latest | jq -r '.tag_name') | |
| echo "Latest GardenLinux release: $LATEST_RELEASE" | |
| echo "latest_version=$LATEST_RELEASE" >> $GITHUB_OUTPUT | |
| - name: Check if Version Already Published | |
| id: check-published | |
| run: | | |
| LATEST_VERSION="${{ steps.get-latest.outputs.latest_version }}" | |
| # Check if the image already exists in ghcr.io by attempting to pull the manifest | |
| if docker manifest inspect ghcr.io/${{ github.repository_owner }}/os-images/gardenlinux-amd64:$LATEST_VERSION > /dev/null 2>&1; then | |
| echo "Version $LATEST_VERSION already published, skipping" | |
| echo "should_publish=false" >> $GITHUB_OUTPUT | |
| else | |
| echo "New version $LATEST_VERSION found, will publish" | |
| echo "should_publish=true" >> $GITHUB_OUTPUT | |
| fi | |
| publish: | |
| needs: check-release | |
| if: needs.check-release.outputs.should_publish == 'true' | |
| permissions: | |
| contents: read | |
| packages: write | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| arch: [ "arm64", "amd64" ] | |
| steps: | |
| - name: Checkout Repository | |
| uses: actions/checkout@v4 | |
| - name: Setup ORAS | |
| uses: oras-project/setup-oras@v1 | |
| - name: Set Version and Artifact URLs | |
| id: read-config | |
| run: | | |
| OS_VERSION="${{ needs.check-release.outputs.latest_version }}" | |
| echo "OS_VERSION=$OS_VERSION" >> $GITHUB_ENV | |
| # Fetch release assets to find the correct artifact filenames | |
| ASSETS=$(curl -s "https://api.github.com/repos/gardenlinux/gardenlinux/releases/tags/$OS_VERSION" | jq -r '.assets[].name') | |
| # Find KVM artifact for this architecture | |
| KVM_ASSET=$(echo "$ASSETS" | grep -E "^kvm-gardener_prod-${{ matrix.arch }}-.*\.tar\.xz$" | head -1) | |
| if [ -z "$KVM_ASSET" ]; then | |
| echo "Error: Could not find KVM artifact for ${{ matrix.arch }}" | |
| exit 1 | |
| fi | |
| GARDENLINUX_KVM_ARTIFACT_URL="https://github.com/gardenlinux/gardenlinux/releases/download/$OS_VERSION/$KVM_ASSET" | |
| echo "GARDENLINUX_KVM_ARTIFACT_URL=$GARDENLINUX_KVM_ARTIFACT_URL" >> $GITHUB_ENV | |
| # Find Metal PXE artifact for this architecture (optional - may not exist for arm64) | |
| METAL_ASSET=$(echo "$ASSETS" | grep -E "^metal-gardener_prod_pxe-${{ matrix.arch }}-.*\.tar\.xz$" | head -1) | |
| if [ -z "$METAL_ASSET" ]; then | |
| echo "Warning: Could not find Metal artifact for ${{ matrix.arch }}, skipping Metal artifacts" | |
| echo "HAS_METAL_ARTIFACT=false" >> $GITHUB_ENV | |
| else | |
| GARDENLINUX_METAL_ARTIFACT_URL="https://github.com/gardenlinux/gardenlinux/releases/download/$OS_VERSION/$METAL_ASSET" | |
| echo "GARDENLINUX_METAL_ARTIFACT_URL=$GARDENLINUX_METAL_ARTIFACT_URL" >> $GITHUB_ENV | |
| echo "HAS_METAL_ARTIFACT=true" >> $GITHUB_ENV | |
| fi | |
| echo "KVM URL: $GARDENLINUX_KVM_ARTIFACT_URL" | |
| if [ -n "$METAL_ASSET" ]; then | |
| echo "Metal URL: $GARDENLINUX_METAL_ARTIFACT_URL" | |
| else | |
| echo "Metal URL: (not available for ${{ matrix.arch }})" | |
| fi | |
| - name: Download and Extract Gardenlinux KVM Artifact | |
| run: | | |
| curl -L ${{ env.GARDENLINUX_KVM_ARTIFACT_URL }} -o gardenlinux.tar.xz | |
| tar -xf gardenlinux.tar.xz | |
| echo "Extracted contents:" | |
| ls -la | |
| - name: Download and Extract Gardenlinux Metal Artifact | |
| if: env.HAS_METAL_ARTIFACT == 'true' | |
| run: | | |
| # Download the outer tarball | |
| curl -L ${{ env.GARDENLINUX_METAL_ARTIFACT_URL }} -o gardenlinux-metal.tar.xz | |
| tar -xf gardenlinux-metal.tar.xz | |
| # Extract the nested tarball to get the initrd, vmlinuz, and root.squashfs files | |
| NESTED_TARBALL=$(find . -name "*pxe.tar.gz") | |
| tar -xzf $NESTED_TARBALL | |
| - name: Create Config JSON | |
| run: | | |
| if [ "${{ matrix.arch }}" == "arm64" ]; then | |
| echo "{\"commandLine\": \"gl.url=/dev/disk/by-id/virtio-machineboot gl.live=1 gl.ovl=/:tmpfs console=tty0 console=ttyAMA0,115200 earlyprintk=ttyAMA0,115200 consoleblank=0 cgroup_enable=memory swapaccount=1 ignition.firstboot=1 ignition.platform.id=qemu\", \"os-release\": \"$OS_VERSION\", \"arch\": \"${{ matrix.arch }}\"}" > config.json | |
| fi | |
| if [ "${{ matrix.arch }}" == "amd64" ]; then | |
| echo "{\"commandLine\": \"gl.url=/dev/disk/by-id/virtio-machineboot gl.live=1 gl.ovl=/:tmpfs console=tty0 console=ttyS0,115200 earlyprintk=ttyS0,115200 consoleblank=0 cgroup_enable=memory swapaccount=1 ignition.firstboot=1 ignition.platform.id=qemu\", \"os-release\": \"$OS_VERSION\", \"arch\": \"${{ matrix.arch }}\"}" > config.json | |
| fi | |
| - name: Login to GitHub Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Push Image with ORAS (Version Tag) | |
| run: | | |
| # Find the .raw file dynamically (handles varying folder structures) | |
| KVM_RAW_FILE=$(find . -name "*.raw" -type f | head -1) | |
| if [ -z "$KVM_RAW_FILE" ]; then | |
| echo "Error: Could not find .raw file after extraction" | |
| exit 1 | |
| fi | |
| echo "Found KVM raw file: $KVM_RAW_FILE" | |
| # Build the oras push command with required KVM artifact | |
| ORAS_ARGS="$KVM_RAW_FILE:application/vnd.ironcore.image.rootfs.v1alpha1.rootfs" | |
| # Add Metal artifacts if available | |
| if [ "${{ env.HAS_METAL_ARTIFACT }}" == "true" ]; then | |
| ORAS_ARGS="$ORAS_ARGS root.squashfs:application/vnd.ironcore.image.squashfs.v1alpha1.squashfs" | |
| ORAS_ARGS="$ORAS_ARGS initrd:application/vnd.ironcore.image.initramfs.v1alpha1.initramfs" | |
| ORAS_ARGS="$ORAS_ARGS vmlinuz:application/vnd.ironcore.image.vmlinuz.v1alpha1.vmlinuz" | |
| fi | |
| oras push ghcr.io/${{ github.repository_owner }}/os-images/gardenlinux-${{ matrix.arch }}:$OS_VERSION \ | |
| $ORAS_ARGS \ | |
| --config config.json:application/vnd.ironcore.image.config.v1alpha1+json | |
| - name: Push Image with ORAS (Latest Tag) | |
| run: | | |
| oras tag ghcr.io/${{ github.repository_owner }}/os-images/gardenlinux-${{ matrix.arch }}:$OS_VERSION latest |