Skip to content

[WIP] [DO NOT REVIEW] ci: replace Cirrus CI with GitHub Actions #6

[WIP] [DO NOT REVIEW] ci: replace Cirrus CI with GitHub Actions

[WIP] [DO NOT REVIEW] ci: replace Cirrus CI with GitHub Actions #6

Workflow file for this run

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"