From 7d899fdc43328f9721108a7f95a024bf64391902 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Thu, 15 Jan 2026 21:08:55 -0800 Subject: [PATCH] Migrate nightly builds from Azure DevOps to GitHub Actions (#8206) * Initial plan * Add GitHub Actions workflow for nightly builds Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com> * Fix Windows builds to use --zip flag instead of manual archiving Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com> --- .github/workflows/nightly.yml | 593 ++++++++++++++++++++++++++++++++++ 1 file changed, 593 insertions(+) create mode 100644 .github/workflows/nightly.yml diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml new file mode 100644 index 000000000..85ed34b67 --- /dev/null +++ b/.github/workflows/nightly.yml @@ -0,0 +1,593 @@ +name: Nightly Build + +on: + schedule: + # Run at 2 AM UTC every day + - cron: '0 2 * * *' + workflow_dispatch: + inputs: + force_build: + description: 'Force nightly build' + required: false + default: 'true' + +permissions: + contents: write + +env: + MAJOR: '4' + MINOR: '15' + PATCH: '5' + +jobs: + # ============================================================================ + # BUILD STAGE + # ============================================================================ + + mac-build-x64: + name: "Mac Build x64" + runs-on: macos-13 + timeout-minutes: 90 + steps: + - name: Checkout code + uses: actions/checkout@v6.0.1 + + - name: Setup Python + uses: actions/setup-python@v6 + with: + python-version: '3.x' + + - name: Build + run: python scripts/mk_unix_dist.py --dotnet-key=$GITHUB_WORKSPACE/resources/z3.snk + + - name: Clone z3test + run: git clone https://github.com/z3prover/z3test z3test + + - name: Test + run: python z3test/scripts/test_benchmarks.py build-dist/z3 z3test/regressions/smt2 + + - name: Upload artifact + uses: actions/upload-artifact@v6 + with: + name: macOsBuild + path: dist/*.zip + retention-days: 2 + + mac-build-arm64: + name: "Mac ARM64 Build" + runs-on: macos-latest + timeout-minutes: 90 + steps: + - name: Checkout code + uses: actions/checkout@v6.0.1 + + - name: Setup Python + uses: actions/setup-python@v6 + with: + python-version: '3.x' + + - name: Build + run: python scripts/mk_unix_dist.py --dotnet-key=$GITHUB_WORKSPACE/resources/z3.snk --arch=arm64 + + - name: Clone z3test + run: git clone https://github.com/z3prover/z3test z3test + + - name: Upload artifact + uses: actions/upload-artifact@v6 + with: + name: MacArm64 + path: dist/*.zip + retention-days: 2 + + ubuntu-build: + name: "Ubuntu build" + runs-on: ubuntu-latest + timeout-minutes: 90 + steps: + - name: Checkout code + uses: actions/checkout@v6.0.1 + + - name: Setup Python + uses: actions/setup-python@v6 + with: + python-version: '3.x' + + - name: Build + run: python scripts/mk_unix_dist.py --dotnet-key=$GITHUB_WORKSPACE/resources/z3.snk + + - name: Clone z3test + run: git clone https://github.com/z3prover/z3test z3test + + - name: Test + run: python z3test/scripts/test_benchmarks.py build-dist/z3 z3test/regressions/smt2 + + - name: Upload artifact + uses: actions/upload-artifact@v6 + with: + name: UbuntuBuild + path: dist/*.zip + retention-days: 2 + + ubuntu-arm64: + name: "Ubuntu ARM64 build" + runs-on: ubuntu-latest + timeout-minutes: 90 + steps: + - name: Checkout code + uses: actions/checkout@v6.0.1 + + - name: Setup Python + uses: actions/setup-python@v6 + with: + python-version: '3.x' + + - name: Download ARM toolchain + run: curl -L -o /tmp/arm-toolchain.tar.xz 'https://developer.arm.com/-/media/Files/downloads/gnu/13.3.rel1/binrel/arm-gnu-toolchain-13.3.rel1-x86_64-aarch64-none-linux-gnu.tar.xz' + + - name: Extract ARM toolchain + run: | + mkdir -p /tmp/arm-toolchain/ + tar xf /tmp/arm-toolchain.tar.xz -C /tmp/arm-toolchain/ --strip-components=1 + + - name: Build + run: | + export PATH="/tmp/arm-toolchain/bin:/tmp/arm-toolchain/aarch64-none-linux-gnu/libc/usr/bin:$PATH" + echo $PATH + stat /tmp/arm-toolchain/bin/aarch64-none-linux-gnu-gcc + python scripts/mk_unix_dist.py --nodotnet --arch=arm64 + + - name: Upload artifact + uses: actions/upload-artifact@v6 + with: + name: UbuntuArm64 + path: dist/*.zip + retention-days: 2 + + ubuntu-doc: + name: "Ubuntu Doc build" + runs-on: ubuntu-latest + timeout-minutes: 90 + steps: + - name: Checkout code + uses: actions/checkout@v6.0.1 + + - name: Setup Python + uses: actions/setup-python@v6 + with: + python-version: '3.x' + + - name: Install dependencies + run: | + pip3 install importlib-resources + sudo apt-get update + sudo apt-get install -y ocaml opam libgmp-dev doxygen graphviz + + - name: Setup OCaml + run: | + opam init -y + eval $(opam config env) + opam install zarith ocamlfind -y + + - name: Build + run: | + eval $(opam config env) + python scripts/mk_make.py --ml + cd build + make -j3 + make -j3 examples + make -j3 test-z3 + cd .. + + - name: Generate documentation + run: | + eval $(opam config env) + cd doc + python3 mk_api_doc.py --mld --z3py-package-path=../build/python/z3 + python3 mk_params_doc.py + mkdir -p api/html/ml + ocamldoc -html -d api/html/ml -sort -hide Z3 -I $(ocamlfind query zarith) -I ../build/api/ml ../build/api/ml/z3enums.mli ../build/api/ml/z3.mli + cd .. + + - name: Create documentation archive + run: zip -r z3doc.zip doc/api + + - name: Upload artifact + uses: actions/upload-artifact@v6 + with: + name: UbuntuDoc + path: z3doc.zip + retention-days: 2 + + manylinux-python-amd64: + name: "Python bindings (manylinux AMD64)" + runs-on: ubuntu-latest + timeout-minutes: 90 + container: quay.io/pypa/manylinux2014_x86_64:latest + steps: + - name: Checkout code + uses: actions/checkout@v6.0.1 + + - name: Setup Python environment + run: | + /opt/python/cp38-cp38/bin/python -m venv $PWD/env + echo "$PWD/env/bin" >> $GITHUB_PATH + + - name: Install build tools + run: pip install build git+https://github.com/rhelmot/auditwheel + + - name: Build wheels + run: cd src/api/python && python -m build && AUDITWHEEL_PLAT= auditwheel repair --best-plat dist/*.whl && cd ../../.. + + - name: Test wheels + run: pip install ./src/api/python/wheelhouse/*.whl && python - > $GITHUB_PATH + echo "/tmp/arm-toolchain/bin" >> $GITHUB_PATH + echo "/tmp/arm-toolchain/aarch64-none-linux-gnu/libc/usr/bin" >> $GITHUB_PATH + + - name: Install build tools + run: | + echo $PATH + stat $(which aarch64-none-linux-gnu-gcc) + pip install build git+https://github.com/rhelmot/auditwheel + + - name: Build wheels + run: cd src/api/python && CC=aarch64-none-linux-gnu-gcc CXX=aarch64-none-linux-gnu-g++ AR=aarch64-none-linux-gnu-ar LD=aarch64-none-linux-gnu-ld Z3_CROSS_COMPILING=aarch64 python -m build && AUDITWHEEL_PLAT= auditwheel repair --best-plat dist/*.whl && cd ../../.. + + - name: Upload artifact + uses: actions/upload-artifact@v6 + with: + name: ManyLinuxPythonBuildArm64 + path: src/api/python/wheelhouse/*.whl + retention-days: 2 + + windows-build-x64: + name: "Windows x64 build" + runs-on: windows-latest + timeout-minutes: 120 + steps: + - name: Checkout code + uses: actions/checkout@v6.0.1 + + - name: Setup Python + uses: actions/setup-python@v6 + with: + python-version: '3.x' + + - name: Build + shell: cmd + run: | + call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64 + python scripts\mk_win_dist.py --x64-only --dotnet-key=%GITHUB_WORKSPACE%\resources\z3.snk --zip + + - name: Upload artifact + uses: actions/upload-artifact@v6 + with: + name: WindowsBuild-x64 + path: dist/*.zip + retention-days: 2 + + windows-build-x86: + name: "Windows x86 build" + runs-on: windows-latest + timeout-minutes: 120 + steps: + - name: Checkout code + uses: actions/checkout@v6.0.1 + + - name: Setup Python + uses: actions/setup-python@v6 + with: + python-version: '3.x' + + - name: Build + shell: cmd + run: | + call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x86 + python scripts\mk_win_dist.py --x86-only --dotnet-key=%GITHUB_WORKSPACE%\resources\z3.snk --zip + + - name: Upload artifact + uses: actions/upload-artifact@v6 + with: + name: WindowsBuild-x86 + path: dist/*.zip + retention-days: 2 + + windows-build-arm64: + name: "Windows ARM64 build" + runs-on: windows-latest + timeout-minutes: 90 + steps: + - name: Checkout code + uses: actions/checkout@v6.0.1 + + - name: Setup Python + uses: actions/setup-python@v6 + with: + python-version: '3.x' + + - name: Build + shell: cmd + run: | + call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" amd64_arm64 + python scripts\mk_win_dist_cmake.py --arm64-only --dotnet-key=%GITHUB_WORKSPACE%\resources\z3.snk --assembly-version=${{ env.MAJOR }}.${{ env.MINOR }}.${{ env.PATCH }} --zip + + - name: Upload artifact + uses: actions/upload-artifact@v6 + with: + name: WindowsBuild-arm64 + path: build-dist/arm64/dist/*.zip + retention-days: 2 + + # ============================================================================ + # PACKAGE STAGE + # ============================================================================ + + nuget-package-x64: + name: "NuGet 64 packaging" + needs: [windows-build-x64, windows-build-arm64, ubuntu-build, ubuntu-arm64, mac-build-x64, mac-build-arm64] + runs-on: windows-latest + steps: + - name: Checkout code + uses: actions/checkout@v6.0.1 + + - name: Setup Python + uses: actions/setup-python@v6 + with: + python-version: '3.x' + + - name: Download Win64 Build + uses: actions/download-artifact@v7.0.0 + with: + name: WindowsBuild-x64 + path: package + + - name: Download Win ARM64 Build + uses: actions/download-artifact@v7.0.0 + with: + name: WindowsBuild-arm64 + path: package + + - name: Download Ubuntu Build + uses: actions/download-artifact@v7.0.0 + with: + name: UbuntuBuild + path: package + + - name: Download Ubuntu ARM64 Build + uses: actions/download-artifact@v7.0.0 + with: + name: UbuntuArm64 + path: package + + - name: Download macOS Build + uses: actions/download-artifact@v7.0.0 + with: + name: macOsBuild + path: package + + - name: Download macOS Arm64 Build + uses: actions/download-artifact@v7.0.0 + with: + name: MacArm64 + path: package + + - name: Setup NuGet + uses: nuget/setup-nuget@v2 + with: + nuget-version: 'latest' + + - name: Assemble NuGet package + shell: cmd + run: | + cd package + python ..\scripts\mk_nuget_task.py . ${{ env.MAJOR }}.${{ env.MINOR }}.${{ env.PATCH }}.${{ github.run_number }} https://github.com/Z3Prover/z3 ${{ github.ref_name }} ${{ github.sha }} ${{ github.workspace }} symbols + + - name: Pack NuGet package + shell: cmd + run: | + cd package + nuget pack out\Microsoft.Z3.sym.nuspec -Version ${{ env.MAJOR }}.${{ env.MINOR }}.${{ env.PATCH }}.${{ github.run_number }} -OutputDirectory . -Verbosity detailed -Symbols -SymbolPackageFormat snupkg -BasePath out + + - name: Upload artifact + uses: actions/upload-artifact@v6 + with: + name: NuGet + path: | + package/*.nupkg + package/*.snupkg + retention-days: 2 + + nuget-package-x86: + name: "NuGet 32 packaging" + needs: [windows-build-x86] + runs-on: windows-latest + steps: + - name: Checkout code + uses: actions/checkout@v6.0.1 + + - name: Setup Python + uses: actions/setup-python@v6 + with: + python-version: '3.x' + + - name: Download artifacts + uses: actions/download-artifact@v7.0.0 + with: + name: WindowsBuild-x86 + path: package + + - name: Setup NuGet + uses: nuget/setup-nuget@v2 + with: + nuget-version: 'latest' + + - name: Assemble NuGet package + shell: cmd + run: | + cd package + python ..\scripts\mk_nuget_task.py . ${{ env.MAJOR }}.${{ env.MINOR }}.${{ env.PATCH }}.${{ github.run_number }} https://github.com/Z3Prover/z3 ${{ github.ref_name }} ${{ github.sha }} ${{ github.workspace }} symbols x86 + + - name: Pack NuGet package + shell: cmd + run: | + cd package + nuget pack out\Microsoft.Z3.x86.sym.nuspec -Version ${{ env.MAJOR }}.${{ env.MINOR }}.${{ env.PATCH }}.${{ github.run_number }} -OutputDirectory . -Verbosity detailed -Symbols -SymbolPackageFormat snupkg -BasePath out + + - name: Upload artifact + uses: actions/upload-artifact@v6 + with: + name: NuGet32 + path: | + package/*.nupkg + package/*.snupkg + retention-days: 2 + + python-package: + name: "Python packaging" + needs: [mac-build-x64, mac-build-arm64, windows-build-x64, windows-build-x86, manylinux-python-arm64] + runs-on: ubuntu-24.04 + steps: + - name: Checkout code + uses: actions/checkout@v6.0.1 + + - name: Setup Python + uses: actions/setup-python@v6 + with: + python-version: '3.x' + + - name: Download macOS x64 Build + uses: actions/download-artifact@v7.0.0 + with: + name: macOsBuild + path: artifacts + + - name: Download macOS Arm64 Build + uses: actions/download-artifact@v7.0.0 + with: + name: MacArm64 + path: artifacts + + - name: Download Win64 Build + uses: actions/download-artifact@v7.0.0 + with: + name: WindowsBuild-x64 + path: artifacts + + - name: Download Win32 Build + uses: actions/download-artifact@v7.0.0 + with: + name: WindowsBuild-x86 + path: artifacts + + - name: Download ManyLinux Arm64 Build + uses: actions/download-artifact@v7.0.0 + with: + name: ManyLinuxPythonBuildArm64 + path: artifacts + + - name: Extract builds + run: | + cd artifacts + mkdir -p osx-x64-bin osx-arm64-bin win32-bin win64-bin + cd osx-x64-bin && unzip ../*x64-osx*.zip && cd .. + cd osx-arm64-bin && unzip ../*arm64-osx*.zip && cd .. + cd win32-bin && unzip ../*x86-win*.zip && cd .. + cd win64-bin && unzip ../*x64-win*.zip && cd .. + + - name: Build Python packages + run: | + python3 -m pip install --user -U setuptools + cd src/api/python + python3 setup.py sdist + echo $PWD/../../../artifacts/win32-bin/* | xargs printf 'PACKAGE_FROM_RELEASE=%s\n' | xargs -I '{}' env '{}' python3 setup.py bdist_wheel + echo $PWD/../../../artifacts/win64-bin/* | xargs printf 'PACKAGE_FROM_RELEASE=%s\n' | xargs -I '{}' env '{}' python3 setup.py bdist_wheel + echo $PWD/../../../artifacts/osx-x64-bin/* | xargs printf 'PACKAGE_FROM_RELEASE=%s\n' | xargs -I '{}' env '{}' python3 setup.py bdist_wheel + echo $PWD/../../../artifacts/osx-arm64-bin/* | xargs printf 'PACKAGE_FROM_RELEASE=%s\n' | xargs -I '{}' env '{}' python3 setup.py bdist_wheel + cp $PWD/../../../artifacts/*.whl dist/ || true + + - name: Upload artifact + uses: actions/upload-artifact@v6 + with: + name: Python packages + path: src/api/python/dist/* + retention-days: 2 + + # ============================================================================ + # DEPLOYMENT STAGE + # ============================================================================ + + deploy-nightly: + name: "Deploy to GitHub Releases" + needs: [ + windows-build-x86, + windows-build-x64, + windows-build-arm64, + mac-build-x64, + mac-build-arm64, + ubuntu-build, + ubuntu-arm64, + ubuntu-doc, + python-package, + nuget-package-x64, + nuget-package-x86 + ] + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v6.0.1 + + - name: Download all artifacts + uses: actions/download-artifact@v7.0.0 + with: + path: tmp + + - name: Display structure of downloaded files + run: ls -R tmp + + - name: Delete existing Nightly release + continue-on-error: true + env: + GH_TOKEN: ${{ github.token }} + run: | + gh release delete Nightly --yes --cleanup-tag || true + + - name: Create Nightly release + env: + GH_TOKEN: ${{ github.token }} + run: | + find tmp -type f \( -name "*.zip" -o -name "*.whl" -o -name "*.tar.gz" -o -name "*.nupkg" -o -name "*.snupkg" \) > release_files.txt + + gh release create Nightly \ + --title "Nightly" \ + --notes "Automated nightly build from commit ${{ github.sha }}" \ + --prerelease \ + --target ${{ github.sha }} \ + $(cat release_files.txt | tr '\n' ' ')