chore(release): prepare v2.1.0 (#349) #97
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: release | |
| on: | |
| push: | |
| tags: | |
| - "v*" | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: "Optional tag to build/release (e.g. v1.23.0). If empty, uses the current ref." | |
| required: false | |
| default: "" | |
| permissions: | |
| contents: write | |
| concurrency: | |
| group: release-${{ github.workflow }}-${{ github.event.inputs.tag || github.ref }} | |
| cancel-in-progress: false | |
| jobs: | |
| build-release: | |
| name: build (${{ matrix.vixos }} / ${{ matrix.arch }}) | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: ubuntu-22.04 | |
| vixos: linux | |
| arch: x86_64 | |
| - os: ubuntu-22.04-arm | |
| vixos: linux | |
| arch: aarch64 | |
| - os: macos-15-intel | |
| vixos: macos | |
| arch: x86_64 | |
| - os: macos-14 | |
| vixos: macos | |
| arch: aarch64 | |
| - os: windows-2022 | |
| vixos: windows | |
| arch: x86_64 | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| fetch-depth: 0 | |
| - name: Checkout tag (manual input) | |
| if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.tag != '' }} | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| git fetch --tags --force | |
| git checkout "tags/${{ github.event.inputs.tag }}" | |
| - name: Setup CMake | |
| uses: lukka/get-cmake@latest | |
| # ------------------------- | |
| # Linux deps (native x86_64) | |
| # ------------------------- | |
| - name: Install deps (Linux x86_64) | |
| if: runner.os == 'Linux' && matrix.arch == 'x86_64' | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| sudo apt-get update | |
| sudo apt-get install -y --no-install-recommends \ | |
| pkg-config ninja-build ca-certificates \ | |
| nlohmann-json3-dev \ | |
| libssl-dev \ | |
| zlib1g-dev \ | |
| libsqlite3-dev \ | |
| libbrotli-dev | |
| # ------------------------- | |
| # Linux aarch64 toolchain + arm64 dev libs (cross) | |
| # ------------------------- | |
| - name: Setup Linux aarch64 toolchain | |
| if: runner.os == 'Linux' && matrix.arch == 'aarch64' | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| sudo dpkg --add-architecture arm64 | |
| sudo apt-get update | |
| sudo apt-get install -y --no-install-recommends \ | |
| gcc-aarch64-linux-gnu g++-aarch64-linux-gnu \ | |
| pkg-config ninja-build ca-certificates \ | |
| nlohmann-json3-dev:arm64 \ | |
| libssl-dev:arm64 \ | |
| zlib1g-dev:arm64 \ | |
| libsqlite3-dev:arm64 \ | |
| libbrotli-dev:arm64 | |
| cat > toolchain-aarch64.cmake <<'EOF' | |
| set(CMAKE_SYSTEM_NAME Linux) | |
| set(CMAKE_SYSTEM_PROCESSOR aarch64) | |
| set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc) | |
| set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++) | |
| set(CMAKE_FIND_ROOT_PATH | |
| /usr/aarch64-linux-gnu | |
| /usr/lib/aarch64-linux-gnu | |
| /usr/include/aarch64-linux-gnu | |
| /usr | |
| ) | |
| set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) | |
| set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) | |
| set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) | |
| set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) | |
| # Force pkg-config to use arm64 .pc files (avoid host x86_64) | |
| set(PKG_CONFIG_EXECUTABLE /usr/bin/pkg-config) | |
| set(ENV{PKG_CONFIG_LIBDIR} "/usr/lib/aarch64-linux-gnu/pkgconfig:/usr/share/pkgconfig") | |
| set(ENV{PKG_CONFIG_PATH} "") | |
| EOF | |
| # ------------------------- | |
| # macOS deps | |
| # ------------------------- | |
| - name: Install deps (macOS) | |
| if: runner.os == 'macOS' | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| brew update | |
| brew install pkg-config openssl@3 | |
| # ------------------------- | |
| # Windows deps (OpenSSL via vcpkg) | |
| # ------------------------- | |
| - name: Setup vcpkg (Windows) | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: | | |
| git clone https://github.com/microsoft/vcpkg $env:GITHUB_WORKSPACE\vcpkg | |
| "VCPKG_ROOT=$env:GITHUB_WORKSPACE\vcpkg" | Out-File -FilePath $env:GITHUB_ENV -Append | |
| cd $env:GITHUB_WORKSPACE\vcpkg | |
| .\bootstrap-vcpkg.bat | |
| # ------------------------- | |
| # Configure (Unix) | |
| # ------------------------- | |
| - name: Configure (Unix) | |
| if: runner.os != 'Windows' | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| CMAKE_ARGS=( | |
| -S . -B build -G Ninja | |
| -DCMAKE_BUILD_TYPE=Release | |
| -DVIX_ENABLE_INSTALL=OFF | |
| -DVIX_DB_USE_MYSQL=OFF | |
| -DVIX_CORE_WITH_MYSQL=OFF | |
| -DVIX_ENABLE_HTTP_COMPRESSION=OFF | |
| ) | |
| if [ "${{ runner.os }}" = "Linux" ] && [ "${{ matrix.arch }}" = "aarch64" ]; then | |
| CMAKE_ARGS+=( | |
| -DCMAKE_TOOLCHAIN_FILE="${GITHUB_WORKSPACE}/toolchain-aarch64.cmake" | |
| ) | |
| fi | |
| if [ "${{ runner.os }}" = "macOS" ]; then | |
| if command -v brew >/dev/null 2>&1; then | |
| BREW_SSL="$(brew --prefix openssl@3 2>/dev/null || true)" | |
| if [ -n "$BREW_SSL" ] && [ -d "$BREW_SSL" ]; then | |
| CMAKE_ARGS+=(-DOPENSSL_ROOT_DIR="$BREW_SSL") | |
| fi | |
| fi | |
| fi | |
| : > cmake_output.log | |
| cmake "${CMAKE_ARGS[@]}" --log-level=VERBOSE --debug-output 2>&1 | tee -a cmake_output.log | |
| - name: Dump CMake logs (Unix) | |
| if: failure() && runner.os != 'Windows' | |
| shell: bash | |
| run: | | |
| set +e | |
| echo "=== build/ dir ===" | |
| ls -la build || true | |
| echo | |
| echo "=== CMakeError.log (tail) ===" | |
| test -f build/CMakeFiles/CMakeError.log && tail -n 250 build/CMakeFiles/CMakeError.log || echo "missing" | |
| echo | |
| echo "=== CMakeOutput.log (tail) ===" | |
| test -f build/CMakeFiles/CMakeOutput.log && tail -n 250 build/CMakeFiles/CMakeOutput.log || echo "missing" | |
| echo | |
| echo "=== CMakeConfigureLog.yaml (tail) ===" | |
| test -f build/CMakeFiles/CMakeConfigureLog.yaml && tail -n 250 build/CMakeFiles/CMakeConfigureLog.yaml || echo "missing" | |
| echo | |
| echo "=== cmake_output.log (tail) ===" | |
| test -f cmake_output.log && tail -n 200 cmake_output.log || echo "missing" | |
| - name: Build (Unix) | |
| if: runner.os != 'Windows' | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| : > build_output.log | |
| cmake --build build -j 2>&1 | tee -a build_output.log | |
| - name: Collect logs (Unix) | |
| if: always() && runner.os != 'Windows' | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| OUT="logs/${{ matrix.vixos }}-${{ matrix.arch }}" | |
| mkdir -p "$OUT" | |
| echo "logs collected" > "$OUT/_ok.txt" | |
| test -f cmake_output.log && cp -f cmake_output.log "$OUT/" || true | |
| test -f build_output.log && cp -f build_output.log "$OUT/" || true | |
| test -f build/CMakeCache.txt && cp -f build/CMakeCache.txt "$OUT/" || true | |
| test -f build/CMakeFiles/CMakeError.log && cp -f build/CMakeFiles/CMakeError.log "$OUT/" || true | |
| test -f build/CMakeFiles/CMakeOutput.log && cp -f build/CMakeFiles/CMakeOutput.log "$OUT/" || true | |
| test -f build/CMakeFiles/CMakeConfigureLog.yaml && cp -f build/CMakeFiles/CMakeConfigureLog.yaml "$OUT/" || true | |
| find logs -type f -maxdepth 3 -print || true | |
| - name: Upload logs (Unix) | |
| if: always() && runner.os != 'Windows' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: logs-${{ matrix.vixos }}-${{ matrix.arch }} | |
| path: logs/${{ matrix.vixos }}-${{ matrix.arch }}/* | |
| if-no-files-found: warn | |
| - name: Vcpkg install (manifest, Windows) | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: | | |
| Write-Host "VCPKG_ROOT=$env:VCPKG_ROOT" | |
| cd $env:GITHUB_WORKSPACE | |
| & "$env:VCPKG_ROOT\vcpkg.exe" install --triplet x64-windows --x-manifest-root "$env:GITHUB_WORKSPACE" | |
| if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } | |
| # ------------------------- | |
| # Configure + Build (Windows) | |
| # ------------------------- | |
| - name: Configure (Windows) | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: | | |
| "" | Out-File -FilePath cmake_output.log -Encoding utf8 | |
| Write-Host "VCPKG_ROOT=$env:VCPKG_ROOT" | |
| cmake -S . -B build -A x64 ` | |
| -DVIX_ENABLE_INSTALL=OFF ` | |
| -DVIX_DB_USE_MYSQL=OFF ` | |
| -DVIX_CORE_WITH_MYSQL=OFF ` | |
| -DVIX_ENABLE_HTTP_COMPRESSION=OFF ` | |
| -DVCPKG_TARGET_TRIPLET=x64-windows ` | |
| -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT\scripts\buildsystems\vcpkg.cmake" 2>&1 | Tee-Object -FilePath cmake_output.log -Append | |
| "CMAKE_CONFIGURE_EXIT=$LASTEXITCODE" | Out-File -FilePath $env:GITHUB_ENV -Append | |
| exit 0 | |
| - name: Dump vcpkg manifest log (Windows) | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: | | |
| if ($env:CMAKE_CONFIGURE_EXIT -eq "0") { | |
| Write-Host "Configure succeeded. No vcpkg dump needed." | |
| exit 0 | |
| } | |
| Write-Host "=== vcpkg-manifest-install.log ===" | |
| if (Test-Path "build\vcpkg-manifest-install.log") { | |
| Get-Content "build\vcpkg-manifest-install.log" -Raw | |
| } else { | |
| Write-Host "missing build\vcpkg-manifest-install.log" | |
| } | |
| Write-Host "=== vcpkg logs (last 200 lines each) ===" | |
| $logRoot = "$env:VCPKG_ROOT\buildtrees" | |
| if (Test-Path $logRoot) { | |
| Get-ChildItem -Recurse $logRoot -Filter "*.log" -ErrorAction SilentlyContinue | | |
| Sort-Object LastWriteTime -Descending | | |
| Select-Object -First 8 | | |
| ForEach-Object { | |
| Write-Host "`n--- $($_.FullName) ---" | |
| Get-Content $_.FullName -Tail 200 | |
| } | |
| } else { | |
| Write-Host "missing vcpkg buildtrees folder" | |
| } | |
| - name: Build (Windows) | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: | | |
| if ($env:CMAKE_CONFIGURE_EXIT -ne "0") { | |
| Write-Host "Configure failed (exit=$env:CMAKE_CONFIGURE_EXIT). Skipping build." | |
| exit 1 | |
| } | |
| "" | Out-File -FilePath build_output.log -Encoding utf8 | |
| cmake --build build --config Release 2>&1 | Tee-Object -FilePath build_output.log -Append | |
| if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } | |
| - name: Collect logs (Windows) | |
| if: always() && runner.os == 'Windows' | |
| shell: pwsh | |
| run: | | |
| $out = "logs/${{ matrix.vixos }}-${{ matrix.arch }}" | |
| New-Item -ItemType Directory -Force -Path $out | Out-Null | |
| if (Test-Path "cmake_output.log") { Copy-Item "cmake_output.log" $out -Force } | |
| if (Test-Path "build_output.log") { Copy-Item "build_output.log" $out -Force } | |
| if (Test-Path "build\CMakeCache.txt") { Copy-Item "build\CMakeCache.txt" $out -Force } | |
| if (Test-Path "build\CMakeFiles\CMakeError.log") { Copy-Item "build\CMakeFiles\CMakeError.log" $out -Force } | |
| if (Test-Path "build\CMakeFiles\CMakeOutput.log") { Copy-Item "build\CMakeFiles\CMakeOutput.log" $out -Force } | |
| if (Test-Path "build\CMakeFiles\CMakeConfigureLog.yaml") { Copy-Item "build\CMakeFiles\CMakeConfigureLog.yaml" $out -Force } | |
| if (Test-Path "build") { | |
| Compress-Archive -Path "build\*" -DestinationPath "$out\build.zip" -Force | |
| } | |
| - name: Upload logs (Windows) | |
| if: always() && runner.os == 'Windows' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: logs-${{ matrix.vixos }}-${{ matrix.arch }} | |
| path: logs/${{ matrix.vixos }}-${{ matrix.arch }}/* | |
| if-no-files-found: warn | |
| # ------------------------- | |
| # Package artifact | |
| # ------------------------- | |
| - name: Package (Unix) | |
| if: runner.os != 'Windows' | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| BIN="" | |
| for p in "build/vix" "build/bin/vix" "build/Release/vix"; do | |
| if [ -f "$p" ]; then BIN="$p"; break; fi | |
| done | |
| if [ -z "$BIN" ]; then | |
| echo "Expected vix binary not found. Listing build/ ..." >&2 | |
| ls -la build || true | |
| find build -maxdepth 6 -type f -name vix -print || true | |
| exit 1 | |
| fi | |
| mkdir -p dist | |
| cp "$BIN" dist/vix | |
| chmod +x dist/vix | |
| ASSET="vix-${{ matrix.vixos }}-${{ matrix.arch }}.tar.gz" | |
| tar -C dist -czf "dist/$ASSET" vix | |
| rm -f dist/vix | |
| - name: Package (Windows) | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: | | |
| $candidates = @( | |
| "build\vix.exe", | |
| "build\Release\vix.exe", | |
| "build\bin\vix.exe", | |
| "build\Release\bin\vix.exe" | |
| ) | |
| $bin = $null | |
| foreach ($p in $candidates) { | |
| if (Test-Path $p) { $bin = $p; break } | |
| } | |
| if (!$bin) { | |
| Write-Host "Expected vix.exe not found in build outputs" | |
| if (Test-Path "build") { Get-ChildItem -Recurse build | Select-Object FullName } | |
| exit 1 | |
| } | |
| New-Item -ItemType Directory -Force -Path dist | Out-Null | |
| Copy-Item $bin dist\vix.exe | |
| $asset = "vix-windows-${{ matrix.arch }}.zip" | |
| Compress-Archive -Path dist\vix.exe -DestinationPath "dist\$asset" -Force | |
| Remove-Item dist\vix.exe -Force | |
| - name: Upload dist | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: dist-${{ matrix.vixos }}-${{ matrix.arch }} | |
| path: dist/* | |
| if-no-files-found: error | |
| publish: | |
| name: publish (github release) | |
| needs: build-release | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: dist-all | |
| - name: Flatten dist only | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| mkdir -p dist | |
| find dist-all -type f -path "*/dist-*/vix-*" -print0 | while IFS= read -r -d '' f; do | |
| base="$(basename "$f")" | |
| if [ -f "dist/$base" ]; then | |
| echo "Collision while flattening: $base" >&2 | |
| echo "file: $f" >&2 | |
| exit 1 | |
| fi | |
| cp -f "$f" "dist/$base" | |
| done | |
| ls -la dist | |
| test "$(ls -A dist | wc -l)" -gt 0 | |
| - name: Generate sha256 files | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| cd dist | |
| for f in vix-*; do | |
| [ -f "$f" ] || continue | |
| sha256sum "$f" > "$f.sha256" | |
| done | |
| ls -la | |
| - name: Sign assets (minisign) | |
| shell: bash | |
| env: | |
| MINISIGN_PRIVATE_KEY_B64: ${{ secrets.MINISIGN_PRIVATE_KEY_B64 }} | |
| run: | | |
| set -euxo pipefail | |
| cd dist | |
| MS_VER="0.11" | |
| curl -fL --retry 10 --retry-delay 2 \ | |
| -o minisign-linux.tar.gz \ | |
| "https://github.com/jedisct1/minisign/releases/download/${MS_VER}/minisign-${MS_VER}-linux.tar.gz" | |
| tar -xzf minisign-linux.tar.gz | |
| chmod +x minisign-linux/x86_64/minisign | |
| MS="./minisign-linux/x86_64/minisign" | |
| keyfile="$(mktemp)" | |
| chmod 600 "$keyfile" | |
| printf "%s" "$MINISIGN_PRIVATE_KEY_B64" | base64 -d > "$keyfile" | |
| test -s "$keyfile" | |
| for f in vix-*.tar.gz vix-*.zip; do | |
| [ -f "$f" ] || continue | |
| "$MS" -S -s "$keyfile" -m "$f" | |
| done | |
| rm -f "$keyfile" | |
| ls -la | |
| - name: Determine tag | |
| id: tag | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ -n "${{ github.event.inputs.tag }}" ]; then | |
| echo "tag=${{ github.event.inputs.tag }}" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "tag=${GITHUB_REF_NAME}" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Create GitHub Release + upload | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ steps.tag.outputs.tag }} | |
| name: ${{ steps.tag.outputs.tag }} | |
| draft: false | |
| prerelease: false | |
| files: dist/* |