Files
podman/.github/workflows/ci.yml
Jan Rodák 9cef14899f Merge pull request #28832 from ashley-cui/ci
CI: Adjust Mac tmpdir
2026-06-02 11:55:45 +02:00

698 lines
24 KiB
YAML

name: "ci"
on:
push:
branches:
- main
- 'v*'
pull_request:
branches:
- main
- 'v*'
permissions: {}
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
path-filter:
runs-on: ubuntu-latest
outputs:
all: ${{ steps.filter.outputs.all }}
code: ${{ steps.filter.outputs.code }}
apiv2: ${{ steps.filter.outputs.apiv2 }}
bindings: ${{ steps.filter.outputs.bindings }}
docker_py: ${{ steps.filter.outputs.docker_py }}
unit: ${{ steps.filter.outputs.unit }}
compose_v2: ${{ steps.filter.outputs.compose_v2 }}
int: ${{ steps.filter.outputs.int }}
sys: ${{ steps.filter.outputs.sys }}
machine: ${{ steps.filter.outputs.machine }}
upgrade: ${{ steps.filter.outputs.upgrade }}
windows: ${{ steps.filter.outputs.windows }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1
id: filter
with:
filters: .github/filters.yaml
validate-source:
name: Validate source code changes
# TODO: currently only works on a PR checkout, enable parts of this later to also work on pushes.
if: ${{ github.event_name == 'pull_request' }}
runs-on: cncf-ubuntu-8-32-x86
env:
# Base commit of this PR; used by the Makefile and the helper scripts to
# compute the commit range (git merge-base $DEST_BRANCH HEAD..HEAD).
DEST_BRANCH: ${{ github.event.pull_request.base.sha }}
PR_NUMBER: ${{ github.event.pull_request.number }}
PR_HEAD: ${{ github.event.pull_request.head.sha }}
PR_BODY: ${{ github.event.pull_request.body }}
steps:
- name: Checkout PR head
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
# Check out the actual PR head (not the synthetic merge commit) so
# the commit-range checks validate the contributor's commits.
ref: refs/pull/${{ github.event.pull_request.number }}/head
# Full history (all branches) is required for git merge-base to find
# the fork point against the base branch.
fetch-depth: 0
persist-credentials: false
- name: Install build dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
gawk \
libassuan-dev \
libbtrfs-dev \
libgpgme-dev \
libseccomp-dev \
libsystemd-dev \
libclone-perl \
man-db \
podman \
python3-pip
- name: Set up Go
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version-file: go.mod
cache: false
- name: Read golangci-lint version from Makefile
id: gv
run: |
v=$(awk -F':=' '/^GOLANGCI_LINT_VERSION/ {gsub(/ /,"",$2); print $2; exit}' Makefile)
echo "version=v${v}" >> $GITHUB_OUTPUT
- uses: golangci/golangci-lint-action@82606bf257cbaff209d206a39f5134f0cfbfd2ee # v9.2.1
with:
version: ${{ steps.gv.outputs.version }}
install-only: true
- name: Install pre-commit
run: pipx install pre-commit
- name: Validate source
run: make validate-source
# TODO: I think these should be part of the validate-source target
- name: Check make vendor is clean
run: |
make vendor
SUGGESTION="run 'make vendor' and commit all changes" ./hack/tree_status.sh
- name: Check make -C test/tools vendor is clean
run: |
make -C test/tools vendor
SUGGESTION="run 'make -C test/tools vendor' and commit all changes" ./hack/tree_status.sh
- name: Check make generate-bindings is clean
run: |
make generate-bindings
SUGGESTION="run 'make generate-bindings' and commit all changes" ./hack/tree_status.sh
- name: Build and validate the swagger API spec
# 'make swagger' builds pkg/api/swagger.yaml via the go-swagger tool,
# which validates that the spec generates cleanly.
run: make swagger
- name: Check that the PR includes tests
# The 'No New Tests' label lets maintainers override this check.
if: ${{ !contains(github.event.pull_request.labels.*.name, 'No New Tests') }}
run: make tests-included
- name: Validate renovate config
run: |
diffs=$(git diff --name-only "$DEST_BRANCH" "${PR_HEAD:-HEAD}")
# The renovate validator image is large, only pull it when needed.
if ! grep -E -q '^\.github/renovate\.json5' <<<"$diffs"; then
echo "renovate config unchanged, skipping."
exit 0
fi
echo "Checking renovate config."
podman run --rm \
-v ./.github/renovate.json5:/usr/src/app/renovate.json5:z \
ghcr.io/renovatebot/renovate:latest \
renovate-config-validator
# IMPORTANT: keep this as the LAST step. Don't add anything after this.
# The 'git rebase' below rewrites HEAD and, on failure, leaves the
# checkout mid-rebase, so any step running afterwards would see a
# mutated/detached repo state.
- name: Build each commit
# Confirm that every commit in the PR builds on its own (so that
# 'git bisect' stays usable) and that no binary grows beyond the
# limit enforced by hack/ci/make-and-check-size.sh.
if: ${{ github.event_name == 'pull_request' }}
env:
# The 'bloat_approved' label lets a repo admin override the binary
# size growth check in hack/ci/make-and-check-size.sh.
BLOAT_APPROVED: ${{ contains(github.event.pull_request.labels.*.name, 'bloat_approved') }}
run: |
# git rebase rewrites commits, so it needs a committer identity.
git config user.name "CI"
git config user.email "ci@podman.io"
context_dir=$(mktemp -d --tmpdir make-size-check.XXXXXXX)
savedhead=$(git rev-parse HEAD)
# Make a copy of the script as we'll be rolling git back.
cp -a ./hack/ci/make-and-check-size.sh .
# Replay only the PR's own commits: the fork point against the base
# branch, not the (possibly advanced) base branch tip.
pr_base=$(git merge-base "$DEST_BRANCH" HEAD)
# Build the PR base first; this run records the baseline binary
# sizes that subsequent (per-commit) runs compare against.
git checkout --quiet "$pr_base"
./make-and-check-size.sh "$context_dir"
# Back to the PR head, then build (and size-check) each commit.
git checkout --quiet "$savedhead"
git rebase "$pr_base" -x "./make-and-check-size.sh $context_dir"
rm -rf "$context_dir" ./make-and-check-size.sh
build-alt:
name: Cross Build (Linux, FreeBSD)
runs-on: cncf-ubuntu-16-64-x86
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version-file: go.mod
cache: false
- name: Run cross build
run: make cross
build:
name: build ${{ matrix.distro }}
strategy:
fail-fast: false
matrix:
distro: [fedora-current, fedora-prior, fedora-rawhide, debian-sid]
uses: ./.github/workflows/lima.yml
with:
runner: cncf-ubuntu-8-32-x86
test: build
distro: ${{ matrix.distro }}
timeout: 20
windows-installer:
name: windows installer ${{ matrix.provider }}
runs-on: windows-2025-vs2026
timeout-minutes: 20
permissions: {}
strategy:
fail-fast: false
matrix:
provider: [hyperv, wsl]
env:
PROVIDER: ${{ matrix.provider }}
steps:
- name: Configure git line endings
shell: pwsh
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Set up Go
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version-file: go.mod
cache: true
- name: Install build dependencies
shell: pwsh
run: |
dotnet tool install --global wix --version 5.0.2
choco install -y pandoc
- name: Build podman
shell: pwsh
run: |
.\winmake.ps1 podman-remote
.\bin\windows\podman.exe --version
- name: Fetch gvproxy
shell: pwsh
run: .\winmake.ps1 win-gvproxy
- name: Build docs
shell: pwsh
run: .\winmake.ps1 docs
- name: Build MSI (current version)
shell: pwsh
run: .\winmake.ps1 installer
- name: Build MSI (next version 9.9.9)
shell: pwsh
run: .\winmake.ps1 installer 9.9.9
- name: Run installer test
shell: pwsh
env:
# pass in ro token just so we can use it for API calls to not get rate limited
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: .\winmake.ps1 installertest $env:PROVIDER
- name: Upload artifacts
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: windows-installer-${{ matrix.provider }}-diag
path: |
contrib/win-installer/*.msi
contrib/win-installer/*.log
if-no-files-found: warn
macos-installer:
name: macos installer
runs-on: macos-15
timeout-minutes: 15
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version-file: go.mod
cache: true
- name: Build core binaries
run: |
make podman-remote
make podman-mac-helper
- name: Upload test binaries
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: podman-macos-bin
# Single path keeps the `bin/` prefix; a path list would trigger LCA
# stripping and lose it, breaking chmod in the machine job.
path: bin
if-no-files-found: error
- name: Build .pkg installer
run: |
pushd contrib/pkginstaller
make ARCH=aarch64 NO_CODESIGN=1 pkginstaller
popd
- name: Build release zip
run: make podman-remote-release-darwin_arm64.zip
- name: Upload release artifacts
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: podman-darwin-arm64
path: |
podman-remote-release-darwin_arm64.zip
contrib/pkginstaller/out/podman-installer-macos-*.pkg
if-no-files-found: error
big-tests:
needs: [path-filter, build, build-alt, validate-source, windows-installer, macos-installer]
name: ${{ matrix.test }} ${{ matrix.mode }} ${{ matrix.priv }} ${{ matrix.distro }}
strategy:
fail-fast: false
matrix:
distro: [fedora-current, fedora-prior, fedora-rawhide, debian-sid]
test: [sys, int]
priv: [rootless, root]
mode: [local, remote]
exclude:
# try to keep the task somewhat sane and not run remote test rootless
- priv: rootless
mode: remote
include:
# Add buildah bud tests, only runs as root for now.
- test: bud
distro: fedora-current
priv: root
mode: local
- test: bud
distro: fedora-current
priv: root
mode: remote
uses: ./.github/workflows/lima.yml
with:
runner: cncf-ubuntu-8-32-x86
test: ${{ matrix.test }}
distro: ${{ matrix.distro }}
mode: ${{ matrix.mode }}
priv: ${{ matrix.priv }}
timeout: ${{ matrix.timeout || 30 }}
# Top level if does not work because it does not have access to the matrix context.
# However we can hack around by passing this input argument and the workflow_call
# can then use this in the if condition to make it work that way.
if: >-
${{ github.event_name != 'pull_request' ||
needs.path-filter.outputs.all == 'true' ||
needs.path-filter.outputs.code == 'true' ||
needs.path-filter.outputs[format('{0}', matrix.test)] == 'true' }}
small-tests:
needs: [path-filter, build, build-alt, validate-source, windows-installer]
name: ${{ matrix.test }} ${{ matrix.mode }} ${{ matrix.priv }} ${{ matrix.distro }}
strategy:
fail-fast: false
matrix:
distro: [fedora-current]
test: [apiv2, bindings, compose_v2, docker_py, unit]
priv: [rootless, root]
exclude:
# bindings, and docker_py, upgrade are only run as root
- test: bindings
priv: rootless
- test: docker_py
priv: rootless
include:
# need an extra include for the upgrade tests to set the mode
- test: upgrade
distro: fedora-current
mode: v5.3.1
priv: root
- test: upgrade
distro: fedora-current
mode: v5.6.2
priv: root
uses: ./.github/workflows/lima.yml
with:
runner: cncf-ubuntu-4-16-x86
test: ${{ matrix.test }}
distro: ${{ matrix.distro }}
priv: ${{ matrix.priv }}
mode: ${{ matrix.mode }}
timeout: 20
if: >-
${{ github.event_name != 'pull_request' ||
needs.path-filter.outputs.all == 'true' ||
needs.path-filter.outputs.code == 'true' ||
needs.path-filter.outputs[format('{0}', matrix.test)] == 'true' }}
machine-linux:
needs: [path-filter, build, build-alt, validate-source, windows-installer, macos-installer]
# Note we do not check for "code" here because we do not want to trigger machine tests for all code changes.
if: |
github.event_name != 'pull_request' ||
needs.path-filter.outputs.all == 'true' ||
needs.path-filter.outputs.machine == 'true'
name: machine linux ${{ matrix.os.arch }}
runs-on: ${{ matrix.os.runner }}
strategy:
fail-fast: false
matrix:
os: [ { runner: cncf-ubuntu-24-96-x86, arch: amd64 } ]
# The default runners do not have vrit enabled so we cannot test on arm at the moment.
# CNCF staff is looking if they can give us a bare metal host.
# { runner: cncf-ubuntu-32-128-arm, arch: arm64 } ]
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version-file: go.mod
cache: false
- name: "Install gvproxy"
run: |
VERSION=$(go list -m -f '{{.Version}}' github.com/containers/gvisor-tap-vsock)
echo "Installing gvproxy $VERSION"
sudo mkdir -p /usr/local/libexec/podman/
sudo curl --fail -L -o /usr/local/libexec/podman/gvproxy https://github.com/containers/gvisor-tap-vsock/releases/download/$VERSION/gvproxy-linux-${{ matrix.os.arch }}
sudo chmod +x /usr/local/libexec/podman/gvproxy
- name: "Install dependencies"
run: |
sudo apt-get update
sudo apt-get install -y qemu-system virtiofsd
sudo ln -sfr /usr/libexec/virtiofsd /usr/local/libexec/podman/virtiofsd
# The default podman ship in ubuntu comes with an old unsupported registries.conf v1 format,
# just remove it as we need no special config.
- name: "Configure registries.conf"
run: |
sudo rm -f /etc/containers/registries.conf
# podman-machine needs kvm access
- name: "Fix kvm permissions"
run: |
sudo chmod 666 /dev/kvm
- name: "Build podman-remote"
run: |
make podman-remote
- name: "Run machine tests"
run: |
make localmachine
windows-unit:
needs: [path-filter, build, build-alt, validate-source, windows-installer, macos-installer]
if: |
github.event_name != 'pull_request' ||
needs.path-filter.outputs.all == 'true' ||
needs.path-filter.outputs.code == 'true' ||
needs.path-filter.outputs.unit == 'true' ||
needs.path-filter.outputs.windows == 'true'
name: windows unit
runs-on: windows-2025-vs2026
timeout-minutes: 20
permissions: {}
steps:
- name: Configure git line endings
shell: pwsh
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Set up Go
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version-file: go.mod
cache: true
- name: Run unit tests
shell: pwsh
run: .\winmake.ps1 localunit
windows-e2e:
needs: [path-filter, build, build-alt, validate-source, windows-installer, macos-installer]
if: |
github.event_name != 'pull_request' ||
needs.path-filter.outputs.all == 'true' ||
needs.path-filter.outputs.code == 'true' ||
needs.path-filter.outputs.int == 'true' ||
needs.path-filter.outputs.windows == 'true'
name: windows e2e
runs-on: windows-2025-vs2026
timeout-minutes: 20
steps:
- name: Configure git line endings
shell: pwsh
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Set up Go
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version-file: go.mod
cache: true
- name: Build podman
shell: pwsh
run: |
.\winmake.ps1 podman-remote
.\bin\windows\podman.exe --version
- name: Run non-machine e2e tests
shell: pwsh
run: .\winmake.ps1 ginkgo-run
windows-machine:
needs: [path-filter, build, build-alt, validate-source, windows-installer, macos-installer]
# Note we do not check for "code" here because we do not want to trigger machine tests for all code changes.
if: |
github.event_name != 'pull_request' ||
needs.path-filter.outputs.all == 'true' ||
needs.path-filter.outputs.machine == 'true' ||
needs.path-filter.outputs.windows == 'true'
name: windows machine ${{ matrix.provider }}
runs-on: windows-2025-vs2026
timeout-minutes: 60
permissions: {}
strategy:
fail-fast: false
matrix:
provider: [hyperv, wsl]
env:
CONTAINERS_MACHINE_PROVIDER: ${{ matrix.provider }}
steps:
- name: Configure git line endings
shell: pwsh
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Set up Go
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version-file: go.mod
cache: true
- name: Diagnostics
shell: pwsh
run: |
Get-ComputerInfo | Select-Object OsName, OsVersion, CsProcessors, CsNumberOfLogicalProcessors, CsTotalPhysicalMemory | Format-List
Get-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V | Format-List
Get-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-Hypervisor | Format-List
Get-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform | Format-List
Get-CimInstance Win32_Processor | Select-Object Name, VirtualizationFirmwareEnabled, VMMonitorModeExtensions | Format-List
Get-Disk | Format-Table -AutoSize
- name: Build podman
shell: pwsh
run: |
.\winmake.ps1 podman-remote
.\bin\windows\podman.exe --version
- name: Fetch gvproxy
shell: pwsh
run: .\winmake.ps1 win-gvproxy
- name: WSL info
if: matrix.provider == 'wsl'
shell: pwsh
run: |
wsl --update
wsl --version
wsl --status
- name: Configure container policy
shell: pwsh
run: |
New-Item -ItemType Directory -Force -Path "$env:AppData\containers" | Out-Null
Copy-Item -Path pkg\machine\ocipull\policy.json -Destination "$env:AppData\containers"
- name: Run machine e2e
shell: pwsh
run: .\winmake.ps1 localmachine
macos-machine:
needs: [path-filter, build, build-alt, validate-source, windows-installer, macos-installer]
# Note we do not check for "code" here because we do not want to trigger machine tests for all code changes.
if: |
github.event_name != 'pull_request' ||
needs.path-filter.outputs.all == 'true' ||
needs.path-filter.outputs.machine == 'true'
name: macos machine ${{ matrix.provider }}
runs-on:
group: mac-pool
timeout-minutes: 40
strategy:
fail-fast: false
matrix:
provider: [applehv, libkrun]
env:
PROVIDER: ${{ matrix.provider }}
CONTAINERS_MACHINE_PROVIDER: ${{ matrix.provider }}
# machine_test.go rejects TMPDIR >= 22 chars on darwin (socket path budget).
TMPDIR: /private/tmp/ci
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version-file: go.mod
cache: true
- name: Pre-clean machine state
run: ./hack/ci/gha_mac_cleanup.sh
- name: Download test binaries
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: podman-macos-bin
# `path: bin` on upload sent the *contents* of bin/ (no prefix).
# Extract into bin/ to restore the layout.
path: bin
- name: Restore executable bits
run: chmod +x bin/darwin/podman bin/darwin/podman-mac-helper
- name: Run machine e2e
run: make localmachine
- name: Post-run cleanup
if: always()
run: ./hack/ci/gha_mac_cleanup.sh
### TODO missing
# Farm, needs extra setup I need to look into
# Merge protection is setup for this job name, do not change it.
success:
name: "Total Success"
if: always()
needs:
- path-filter
- validate-source
- build
- build-alt
- big-tests
- small-tests
- machine-linux
- windows-installer
- windows-unit
- windows-e2e
- windows-machine
- macos-installer
- macos-machine
runs-on: ubuntu-latest
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"