From 3a727f31fa76ab146f09f63f78110dd5dbf653b6 Mon Sep 17 00:00:00 2001 From: Alice Frosi Date: Tue, 14 Jul 2026 14:30:53 +0000 Subject: [PATCH 1/8] gha: merge composefs integration tests into integration-tests.yml Simplify the GHA job and merge everything in the integration-test.yml to avoid duplication. Signed-off-by: Alice Frosi --- .../workflows/integration-tests-composefs.yml | 58 ------------------- .github/workflows/integration-tests.yml | 46 +++++++++++++++ 2 files changed, 46 insertions(+), 58 deletions(-) delete mode 100644 .github/workflows/integration-tests-composefs.yml diff --git a/.github/workflows/integration-tests-composefs.yml b/.github/workflows/integration-tests-composefs.yml deleted file mode 100644 index be2c541..0000000 --- a/.github/workflows/integration-tests-composefs.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: Integration Tests (composefs) - -on: - push: - branches: [main] - pull_request: - branches: [main] - -concurrency: - group: integration-composefs-${{ github.head_ref || github.ref }} - cancel-in-progress: true - -env: - BINK_IMAGES: >- - ghcr.io/bootc-dev/bink/cluster:latest - ghcr.io/bootc-dev/bink/node:v1.35-fedora-44-disk-composefs - ghcr.io/bootc-dev/bink/dns:latest - EXTERNAL_IMAGES: >- - quay.io/libpod/busybox:latest - -jobs: - integration-tests-composefs: - runs-on: ubuntu-latest - timeout-minutes: 120 - - steps: - - name: Checkout code - uses: actions/checkout@v7 - - - name: Setup bink - uses: ./.github/actions/setup-bink - with: - cache-key-prefix: composefs - - - name: Run composefs integration tests - run: sudo make test-integration-composefs - timeout-minutes: 90 - env: - CONTAINER_HOST: unix:///run/podman/podman.sock - BINK_NODE_IMAGE: ghcr.io/bootc-dev/bink/node:v1.35-fedora-44-disk-composefs - - - name: Collect logs - if: failure() - run: .github/collect-logs.sh - - - name: Upload logs - if: failure() - uses: actions/upload-artifact@v7 - with: - name: test-logs-composefs - path: /tmp/bink-logs/ - - - name: Cleanup test clusters - if: always() - run: | - sudo podman ps -a --filter "name=k8s-test-bink" --format '{{.Names}}' | \ - xargs -r sudo podman rm -f 2>/dev/null || true - sudo podman volume prune -f 2>/dev/null || true diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 4601135..2230cea 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -73,6 +73,52 @@ jobs: xargs -r sudo podman rm -f 2>/dev/null || true sudo podman volume prune -f 2>/dev/null || true + integration-tests-composefs: + runs-on: ubuntu-latest + timeout-minutes: 120 + + env: + BINK_IMAGES: >- + ghcr.io/bootc-dev/bink/cluster:latest + ghcr.io/bootc-dev/bink/node:v1.35-fedora-44-disk-composefs + ghcr.io/bootc-dev/bink/dns:latest + EXTERNAL_IMAGES: >- + quay.io/libpod/busybox:latest + + steps: + - name: Checkout code + uses: actions/checkout@v7 + + - name: Setup bink + uses: ./.github/actions/setup-bink + with: + cache-key-prefix: composefs + + - name: Run composefs integration tests + run: sudo make test-integration-composefs + timeout-minutes: 90 + env: + CONTAINER_HOST: unix:///run/podman/podman.sock + BINK_NODE_IMAGE: ghcr.io/bootc-dev/bink/node:v1.35-fedora-44-disk-composefs + + - name: Collect logs + if: failure() + run: .github/collect-logs.sh + + - name: Upload logs + if: failure() + uses: actions/upload-artifact@v7 + with: + name: test-logs-composefs + path: /tmp/bink-logs/ + + - name: Cleanup test clusters + if: always() + run: | + sudo podman ps -a --filter "name=k8s-test-bink" --format '{{.Names}}' | \ + xargs -r sudo podman rm -f 2>/dev/null || true + sudo podman volume prune -f 2>/dev/null || true + integration-tests-k8s-versions: needs: supported-versions runs-on: ubuntu-latest From ac646da15756fb148f499d8d584a6c6fdcde72de Mon Sep 17 00:00:00 2001 From: Alice Frosi Date: Tue, 14 Jul 2026 14:37:08 +0000 Subject: [PATCH 2/8] gha: refactor supported-versions to output all and non-default versions Change the support version to print once all the version and once the non default versions. The non-default version is used by the k8s-versions integration tests which run a subset of the tests. The all-versions will be used by the node image build matrix job in the next commit. Assisted-by: AI Signed-off-by: Alice Frosi --- .github/workflows/integration-tests.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 2230cea..ddf2be3 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -24,17 +24,18 @@ jobs: supported-versions: runs-on: ubuntu-latest outputs: - matrix: ${{ steps.set-matrix.outputs.matrix }} + all-versions: ${{ steps.set-matrix.outputs.all-versions }} + non-default-versions: ${{ steps.set-matrix.outputs.non-default-versions }} steps: - name: Get supported Kubernetes versions id: set-matrix run: | DEFAULT="1.35" - # Exclude the default version — the integration-tests job already runs the full suite for it - MATRIX=$(curl -s https://endoflife.date/api/kubernetes.json | \ - jq -c --arg default "$DEFAULT" \ - '[.[] | select(.eol > (now | strftime("%Y-%m-%d"))) | .cycle][:3] | map(select(. != $default))') - echo "matrix=${MATRIX}" >> "$GITHUB_OUTPUT" + ALL=$(curl -s https://endoflife.date/api/kubernetes.json | \ + jq -c '[.[] | select(.eol > (now | strftime("%Y-%m-%d"))) | .cycle][:3]') + NON_DEFAULT=$(echo "$ALL" | jq -c --arg default "$DEFAULT" 'map(select(. != $default))') + echo "all-versions=${ALL}" >> "$GITHUB_OUTPUT" + echo "non-default-versions=${NON_DEFAULT}" >> "$GITHUB_OUTPUT" integration-tests: runs-on: ubuntu-latest @@ -126,7 +127,7 @@ jobs: strategy: fail-fast: false matrix: - kube-minor: ${{ fromJson(needs.supported-versions.outputs.matrix) }} + kube-minor: ${{ fromJson(needs.supported-versions.outputs.non-default-versions) }} env: BINK_NODE_IMAGE: ghcr.io/bootc-dev/bink/node:v${{ matrix.kube-minor }}-fedora-44-disk From 0f7dd3bc6ae489d287d2e71fded6020d594a2155 Mon Sep 17 00:00:00 2001 From: Alice Frosi Date: Tue, 14 Jul 2026 14:40:13 +0000 Subject: [PATCH 3/8] gha: move node image build into integration-tests workflow Detect changes under node-images/fedora/** to conditionally trigger node image builds as part of the integration-tests workflow. Remove the standalone build-node-image.yaml. Build natively on the ubuntu runner instead of inside a Fedora container, avoiding the need to keep the container image version in sync. Assisted-by: AI Signed-off-by: Alice Frosi --- .github/workflows/build-node-image.yaml | 134 ------------------------ .github/workflows/integration-tests.yml | 98 +++++++++++++++++ 2 files changed, 98 insertions(+), 134 deletions(-) delete mode 100644 .github/workflows/build-node-image.yaml diff --git a/.github/workflows/build-node-image.yaml b/.github/workflows/build-node-image.yaml deleted file mode 100644 index ef16228..0000000 --- a/.github/workflows/build-node-image.yaml +++ /dev/null @@ -1,134 +0,0 @@ -name: Build and Push Node Image - -on: - push: - branches: [main] - paths: - - "node-images/fedora/**" - pull_request: - paths: - - "node-images/fedora/**" - workflow_dispatch: - inputs: - push: - description: "Push image to registry" - required: false - default: "false" - type: boolean - -env: - PUSH_REGISTRY: ghcr.io/bootc-dev/bink - PUSH_IMAGE: node - -jobs: - supported-versions: - runs-on: ubuntu-latest - outputs: - matrix: ${{ steps.set-matrix.outputs.matrix }} - steps: - - name: Get supported Kubernetes versions - id: set-matrix - run: | - MATRIX=$(curl -s https://endoflife.date/api/kubernetes.json | \ - jq -c '[.[] | select(.eol > (now | strftime("%Y-%m-%d"))) | .cycle][:3]') - echo "matrix=${MATRIX}" >> "$GITHUB_OUTPUT" - - build: - needs: supported-versions - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - kube-minor: ${{ fromJson(needs.supported-versions.outputs.matrix) }} - permissions: - contents: read - packages: write - container: - image: quay.io/fedora/fedora:44 - options: --privileged --device /dev/kvm -v /var/lib/containers - steps: - - name: Install dependencies - run: dnf install -y --setopt=install_weak_deps=0 podman git make - - - name: Checkout - uses: actions/checkout@v7 - - - name: Log in to GHCR - if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.push) - run: podman login -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} ghcr.io - - - name: Build bootc image - working-directory: node-images/fedora - run: make build-bootc-image KUBE_MINOR=${{ matrix.kube-minor }} - - - name: Determine image tag - id: meta - working-directory: node-images/fedora - run: | - TAG=$(make -s print-image-tag KUBE_MINOR=${{ matrix.kube-minor }}) - echo "tag=${TAG}" >> "$GITHUB_OUTPUT" - echo "Image tag: ${TAG}" - - - name: Push bootc image - id: push-bootc - if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.push) - working-directory: node-images/fedora - run: | - TAG=${{ steps.meta.outputs.tag }} - BOOTC_SRC=$(make -s print-bootc-image KUBE_MINOR=${{ matrix.kube-minor }}) - PUSH_DEST=${{ env.PUSH_REGISTRY }}/${{ env.PUSH_IMAGE }} - - podman tag ${BOOTC_SRC} ${PUSH_DEST}:${TAG} - podman push --digestfile=/tmp/bootc-digest ${PUSH_DEST}:${TAG} - - BOOTC_DIGEST=$(cat /tmp/bootc-digest) - echo "digest=${BOOTC_DIGEST}" >> "$GITHUB_OUTPUT" - echo "Bootc image pushed with digest: ${BOOTC_DIGEST}" - echo "Clean up local images" - podman rmi -f ${BOOTC_SRC} ${PUSH_DEST}:${TAG} - echo "push_dest=${PUSH_DEST}:${TAG}" >> "$GITHUB_OUTPUT" - - - name: Build disk image - working-directory: node-images/fedora - run: | - BOOTC_DIGEST="${{ steps.push-bootc.outputs.digest }}" - PUSH_DEST="${{ steps.push-bootc.outputs.push_dest }}" - if [ -n "${BOOTC_DIGEST}" ] && [ -n "${PUSH_DEST}" ]; then - podman pull "${PUSH_DEST}" - make build-disk-image KUBE_MINOR=${{ matrix.kube-minor }} BOOTC_IMAGE="${PUSH_DEST}" BOOTC_DIGEST="${BOOTC_DIGEST}" - else - make build-disk-image KUBE_MINOR=${{ matrix.kube-minor }} - fi - - - name: Push disk image - if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.push) - working-directory: node-images/fedora - run: | - TAG=${{ steps.meta.outputs.tag }} - DISK_SRC=$(make -s print-node-image KUBE_MINOR=${{ matrix.kube-minor }}) - PUSH_DEST=${{ env.PUSH_REGISTRY }}/${{ env.PUSH_IMAGE }} - - podman tag ${DISK_SRC} ${PUSH_DEST}:${TAG}-disk - podman push ${PUSH_DEST}:${TAG}-disk - - - name: Build composefs disk image - working-directory: node-images/fedora - run: | - BOOTC_DIGEST="${{ steps.push-bootc.outputs.digest }}" - PUSH_DEST="${{ steps.push-bootc.outputs.push_dest }}" - if [ -n "${BOOTC_DIGEST}" ] && [ -n "${PUSH_DEST}" ]; then - make build-disk-image-composefs KUBE_MINOR=${{ matrix.kube-minor }} BOOTC_IMAGE="${PUSH_DEST}" BOOTC_DIGEST="${BOOTC_DIGEST}" - else - make build-disk-image-composefs KUBE_MINOR=${{ matrix.kube-minor }} - fi - - - name: Push composefs disk image - if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.push) - working-directory: node-images/fedora - run: | - TAG=${{ steps.meta.outputs.tag }} - DISK_SRC=$(make -s print-node-image-composefs KUBE_MINOR=${{ matrix.kube-minor }}) - PUSH_DEST=${{ env.PUSH_REGISTRY }}/${{ env.PUSH_IMAGE }} - - podman tag ${DISK_SRC} ${PUSH_DEST}:${TAG}-disk-composefs - podman push ${PUSH_DEST}:${TAG}-disk-composefs diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index ddf2be3..b7f1da1 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -5,6 +5,18 @@ on: branches: [main] pull_request: branches: [main] + workflow_dispatch: + inputs: + build-node-images: + description: "Force building node images" + required: false + default: false + type: boolean + push-node-images: + description: "Push built node images to GHCR" + required: false + default: false + type: boolean concurrency: group: integration-${{ github.head_ref || github.ref }} @@ -19,8 +31,26 @@ env: docker.io/library/registry:2 docker.io/library/haproxy:lts-alpine quay.io/libpod/busybox:latest + PUSH_REGISTRY: ghcr.io/bootc-dev/bink + PUSH_IMAGE: node jobs: + changes: + runs-on: ubuntu-latest + outputs: + node-images: ${{ steps.filter.outputs.node-images }} + steps: + - name: Checkout code + uses: actions/checkout@v7 + + - name: Detect changed paths + id: filter + uses: dorny/paths-filter@v3 + with: + filters: | + node-images: + - 'node-images/fedora/**' + supported-versions: runs-on: ubuntu-latest outputs: @@ -37,6 +67,74 @@ jobs: echo "all-versions=${ALL}" >> "$GITHUB_OUTPUT" echo "non-default-versions=${NON_DEFAULT}" >> "$GITHUB_OUTPUT" + build-node-images: + needs: [changes, supported-versions] + if: needs.changes.outputs.node-images == 'true' || inputs.build-node-images == true + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + kube-minor: ${{ fromJson(needs.supported-versions.outputs.all-versions) }} + steps: + - name: Checkout + uses: actions/checkout@v7 + + - name: Build bootc image + working-directory: node-images/fedora + run: sudo make build-bootc-image KUBE_MINOR=${{ matrix.kube-minor }} + + - name: Determine image tag + id: meta + working-directory: node-images/fedora + run: | + TAG=$(make -s print-image-tag KUBE_MINOR=${{ matrix.kube-minor }}) + echo "tag=${TAG}" >> "$GITHUB_OUTPUT" + echo "Image tag: ${TAG}" + + - name: Save bootc image + working-directory: node-images/fedora + run: | + BOOTC_SRC=$(make -s print-bootc-image KUBE_MINOR=${{ matrix.kube-minor }}) + sudo podman save -o ${{ github.workspace }}/bootc-image.tar ${BOOTC_SRC} + + - name: Upload bootc image artifact + uses: actions/upload-artifact@v7 + with: + name: bootc-image-${{ matrix.kube-minor }} + path: bootc-image.tar + + - name: Build disk image + working-directory: node-images/fedora + run: sudo make build-disk-image KUBE_MINOR=${{ matrix.kube-minor }} + + - name: Save disk image + working-directory: node-images/fedora + run: | + DISK_SRC=$(make -s print-node-image KUBE_MINOR=${{ matrix.kube-minor }}) + sudo podman save -o ${{ github.workspace }}/node-image.tar ${DISK_SRC} + + - name: Upload disk image artifact + uses: actions/upload-artifact@v7 + with: + name: node-image-${{ matrix.kube-minor }} + path: node-image.tar + + - name: Build composefs disk image + working-directory: node-images/fedora + run: sudo make build-disk-image-composefs KUBE_MINOR=${{ matrix.kube-minor }} + + - name: Save composefs disk image + working-directory: node-images/fedora + run: | + DISK_SRC=$(make -s print-node-image-composefs KUBE_MINOR=${{ matrix.kube-minor }}) + sudo podman save -o ${{ github.workspace }}/node-image-composefs.tar ${DISK_SRC} + + - name: Upload composefs disk image artifact + uses: actions/upload-artifact@v7 + with: + name: node-image-composefs-${{ matrix.kube-minor }} + path: node-image-composefs.tar + integration-tests: runs-on: ubuntu-latest timeout-minutes: 120 From 91fdfb742b09014eff30ada83a604e7c5e884ed1 Mon Sep 17 00:00:00 2001 From: Alice Frosi Date: Tue, 14 Jul 2026 15:09:52 +0000 Subject: [PATCH 4/8] gha: add node-image input to setup-bink action Allows callers to pass a node image to pull. When omitted (image already loaded locally from artifact), setup-bink skips pulling it. Assisted-by: AI Signed-off-by: Alice Frosi --- .github/actions/setup-bink/action.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/actions/setup-bink/action.yml b/.github/actions/setup-bink/action.yml index b97513e..a0d7259 100644 --- a/.github/actions/setup-bink/action.yml +++ b/.github/actions/setup-bink/action.yml @@ -5,10 +5,19 @@ inputs: cache-key-prefix: description: Prefix for the image cache key required: true + node-image: + description: Node image to pull (omit if already loaded locally) + required: false + default: '' runs: using: composite steps: + - name: Add node image to pull list + if: inputs.node-image != '' + shell: bash + run: echo "BINK_IMAGES=$BINK_IMAGES ${{ inputs.node-image }}" >> "$GITHUB_ENV" + - name: Configure kernel for nested containers shell: bash run: | From 784a1c8c064b88705cb20e3b491c4ee89dbd48db Mon Sep 17 00:00:00 2001 From: Alice Frosi Date: Tue, 14 Jul 2026 15:20:20 +0000 Subject: [PATCH 5/8] gha: consolidate BINK_IMAGES and EXTERNAL_IMAGES at workflow level Remove per-job overrides and the node image from BINK_IMAGES. The node image will be added dynamically by setup-bink via the node-image input. Assisted-by: AI Signed-off-by: Alice Frosi --- .github/workflows/integration-tests.yml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index b7f1da1..dec9624 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -25,7 +25,6 @@ concurrency: env: BINK_IMAGES: >- ghcr.io/bootc-dev/bink/cluster:latest - ghcr.io/bootc-dev/bink/node:v1.35-fedora-44-disk ghcr.io/bootc-dev/bink/dns:latest EXTERNAL_IMAGES: >- docker.io/library/registry:2 @@ -176,14 +175,6 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 120 - env: - BINK_IMAGES: >- - ghcr.io/bootc-dev/bink/cluster:latest - ghcr.io/bootc-dev/bink/node:v1.35-fedora-44-disk-composefs - ghcr.io/bootc-dev/bink/dns:latest - EXTERNAL_IMAGES: >- - quay.io/libpod/busybox:latest - steps: - name: Checkout code uses: actions/checkout@v7 @@ -229,10 +220,6 @@ jobs: env: BINK_NODE_IMAGE: ghcr.io/bootc-dev/bink/node:v${{ matrix.kube-minor }}-fedora-44-disk - BINK_IMAGES: >- - ghcr.io/bootc-dev/bink/cluster:latest - ghcr.io/bootc-dev/bink/node:v${{ matrix.kube-minor }}-fedora-44-disk - ghcr.io/bootc-dev/bink/dns:latest steps: - name: Checkout code From 12424b30d69ccd0994b13d90f97bffb3223b052d Mon Sep 17 00:00:00 2001 From: Alice Frosi Date: Tue, 14 Jul 2026 15:26:29 +0000 Subject: [PATCH 6/8] gha: wire test jobs to use locally built node images When build-node-images runs, test jobs download and load the artifact instead of pulling from GHCR. When skipped, setup-bink pulls the published image via the node-image input. Assisted-by: AI Signed-off-by: Alice Frosi --- .github/workflows/integration-tests.yml | 45 ++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index dec9624..889cb0b 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -135,6 +135,9 @@ jobs: path: node-image-composefs.tar integration-tests: + needs: [changes, build-node-images] + # Run when build-node-images is skipped (no node image changes) or succeeded, but not when it failed + if: ${{ !cancelled() && needs.build-node-images.result != 'failure' }} runs-on: ubuntu-latest timeout-minutes: 120 @@ -142,10 +145,23 @@ jobs: - name: Checkout code uses: actions/checkout@v7 + - name: Download node image artifact + if: needs.build-node-images.result == 'success' + uses: actions/download-artifact@v7 + with: + name: node-image-1.35 + + - name: Load node image + if: needs.build-node-images.result == 'success' + run: sudo podman load -i node-image.tar + - name: Setup bink uses: ./.github/actions/setup-bink with: cache-key-prefix: integration + # If the build of the image was skipped then we use the default one which needs to be pulled, otherwise we use + # the local one + node-image: ${{ needs.build-node-images.result == 'skipped' && 'ghcr.io/bootc-dev/bink/node:v1.35-fedora-44-disk' || '' }} - name: Run integration tests run: sudo make test-integration TEST_PROCS=2 @@ -172,6 +188,9 @@ jobs: sudo podman volume prune -f 2>/dev/null || true integration-tests-composefs: + needs: [changes, build-node-images] + # Run when build-node-images is skipped (no node image changes) or succeeded, but not when it failed + if: ${{ !cancelled() && needs.build-node-images.result != 'failure' }} runs-on: ubuntu-latest timeout-minutes: 120 @@ -179,10 +198,21 @@ jobs: - name: Checkout code uses: actions/checkout@v7 + - name: Download composefs node image artifact + if: needs.build-node-images.result == 'success' + uses: actions/download-artifact@v7 + with: + name: node-image-composefs-1.35 + + - name: Load composefs node image + if: needs.build-node-images.result == 'success' + run: sudo podman load -i node-image-composefs.tar + - name: Setup bink uses: ./.github/actions/setup-bink with: cache-key-prefix: composefs + node-image: ${{ needs.build-node-images.result == 'skipped' && 'ghcr.io/bootc-dev/bink/node:v1.35-fedora-44-disk-composefs' || '' }} - name: Run composefs integration tests run: sudo make test-integration-composefs @@ -210,7 +240,9 @@ jobs: sudo podman volume prune -f 2>/dev/null || true integration-tests-k8s-versions: - needs: supported-versions + needs: [changes, supported-versions, build-node-images] + # Run when build-node-images is skipped (no node image changes) or succeeded, but not when it failed + if: ${{ !cancelled() && needs.build-node-images.result != 'failure' }} runs-on: ubuntu-latest timeout-minutes: 120 strategy: @@ -225,10 +257,21 @@ jobs: - name: Checkout code uses: actions/checkout@v7 + - name: Download node image artifact + if: needs.build-node-images.result == 'success' + uses: actions/download-artifact@v7 + with: + name: node-image-${{ matrix.kube-minor }} + + - name: Load node image + if: needs.build-node-images.result == 'success' + run: sudo podman load -i node-image.tar + - name: Setup bink uses: ./.github/actions/setup-bink with: cache-key-prefix: k8s-${{ matrix.kube-minor }} + node-image: ${{ needs.build-node-images.result == 'skipped' && format('ghcr.io/bootc-dev/bink/node:v{0}-fedora-44-disk', matrix.kube-minor) || '' }} - name: Run integration tests (K8s ${{ matrix.kube-minor }}) run: sudo make test-integration GINKGO_FOCUS="should create and initialize a complete Kubernetes cluster" From 4b2c34a72f898a6f6b5b432ecd09faa59c5f8bdc Mon Sep 17 00:00:00 2001 From: Alice Frosi Date: Mon, 3 Aug 2026 15:53:12 +0000 Subject: [PATCH 7/8] gha: parameterize kubernetes and fedora versions Expose default-version and fedora-version as outputs from supported-versions so test jobs reference a single source of truth instead of hardcoding v1.35 and fedora-44 throughout the workflow. Assisted-by: AI Signed-off-by: Alice Frosi --- .github/workflows/integration-tests.yml | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 889cb0b..35f5f7f 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -55,16 +55,21 @@ jobs: outputs: all-versions: ${{ steps.set-matrix.outputs.all-versions }} non-default-versions: ${{ steps.set-matrix.outputs.non-default-versions }} + default-version: ${{ steps.set-matrix.outputs.default-version }} + fedora-version: ${{ steps.set-matrix.outputs.fedora-version }} steps: - name: Get supported Kubernetes versions id: set-matrix run: | DEFAULT="1.35" + FEDORA_VERSION="44" ALL=$(curl -s https://endoflife.date/api/kubernetes.json | \ jq -c '[.[] | select(.eol > (now | strftime("%Y-%m-%d"))) | .cycle][:3]') NON_DEFAULT=$(echo "$ALL" | jq -c --arg default "$DEFAULT" 'map(select(. != $default))') echo "all-versions=${ALL}" >> "$GITHUB_OUTPUT" echo "non-default-versions=${NON_DEFAULT}" >> "$GITHUB_OUTPUT" + echo "default-version=${DEFAULT}" >> "$GITHUB_OUTPUT" + echo "fedora-version=${FEDORA_VERSION}" >> "$GITHUB_OUTPUT" build-node-images: needs: [changes, supported-versions] @@ -135,7 +140,7 @@ jobs: path: node-image-composefs.tar integration-tests: - needs: [changes, build-node-images] + needs: [changes, supported-versions, build-node-images] # Run when build-node-images is skipped (no node image changes) or succeeded, but not when it failed if: ${{ !cancelled() && needs.build-node-images.result != 'failure' }} runs-on: ubuntu-latest @@ -149,7 +154,7 @@ jobs: if: needs.build-node-images.result == 'success' uses: actions/download-artifact@v7 with: - name: node-image-1.35 + name: node-image-${{ needs.supported-versions.outputs.default-version }} - name: Load node image if: needs.build-node-images.result == 'success' @@ -159,9 +164,7 @@ jobs: uses: ./.github/actions/setup-bink with: cache-key-prefix: integration - # If the build of the image was skipped then we use the default one which needs to be pulled, otherwise we use - # the local one - node-image: ${{ needs.build-node-images.result == 'skipped' && 'ghcr.io/bootc-dev/bink/node:v1.35-fedora-44-disk' || '' }} + node-image: ${{ needs.build-node-images.result == 'skipped' && format('ghcr.io/bootc-dev/bink/node:v{0}-fedora-{1}-disk', needs.supported-versions.outputs.default-version, needs.supported-versions.outputs.fedora-version) || '' }} - name: Run integration tests run: sudo make test-integration TEST_PROCS=2 @@ -188,7 +191,7 @@ jobs: sudo podman volume prune -f 2>/dev/null || true integration-tests-composefs: - needs: [changes, build-node-images] + needs: [changes, supported-versions, build-node-images] # Run when build-node-images is skipped (no node image changes) or succeeded, but not when it failed if: ${{ !cancelled() && needs.build-node-images.result != 'failure' }} runs-on: ubuntu-latest @@ -202,7 +205,7 @@ jobs: if: needs.build-node-images.result == 'success' uses: actions/download-artifact@v7 with: - name: node-image-composefs-1.35 + name: node-image-composefs-${{ needs.supported-versions.outputs.default-version }} - name: Load composefs node image if: needs.build-node-images.result == 'success' @@ -212,14 +215,14 @@ jobs: uses: ./.github/actions/setup-bink with: cache-key-prefix: composefs - node-image: ${{ needs.build-node-images.result == 'skipped' && 'ghcr.io/bootc-dev/bink/node:v1.35-fedora-44-disk-composefs' || '' }} + node-image: ${{ needs.build-node-images.result == 'skipped' && format('ghcr.io/bootc-dev/bink/node:v{0}-fedora-{1}-disk-composefs', needs.supported-versions.outputs.default-version, needs.supported-versions.outputs.fedora-version) || '' }} - name: Run composefs integration tests run: sudo make test-integration-composefs timeout-minutes: 90 env: CONTAINER_HOST: unix:///run/podman/podman.sock - BINK_NODE_IMAGE: ghcr.io/bootc-dev/bink/node:v1.35-fedora-44-disk-composefs + BINK_NODE_IMAGE: ghcr.io/bootc-dev/bink/node:v${{ needs.supported-versions.outputs.default-version }}-fedora-${{ needs.supported-versions.outputs.fedora-version }}-disk-composefs - name: Collect logs if: failure() @@ -251,7 +254,7 @@ jobs: kube-minor: ${{ fromJson(needs.supported-versions.outputs.non-default-versions) }} env: - BINK_NODE_IMAGE: ghcr.io/bootc-dev/bink/node:v${{ matrix.kube-minor }}-fedora-44-disk + BINK_NODE_IMAGE: ghcr.io/bootc-dev/bink/node:v${{ matrix.kube-minor }}-fedora-${{ needs.supported-versions.outputs.fedora-version }}-disk steps: - name: Checkout code @@ -271,7 +274,7 @@ jobs: uses: ./.github/actions/setup-bink with: cache-key-prefix: k8s-${{ matrix.kube-minor }} - node-image: ${{ needs.build-node-images.result == 'skipped' && format('ghcr.io/bootc-dev/bink/node:v{0}-fedora-44-disk', matrix.kube-minor) || '' }} + node-image: ${{ needs.build-node-images.result == 'skipped' && format('ghcr.io/bootc-dev/bink/node:v{0}-fedora-{1}-disk', matrix.kube-minor, needs.supported-versions.outputs.fedora-version) || '' }} - name: Run integration tests (K8s ${{ matrix.kube-minor }}) run: sudo make test-integration GINKGO_FOCUS="should create and initialize a complete Kubernetes cluster" From a3539035d9b471f9909741724935acf9a444a400 Mon Sep 17 00:00:00 2001 From: Alice Frosi Date: Mon, 3 Aug 2026 15:07:29 +0000 Subject: [PATCH 8/8] gha: push node images only after integration tests pass Create a separate job to run after the integration tests. The job uses the image built and saved in the previous step. Assisted-by: AI Signed-off-by: Alice Frosi --- .github/workflows/integration-tests.yml | 78 +++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 35f5f7f..bdf8376 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -300,3 +300,81 @@ jobs: sudo podman ps -a --filter "name=k8s-test-bink" --format '{{.Names}}' | \ xargs -r sudo podman rm -f 2>/dev/null || true sudo podman volume prune -f 2>/dev/null || true + + push-node-images: + needs: [supported-versions, build-node-images, integration-tests, integration-tests-composefs, integration-tests-k8s-versions] + if: >- + needs.build-node-images.result == 'success' && + (github.event_name == 'push' || inputs.push-node-images == true) + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + kube-minor: ${{ fromJson(needs.supported-versions.outputs.all-versions) }} + permissions: + contents: read + packages: write + steps: + - name: Checkout + uses: actions/checkout@v7 + + - name: Download bootc image artifact + uses: actions/download-artifact@v7 + with: + name: bootc-image-${{ matrix.kube-minor }} + + - name: Download disk image artifact + uses: actions/download-artifact@v7 + with: + name: node-image-${{ matrix.kube-minor }} + + - name: Download composefs disk image artifact + uses: actions/download-artifact@v7 + with: + name: node-image-composefs-${{ matrix.kube-minor }} + + - name: Load images + run: | + sudo podman load -i bootc-image.tar + sudo podman load -i node-image.tar + sudo podman load -i node-image-composefs.tar + + - name: Determine image tag + id: meta + working-directory: node-images/fedora + run: | + TAG=$(make -s print-image-tag KUBE_MINOR=${{ matrix.kube-minor }}) + echo "tag=${TAG}" >> "$GITHUB_OUTPUT" + + - name: Log in to GHCR + run: sudo podman login -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} ghcr.io + + - name: Push bootc image + working-directory: node-images/fedora + run: | + TAG=${{ steps.meta.outputs.tag }} + BOOTC_SRC=$(make -s print-bootc-image KUBE_MINOR=${{ matrix.kube-minor }}) + PUSH_DEST=${{ env.PUSH_REGISTRY }}/${{ env.PUSH_IMAGE }} + + sudo podman tag ${BOOTC_SRC} ${PUSH_DEST}:${TAG} + sudo podman push ${PUSH_DEST}:${TAG} + + - name: Push disk image + working-directory: node-images/fedora + run: | + TAG=${{ steps.meta.outputs.tag }} + DISK_SRC=$(make -s print-node-image KUBE_MINOR=${{ matrix.kube-minor }}) + PUSH_DEST=${{ env.PUSH_REGISTRY }}/${{ env.PUSH_IMAGE }} + + sudo podman tag ${DISK_SRC} ${PUSH_DEST}:${TAG}-disk + sudo podman push ${PUSH_DEST}:${TAG}-disk + + - name: Push composefs disk image + working-directory: node-images/fedora + run: | + TAG=${{ steps.meta.outputs.tag }} + DISK_SRC=$(make -s print-node-image-composefs KUBE_MINOR=${{ matrix.kube-minor }}) + PUSH_DEST=${{ env.PUSH_REGISTRY }}/${{ env.PUSH_IMAGE }} + + sudo podman tag ${DISK_SRC} ${PUSH_DEST}:${TAG}-disk-composefs + sudo podman push ${PUSH_DEST}:${TAG}-disk-composefs