Skip to content

chore(release): prepare v2.1.0 (#349) #97

chore(release): prepare v2.1.0 (#349)

chore(release): prepare v2.1.0 (#349) #97

Workflow file for this run

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/*