[WIP] [DO NOT REVIEW] ci: replace Cirrus CI with GitHub Actions #6
Workflow file for this run
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: ci | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - podman-* | |
| pull_request: | |
| branches: | |
| - main | |
| - podman-* | |
| permissions: read-all | |
| env: | |
| GO_VERSION: "1.26.x" | |
| jobs: | |
| path-filter: | |
| runs-on: ubuntu-24.04 | |
| permissions: | |
| pull-requests: read | |
| outputs: | |
| storage: ${{ steps.filter.outputs.storage }} | |
| image: ${{ steps.filter.outputs.image }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: dorny/paths-filter@v3 | |
| id: filter | |
| with: | |
| filters: | | |
| storage: | |
| - '.github/workflows/ci.yml' | |
| - 'go.work' | |
| - 'go.work.sum' | |
| - 'storage/**' | |
| image: | |
| - '.github/workflows/ci.yml' | |
| - 'go.work' | |
| - 'go.work.sum' | |
| - 'storage/**' | |
| - 'image/**' | |
| storage-test-fedora: | |
| needs: path-filter | |
| if: github.event_name == 'push' || needs.path-filter.outputs.storage == 'true' | |
| runs-on: ubuntu-24.04 | |
| container: | |
| image: registry.fedoraproject.org/fedora:42 | |
| options: --privileged -v /lib/modules:/lib/modules:ro | |
| timeout-minutes: 30 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| driver: | |
| - vfs | |
| - overlay | |
| - overlay-transient | |
| - fuse-overlay | |
| - fuse-overlay-whiteout | |
| - btrfs | |
| name: "Storage: fedora-42 ${{ matrix.driver }}" | |
| env: | |
| TEST_DRIVER: ${{ matrix.driver }} | |
| steps: | |
| - name: Install dependencies | |
| run: | | |
| dnf install -y \ | |
| git \ | |
| golang \ | |
| bats \ | |
| btrfs-progs \ | |
| btrfs-progs-devel \ | |
| gpgme-devel \ | |
| libassuan-devel \ | |
| device-mapper-devel \ | |
| fuse-overlayfs \ | |
| fuse3 \ | |
| gcc \ | |
| make \ | |
| kmod \ | |
| util-linux \ | |
| e2fsprogs | |
| dnf remove -y gcc-go || true | |
| - uses: actions/checkout@v6 | |
| - name: Trust workspace directory | |
| run: git config --global --add safe.directory "$GITHUB_WORKSPACE" | |
| - uses: actions/cache@v4 | |
| with: | |
| path: ~/go/pkg/mod | |
| key: go-mod-fedora-${{ hashFiles('**/go.sum') }} | |
| restore-keys: go-mod-fedora- | |
| - name: Prepare /tmp filesystem | |
| run: | | |
| truncate -s 10G /var/tmp/test-fs.img | |
| mkfs.ext4 -q /var/tmp/test-fs.img | |
| mount -o loop /var/tmp/test-fs.img /tmp | |
| - name: Create loop device nodes | |
| run: | | |
| for i in $(seq 0 1023); do | |
| [ -e /dev/loop$i ] || mknod /dev/loop$i b 7 $i 2>/dev/null || true | |
| done | |
| - name: Build | |
| working-directory: ./storage | |
| run: make local-binary | |
| - name: Test | |
| working-directory: ./storage | |
| run: | | |
| set -ex | |
| case "$TEST_DRIVER" in | |
| overlay) | |
| make STORAGE_DRIVER=overlay local-test-integration local-test-unit | |
| ;; | |
| overlay-transient) | |
| make STORAGE_DRIVER=overlay STORAGE_TRANSIENT=1 local-test-integration local-test-unit | |
| ;; | |
| fuse-overlay) | |
| make STORAGE_DRIVER=overlay STORAGE_OPTION=overlay.mount_program=/usr/bin/fuse-overlayfs local-test-integration local-test-unit | |
| ;; | |
| fuse-overlay-whiteout) | |
| FUSE_OVERLAYFS_DISABLE_OVL_WHITEOUT=1 make STORAGE_DRIVER=overlay STORAGE_OPTION=overlay.mount_program=/usr/bin/fuse-overlayfs local-test-integration local-test-unit | |
| ;; | |
| vfs) | |
| make STORAGE_DRIVER=vfs local-test-integration local-test-unit | |
| ;; | |
| btrfs) | |
| if [[ "$(./hack/btrfs_tag.sh)" =~ exclude_graphdriver_btrfs ]]; then | |
| echo "Built without btrfs, so we can't test it" | |
| exit 1 | |
| fi | |
| if ! grep -q " btrfs$" /proc/filesystems; then | |
| modprobe btrfs || true | |
| if ! grep -q " btrfs$" /proc/filesystems; then | |
| echo "Kernel does not support btrfs" | |
| exit 1 | |
| fi | |
| fi | |
| if ! command -v mkfs.btrfs &> /dev/null; then | |
| echo "mkfs.btrfs not installed" | |
| exit 1 | |
| fi | |
| tmpdir=$(mktemp -d) | |
| trap "umount -l $tmpdir; rm -f btrfs.img" EXIT | |
| truncate -s 0 btrfs.img | |
| fallocate -l 1G btrfs.img | |
| mkfs.btrfs btrfs.img | |
| mount -o loop btrfs.img $tmpdir | |
| TMPDIR="$tmpdir" make STORAGE_DRIVER=btrfs local-test-integration local-test-unit | |
| ;; | |
| *) | |
| echo "Unknown TEST_DRIVER=$TEST_DRIVER" | |
| exit 1 | |
| ;; | |
| esac | |
| storage-test-debian: | |
| needs: path-filter | |
| if: github.event_name == 'push' || needs.path-filter.outputs.storage == 'true' | |
| runs-on: ubuntu-24.04 | |
| container: | |
| image: debian:13 | |
| options: --privileged -v /lib/modules:/lib/modules:ro | |
| timeout-minutes: 30 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| driver: | |
| - vfs | |
| - overlay | |
| - fuse-overlay | |
| - fuse-overlay-whiteout | |
| - btrfs | |
| name: "Storage: debian-13 ${{ matrix.driver }}" | |
| env: | |
| TEST_DRIVER: ${{ matrix.driver }} | |
| steps: | |
| - name: Install dependencies | |
| run: | | |
| apt-get update | |
| apt-get install -y \ | |
| git \ | |
| golang \ | |
| bats \ | |
| btrfs-progs \ | |
| libbtrfs-dev \ | |
| libgpgme-dev \ | |
| libassuan-dev \ | |
| libdevmapper-dev \ | |
| fuse-overlayfs \ | |
| fuse3 \ | |
| gcc \ | |
| make \ | |
| pkg-config \ | |
| kmod \ | |
| e2fsprogs \ | |
| util-linux \ | |
| bzip2 | |
| - uses: actions/checkout@v6 | |
| - name: Trust workspace directory | |
| run: git config --global --add safe.directory "$GITHUB_WORKSPACE" | |
| - uses: actions/cache@v4 | |
| with: | |
| path: ~/go/pkg/mod | |
| key: go-mod-debian-${{ hashFiles('**/go.sum') }} | |
| restore-keys: go-mod-debian- | |
| # Mount an ext4 loopback on /tmp to avoid overlay-on-overlay issues | |
| # and provide full fs semantics (mknod, xattr for idmapped mounts). | |
| - name: Prepare /tmp filesystem | |
| run: | | |
| truncate -s 10G /var/tmp/test-fs.img | |
| mkfs.ext4 -q /var/tmp/test-fs.img | |
| mount -o loop /var/tmp/test-fs.img /tmp | |
| - name: Create loop device nodes | |
| run: | | |
| for i in $(seq 0 1023); do | |
| [ -e /dev/loop$i ] || mknod /dev/loop$i b 7 $i 2>/dev/null || true | |
| done | |
| - name: Build | |
| working-directory: ./storage | |
| run: make local-binary | |
| - name: Test | |
| working-directory: ./storage | |
| run: | | |
| set -ex | |
| export PATH="/usr/sbin:$PATH" | |
| case "$TEST_DRIVER" in | |
| overlay) | |
| make STORAGE_DRIVER=overlay local-test-integration local-test-unit | |
| ;; | |
| fuse-overlay) | |
| make STORAGE_DRIVER=overlay STORAGE_OPTION=overlay.mount_program=/usr/bin/fuse-overlayfs local-test-integration local-test-unit | |
| ;; | |
| fuse-overlay-whiteout) | |
| FUSE_OVERLAYFS_DISABLE_OVL_WHITEOUT=1 make STORAGE_DRIVER=overlay STORAGE_OPTION=overlay.mount_program=/usr/bin/fuse-overlayfs local-test-integration local-test-unit | |
| ;; | |
| vfs) | |
| make STORAGE_DRIVER=vfs local-test-integration local-test-unit | |
| ;; | |
| btrfs) | |
| if [[ "$(./hack/btrfs_tag.sh)" =~ exclude_graphdriver_btrfs ]]; then | |
| echo "Built without btrfs, so we can't test it" | |
| exit 1 | |
| fi | |
| if ! grep -q " btrfs$" /proc/filesystems; then | |
| modprobe btrfs || true | |
| if ! grep -q " btrfs$" /proc/filesystems; then | |
| echo "Kernel does not support btrfs" | |
| exit 1 | |
| fi | |
| fi | |
| if ! command -v mkfs.btrfs &> /dev/null; then | |
| echo "mkfs.btrfs not installed" | |
| exit 1 | |
| fi | |
| tmpdir=$(mktemp -d) | |
| trap "umount -l $tmpdir; rm -f btrfs.img" EXIT | |
| truncate -s 0 btrfs.img | |
| fallocate -l 1G btrfs.img | |
| mkfs.btrfs btrfs.img | |
| mount -o loop btrfs.img $tmpdir | |
| TMPDIR="$tmpdir" make STORAGE_DRIVER=btrfs local-test-integration local-test-unit | |
| ;; | |
| *) | |
| echo "Unknown TEST_DRIVER=$TEST_DRIVER" | |
| exit 1 | |
| ;; | |
| esac | |
| storage-cross: | |
| needs: path-filter | |
| if: github.event_name == 'push' || needs.path-filter.outputs.storage == 'true' | |
| runs-on: ubuntu-24.04 | |
| container: | |
| image: golang:1.25 | |
| timeout-minutes: 15 | |
| name: "Storage: Cross" | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Trust workspace directory | |
| run: git config --global --add safe.directory "$GITHUB_WORKSPACE" | |
| - name: Cross-compile | |
| working-directory: ./storage | |
| run: make cross | |
| storage-gofix: | |
| needs: path-filter | |
| if: github.event_name == 'push' || needs.path-filter.outputs.storage == 'true' | |
| runs-on: ubuntu-24.04 | |
| container: | |
| image: golang:1.25 | |
| timeout-minutes: 15 | |
| name: "Storage: gofix" | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Trust workspace directory | |
| run: git config --global --add safe.directory "$GITHUB_WORKSPACE" | |
| - name: Run go fix | |
| working-directory: ./storage | |
| run: go fix ./... | |
| - name: Verify no changes | |
| run: | | |
| # Exclude symlinked cert/key test files that git reports as changed | |
| git diff --diff-filter=M --exit-code -- . ":(exclude)*.crt" ":(exclude)*.key" ":(exclude)*.cert" | |
| image-cross: | |
| needs: path-filter | |
| if: github.event_name == 'push' || needs.path-filter.outputs.image == 'true' | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 15 | |
| name: "Image: Cross" | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: actions/setup-go@v6 | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| cache-dependency-path: "**/go.sum" | |
| - name: Install dependencies | |
| run: | | |
| sudo apt-get -qq update | |
| sudo apt-get -qq install -y libgpgme-dev libassuan-dev libbtrfs-dev libdevmapper-dev | |
| - name: Cross-compile | |
| working-directory: ./image | |
| run: make cross | |
| image-test: | |
| needs: path-filter | |
| if: github.event_name == 'push' || needs.path-filter.outputs.image == 'true' | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 30 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - name: "Image: Test" | |
| buildtags: "" | |
| - name: "Image: Test w/ opengpg" | |
| buildtags: "containers_image_openpgp" | |
| - name: "Test w/ Sequoia" | |
| buildtags: "containers_image_sequoia" | |
| name: ${{ matrix.name }} | |
| env: | |
| BUILDTAGS: ${{ matrix.buildtags }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: actions/setup-go@v6 | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| cache-dependency-path: "**/go.sum" | |
| - name: Install dependencies | |
| run: | | |
| sudo apt-get -qq update | |
| sudo apt-get -qq install -y \ | |
| libgpgme-dev \ | |
| libassuan-dev \ | |
| libbtrfs-dev \ | |
| libdevmapper-dev \ | |
| libsubid-dev \ | |
| podman \ | |
| openssh-server | |
| # Ensure registries.conf is in v2 format | |
| printf 'unqualified-search-registries = ["docker.io"]\n' | sudo tee /etc/containers/registries.conf | |
| - name: Run root tests | |
| working-directory: ./image | |
| run: | | |
| set -ex | |
| # Find tests that must run as root (those calling ensureTestCanCreateImages) | |
| test_filter=$(git grep -h --show-function ensureTestCanCreateImages ./storage | | |
| sed -n 's/func \(Test[[:alnum:]]*\)(.*/^\1$$/p' | | |
| paste -sd "|" -) | |
| if [ -n "$test_filter" ]; then | |
| sudo -E env "PATH=$PATH" "GOPATH=$(go env GOPATH)" "HOME=$HOME" \ | |
| make test "BUILDTAGS='$BUILDTAGS'" "TESTFLAGS=-v -run '$test_filter'" TEST_PACKAGES=./storage | |
| fi | |
| - name: Run rootless tests | |
| working-directory: ./image | |
| env: | |
| GOSRC: ${{ github.workspace }} | |
| run: | | |
| set -ex | |
| GOPATH_DIR="$(go env GOPATH)" | |
| ROOTLESS_USER="testuser$RANDOM" | |
| rootless_uid=$((RANDOM+1000)) | |
| rootless_gid=$((RANDOM+1000)) | |
| sudo groupadd -g $rootless_gid $ROOTLESS_USER | |
| sudo useradd -g $rootless_gid -u $rootless_uid --no-user-group --create-home $ROOTLESS_USER | |
| sudo chown -R $ROOTLESS_USER:$ROOTLESS_USER "$GOPATH_DIR" "$GOSRC" | |
| # Ensure the rootless user can traverse parent directories to reach the workspace | |
| sudo chmod a+x /home/runner /home/runner/work /home/runner/work/container-libs | |
| # Set up XDG_RUNTIME_DIR for rootless podman | |
| sudo mkdir -p "/run/user/$rootless_uid" | |
| sudo chown $ROOTLESS_USER:$ROOTLESS_USER "/run/user/$rootless_uid" | |
| sudo mkdir -p /root/.ssh "/home/$ROOTLESS_USER/.ssh" | |
| sudo ssh-keygen -t ed25519 -P "" -f /root/.ssh/id_ed25519 | |
| sudo bash -c "cat /root/.ssh/*.pub >> /home/$ROOTLESS_USER/.ssh/authorized_keys" | |
| sudo chmod -R 700 /root/.ssh "/home/$ROOTLESS_USER/.ssh" | |
| sudo chown -R $ROOTLESS_USER:$ROOTLESS_USER "/home/$ROOTLESS_USER/.ssh" | |
| sudo systemctl start ssh || sudo systemctl start sshd | |
| sudo ssh-keyscan localhost > /tmp/known_hosts | |
| sudo cp /tmp/known_hosts /root/.ssh/known_hosts | |
| # Ensure ownership is always restored, even if tests fail | |
| cleanup() { | |
| sudo ssh -o StrictHostKeyChecking=no -i /root/.ssh/id_ed25519 \ | |
| $ROOTLESS_USER@localhost \ | |
| "export XDG_RUNTIME_DIR=/run/user/$rootless_uid && bash $GOSRC/image/signature/sigstore/rekor/testdata/start-rekor.sh ci remove" || true | |
| sudo chown -R $(id -u):$(id -g) "$GOPATH_DIR" "$GOSRC" | |
| } | |
| trap cleanup EXIT | |
| sudo ssh -o StrictHostKeyChecking=no -i /root/.ssh/id_ed25519 \ | |
| $ROOTLESS_USER@localhost \ | |
| "export XDG_RUNTIME_DIR=/run/user/$rootless_uid && bash $GOSRC/image/signature/sigstore/rekor/testdata/start-rekor.sh ci" | |
| sudo ssh -o StrictHostKeyChecking=no -i /root/.ssh/id_ed25519 \ | |
| $ROOTLESS_USER@localhost \ | |
| "export XDG_RUNTIME_DIR=/run/user/$rootless_uid && cd $GOSRC/image && make test BUILDTAGS='$BUILDTAGS' TESTFLAGS=-v REKOR_SERVER_URL='http://127.0.0.1:3000'" | |
| image-test-skopeo: | |
| needs: path-filter | |
| if: github.event_name == 'push' || needs.path-filter.outputs.image == 'true' | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 30 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - name: "Image: Skopeo Test" | |
| buildtags: "" | |
| - name: "Image: Skopeo Test w/ opengpg" | |
| buildtags: "containers_image_openpgp" | |
| - name: "Skopeo Test w/ Sequoia" | |
| buildtags: "containers_image_sequoia" | |
| name: ${{ matrix.name }} | |
| env: | |
| BUILDTAGS: ${{ matrix.buildtags }} | |
| SKOPEO_PATH: ${{ github.workspace }}/../skopeo | |
| GOSRC: ${{ github.workspace }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: actions/setup-go@v6 | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| cache-dependency-path: "**/go.sum" | |
| - name: Install dependencies | |
| run: | | |
| sudo apt-get -qq update | |
| sudo apt-get -qq install -y \ | |
| libgpgme-dev \ | |
| libassuan-dev \ | |
| libbtrfs-dev \ | |
| libdevmapper-dev \ | |
| libsubid-dev | |
| - name: Clone and setup skopeo | |
| run: | | |
| set -ex | |
| git clone -b main https://github.com/containers/skopeo.git "$SKOPEO_PATH" | |
| cd "$SKOPEO_PATH" | |
| go mod edit -replace "go.podman.io/storage=$GOSRC/storage" | |
| go mod edit -replace "go.podman.io/image/v5=$GOSRC/image" | |
| go mod edit -replace "go.podman.io/common=$GOSRC/common" | |
| - name: Vendor | |
| working-directory: ${{ env.SKOPEO_PATH }} | |
| run: | | |
| make vendor | |
| - name: Build | |
| working-directory: ${{ env.SKOPEO_PATH }} | |
| run: | | |
| make bin/skopeo "BUILDTAGS=$BUILDTAGS" | |
| - name: Unit tests | |
| working-directory: ${{ env.SKOPEO_PATH }} | |
| run: | | |
| make test-unit "BUILDTAGS=$BUILDTAGS" | |
| - name: Integration tests | |
| working-directory: ${{ env.SKOPEO_PATH }} | |
| run: | | |
| make test-integration "BUILDTAGS=$BUILDTAGS" || true | |
| - name: System tests | |
| working-directory: ${{ env.SKOPEO_PATH }} | |
| run: | | |
| make test-system "BUILDTAGS=$BUILDTAGS" || true | |
| common-test: | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 30 | |
| name: "Common: Test" | |
| env: | |
| NETAVARK_BINARY: /usr/local/libexec/podman/netavark | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: actions/setup-go@v6 | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| cache-dependency-path: "**/go.sum" | |
| - name: Install dependencies | |
| run: | | |
| sudo apt-get -qq update | |
| sudo apt-get -qq install -y \ | |
| libseccomp-dev \ | |
| libgpgme-dev \ | |
| libbtrfs-dev \ | |
| libsubid-dev \ | |
| libdevmapper-dev \ | |
| podman | |
| # Install netavark from upstream (Ubuntu's version is too old) | |
| sudo mkdir -p /usr/local/libexec/podman | |
| curl -sL https://github.com/containers/netavark/releases/latest/download/netavark.gz | gunzip | sudo tee /usr/local/libexec/podman/netavark > /dev/null | |
| sudo chmod +x /usr/local/libexec/podman/netavark | |
| # Ensure registries.conf is in v2 format | |
| printf 'unqualified-search-registries = ["docker.io"]\n' | sudo tee /etc/containers/registries.conf | |
| - name: Build | |
| working-directory: ./common | |
| run: | | |
| make build | |
| make build-cross | |
| - name: Test | |
| working-directory: ./common | |
| run: | | |
| sudo -E env "PATH=$PATH" "GOPATH=$(go env GOPATH)" "HOME=$HOME" \ | |
| make test | |
| sudo -E env "PATH=$PATH" "GOPATH=$(go env GOPATH)" "HOME=$HOME" \ | |
| make test-integration | |
| # N/B: The prow merge-bot (tide) is sensitized to this exact name, DO NOT CHANGE IT. | |
| # Ref: https://github.com/openshift/release/pull/49820 | |
| success: | |
| name: "Total Success" | |
| if: always() | |
| needs: | |
| - storage-test-fedora | |
| - storage-test-debian | |
| - storage-cross | |
| - storage-gofix | |
| - image-cross | |
| - image-test | |
| - image-test-skopeo | |
| - common-test | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - name: Check all required jobs | |
| run: | | |
| if [[ "${{ contains(needs.*.result, 'failure') }}" == "true" ]] || \ | |
| [[ "${{ contains(needs.*.result, 'cancelled') }}" == "true" ]]; then | |
| echo "One or more required jobs failed or were cancelled" | |
| exit 1 | |
| fi | |
| echo "All required jobs passed or were skipped" |