version: 2.1 orbs: # NB: this is not the Go version, but the Orb version # https://circleci.com/developer/orbs/orb/circleci/go#usage-go-modules-cache go: circleci/go@1.11.0 commands: setup-home-local-bin: steps: - run: shell: /bin/bash -euo pipefail command: | mkdir -p "$HOME/.local/bin" line='export PATH="$HOME/.local/bin:$PATH"' if grep "$line" $BASH_ENV >/dev/null; then echo "$line" >> $BASH_ENV fi # NOTE: UV version is defined in .uv-version file at repository root install-docdep: steps: - run: name: Read UV version from .uv-version command: | UV_VERSION=$(cat .uv-version) echo "export UV_VERSION=$UV_VERSION" >> $BASH_ENV # Python is managed by uv - it will automatically download the version # specified in docs/.python-version when needed - run: name: Install uv command: curl -LsSf https://astral.sh/uv/${UV_VERSION}/install.sh | sh - run: name: Add uv to PATH and set cache dir command: | echo 'export PATH="$HOME/.local/bin:$PATH"' >> $BASH_ENV echo 'export UV_CACHE_DIR="$HOME/.cache/uv"' >> $BASH_ENV - restore_cache: name: Restore uv cache keys: - uv-cache-v1-${UV_VERSION}-{{ checksum "docs/uv.lock" }} - uv-cache-v1-${UV_VERSION}- save-uv-cache: steps: - run: name: Prune uv cache for CI command: uv cache prune --ci - save_cache: name: Save uv cache key: uv-cache-v1-${UV_VERSION}-{{ checksum "docs/uv.lock" }} paths: - ~/.cache/uv install-zfs-from-source: parameters: zfs_release: type: string steps: - run: name: Record kernel version for cache key command: uname -r > /tmp/kernel-version - restore_cache: name: Restore ZFS native debs cache keys: - zfs-debs-v2-<>-{{ checksum "/tmp/kernel-version" }} - run: # https://openzfs.github.io/openzfs-docs/Developer%20Resources/Building%20ZFS.html name: Build ZFS <> native debs (if not cached) no_output_timeout: 20m command: | # CircleCI machine images have pyenv Python 3.13 shadowing the system # Python 3.12. The apt python3-* packages (setuptools, cffi, etc.) only # install for the system Python, and ZFS's dpkg-buildpackage needs them # for --enable-pyzfs. Use the system Python so apt packages are visible. export PYENV_VERSION=system if [ -d /tmp/zfs-debs ]; then echo "ZFS debs cache hit, skipping build" exit 0 fi sudo apt-get update sudo apt-get install -y \ alien autoconf automake build-essential debhelper-compat dh-autoreconf \ dh-dkms dh-python dkms fakeroot gawk git libaio-dev libattr1-dev \ libblkid-dev libcurl4-openssl-dev libelf-dev libffi-dev libpam0g-dev \ libssl-dev libtirpc-dev libtool libudev-dev linux-headers-$(uname -r) lsb-release \ parallel po-debconf python3 python3-all-dev python3-cffi python3-dev \ python3-packaging python3-setuptools python3-sphinx uuid-dev zlib1g-dev mkdir -p /tmp/zfs-build cd /tmp/zfs-build git clone --depth 1 --branch <> https://github.com/openzfs/zfs.git zfs-src cd zfs-src sh autogen.sh ./configure make native-deb mkdir -p /tmp/zfs-debs find /tmp/zfs-build -name '*.deb' -exec mv -t /tmp/zfs-debs/ {} + - save_cache: name: Save ZFS native debs cache key: zfs-debs-v2-<>-{{ checksum "/tmp/kernel-version" }} paths: - /tmp/zfs-debs - run: name: Install ZFS <> command: | ls /tmp/zfs-debs/ # Only install the debs we need. Exclude dracut (conflicts with # initramfs-tools), dkms (we have prebuilt modules), and packages # we don't need (pyzfs, test, doc). sudo apt-get install -y $(find /tmp/zfs-debs -name '*.deb' \ ! -name '*dracut*' \ ! -name '*dkms*' \ ! -name '*initramfs*' \ ! -name '*pyzfs*' \ ! -name '*doc*' \ ! -name '*test*' \ -print) sudo modprobe zfs - run: name: Verify ZFS version command: | sudo zfs version sudo zpool version docs-publish-sh: parameters: push: type: boolean steps: - checkout - run: command: | git config --global user.email "zreplbot@cschwarz.com" git config --global user.name "zrepl-github-io-ci" # Configure git to use the GitHub token for HTTPS authentication. # The token is stored in the 'zrepl-github-io-deploy' context. - when: condition: << parameters.push >> steps: - run: name: Configure git to use GitHub token for push # GITHUB_PAGES_TOKEN is from the 'zrepl-github-io-deploy' context. # CircleCI's secret masking automatically redacts context variables in logs. command: | # Unset CircleCI's SSH URL rewriting that checkout step configured git config --global --unset-all url."ssh://git@github.com".insteadOf || true # Set up credential helper with GitHub token git config --global credential.helper store echo "https://x-access-token:${GITHUB_PAGES_TOKEN}@github.com" > ~/.git-credentials chmod 600 ~/.git-credentials # caller must install-docdep - when: condition: << parameters.push >> steps: - run: bash -x docs/publish.sh -c -a -P - when: condition: not: << parameters.push >> steps: - run: bash -x docs/publish.sh -c -a parameters: do_ci: type: boolean default: true do_release: type: boolean default: false workflows: version: 2 ci: when: << pipeline.parameters.do_ci >> jobs: - run-docs-publish-sh: name: quickcheck-docs push: false - quickcheck-go: name: quickcheck-go-amd64-linux-1.25.7 goversion: &latest-go-release "1.25.7" goos: linux goarch: amd64 - test-go: goversion: *latest-go-release - quickcheck-go: requires: - quickcheck-go-amd64-linux-1.25.7 #quickcheck-go-smoketest.name matrix: alias: quickcheck-go-matrix parameters: goversion: [*latest-go-release, "1.24.13"] goos: ["linux", "freebsd"] goarch: ["amd64", "arm64"] exclude: # don't re-do quickcheck-go-smoketest - goversion: *latest-go-release goos: linux goarch: amd64 - platformtest: matrix: parameters: goversion: [*latest-go-release] goos: ["linux"] goarch: ["amd64"] zfs_release: ["zfs-2.2.9", "zfs-2.3.5", "zfs-2.4.0"] requires: - test-go - quickcheck-go-<< matrix.goarch >>-<< matrix.goos >>-<< matrix.goversion >> release: when: << pipeline.parameters.do_release >> jobs: - release-build - release-deb: requires: - release-build - release-rpm: requires: - release-build - release-upload: requires: - release-build - release-deb - release-rpm publish-zrepl.github.io: jobs: - run-docs-publish-sh: name: publish-zrepl.github.io push: true context: - zrepl-github-io-deploy filters: branches: only: - master jobs: run-docs-publish-sh: parameters: push: type: boolean docker: - image: cimg/base:current steps: - checkout - install-docdep - docs-publish-sh: push: << parameters.push >> - save-uv-cache quickcheck-go: parameters: goversion: type: string goos: type: string goarch: type: string docker: - image: &cimg_with_modern_go cimg/go:1.25 environment: GOOS: <> GOARCH: <> GOTOOLCHAIN: "go<>" steps: - checkout - go/load-cache: key: quickcheck-<> - run: make build/install - run: go mod download - run: cd build && go mod download - go/save-cache: key: quickcheck-<> # ensure all code has been generated - run: make generate - run: | if output=$(git status --porcelain) && [ -z "$output" ]; then echo "Working directory clean" else echo "Uncommitted changes" echo "" echo "$output" exit 1 fi # other checks - run: make zrepl-bin test-platform-bin - run: make vet - run: make lint - store_artifacts: path: artifacts - persist_to_workspace: root: . paths: [.] platformtest: parameters: goversion: type: string goos: type: string goarch: type: string zfs_release: type: string machine: # pinned (not :current) to keep ZFS build cache valid across runs image: ubuntu-2404:2025.09.1 resource_class: medium environment: GOOS: <> GOARCH: <> steps: - attach_workspace: at: . - install-zfs-from-source: zfs_release: <> - run: sudo make test-platform GOOS="$GOOS" GOARCH="$GOARCH" test-go: parameters: goversion: type: string docker: - image: *cimg_with_modern_go environment: GOTOOLCHAIN: "go<>" steps: - checkout - go/load-cache: key: make-test-go - run: make test-go - go/save-cache: key: make-test-go release-build: machine: image: &release-vm-image "ubuntu-2404:current" resource_class: large steps: - checkout - run: make release-docker - persist_to_workspace: root: . paths: [.] release-deb: machine: image: *release-vm-image steps: - attach_workspace: at: . - run: make debs-docker - persist_to_workspace: root: . paths: - "artifacts/*.deb" release-rpm: machine: image: *release-vm-image steps: - attach_workspace: at: . - run: make rpms-docker - persist_to_workspace: root: . paths: - "artifacts/*.rpm" release-upload: docker: - image: cimg/base:2024.09 steps: - attach_workspace: at: . - run: make wrapup-and-checksum - store_artifacts: path: artifacts/release