blob: db2d754be8eaa8540a6f7ba3c96be19f128ba105 [file]
# Publish-oriented packaging workflow:
# - manual runs, release:published, v* tags
# - rc/** pushes only when C++-related paths change (job should-package)
# release events always use the workflow file from the default branch.
name: C++ Client package
on:
workflow_dispatch:
inputs:
variants:
description: "Which packages to build"
required: false
default: all
type: choice
options:
- all
- linux
- macos
- windows
- windows-vs2017
- windows-vs2019
- windows-vs2022
- windows-vs2026
release:
types: [published]
push:
branches:
- "rc/**"
tags:
- "v*"
concurrency:
group: client-cpp-package-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
MAVEN_OPTS: -Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false -Dmaven.wagon.http.retryHandler.class=standard -Dmaven.wagon.http.retryHandler.count=3
MAVEN_ARGS: --batch-mode --no-transfer-progress
jobs:
should-package:
# Keep rc branch cost low: skip full matrix when unrelated files change.
runs-on: ubuntu-latest
outputs:
run: ${{ steps.result.outputs.run }}
steps:
- uses: actions/checkout@v5
if: github.event_name == 'push' && startsWith(github.ref, 'refs/heads/rc/')
- uses: dorny/paths-filter@v3
id: filter
if: github.event_name == 'push' && startsWith(github.ref, 'refs/heads/rc/')
with:
filters: |
cpp:
- 'iotdb-client/client-cpp/**'
- 'iotdb-client/pom.xml'
- 'iotdb-protocol/thrift-datanode/src/main/thrift/client.thrift'
- 'iotdb-protocol/thrift-commons/src/main/thrift/common.thrift'
- '.github/workflows/client-cpp-package.yml'
- '.github/scripts/package-client-cpp-*.sh'
- id: result
shell: bash
run: |
set -euo pipefail
E="${{ github.event_name }}"
R="${{ github.ref }}"
if [[ "$E" == "workflow_dispatch" ]] || [[ "$E" == "release" ]]; then
echo "run=true" >> "$GITHUB_OUTPUT"
exit 0
fi
if [[ "$E" == "push" ]] && [[ "$R" == refs/tags/v* ]]; then
echo "run=true" >> "$GITHUB_OUTPUT"
exit 0
fi
if [[ "$E" == "push" ]] && [[ "$R" =~ ^refs/heads/rc/ ]]; then
if [[ "${{ steps.filter.outputs.cpp }}" == "true" ]]; then
echo "run=true" >> "$GITHUB_OUTPUT"
else
echo "run=false" >> "$GITHUB_OUTPUT"
fi
exit 0
fi
echo "run=false" >> "$GITHUB_OUTPUT"
resolve-matrix:
name: Resolve package matrix
needs: should-package
if: needs.should-package.outputs.run == 'true'
runs-on: ubuntu-latest
outputs:
run_linux: ${{ steps.filter.outputs.run_linux }}
run_macos: ${{ steps.filter.outputs.run_macos }}
run_windows: ${{ steps.filter.outputs.run_windows }}
windows_matrix: ${{ steps.filter.outputs.windows_matrix }}
steps:
- id: filter
# Resolve workflow_dispatch variants to a compact matrix payload for fromJSON().
shell: bash
run: |
set -euo pipefail
VARIANT="${{ github.event.inputs.variants || 'all' }}"
run_linux=false
run_macos=false
run_windows=false
case "$VARIANT" in
all)
run_linux=true
run_macos=true
run_windows=true
;;
linux) run_linux=true ;;
macos) run_macos=true ;;
windows) run_windows=true ;;
windows-vs2017|windows-vs2019|windows-vs2022|windows-vs2026)
run_windows=true
;;
*)
echo "Unknown variant: $VARIANT" >&2
exit 1
;;
esac
echo "run_linux=${run_linux}" >> "$GITHUB_OUTPUT"
echo "run_macos=${run_macos}" >> "$GITHUB_OUTPUT"
echo "run_windows=${run_windows}" >> "$GITHUB_OUTPUT"
# Compact JSON (no leading whitespace); required for GITHUB_OUTPUT + fromJSON().
WINDOWS_MATRIX='[{"name":"windows-vs2026","runs-on":"windows-2025-vs2026","boost_choco":"","boost_choco_version":"","cmake_generator":"Visual Studio 18 2026","package_classifier":"windows-x86_64-msvc14.4","vs_choco":"","vs_choco_params":""},{"name":"windows-vs2022","runs-on":"windows-2022","boost_choco":"","boost_choco_version":"","cmake_generator":"","package_classifier":"windows-x86_64-msvc14.3","vs_choco":"","vs_choco_params":""},{"name":"windows-vs2019","runs-on":"windows-2022","boost_choco":"","boost_choco_version":"","cmake_generator":"Visual Studio 16 2019","package_classifier":"windows-x86_64-msvc14.2","vs_choco":"visualstudio2019buildtools","vs_choco_params":"--add Microsoft.VisualStudio.Workload.VCTools --includeRecommended"},{"name":"windows-vs2017","runs-on":"windows-2022","boost_choco":"","boost_choco_version":"","cmake_generator":"Visual Studio 15 2017","package_classifier":"windows-x86_64-msvc14.1","vs_choco":"visualstudio2017buildtools","vs_choco_params":"--add Microsoft.VisualStudio.Workload.VCTools --includeRecommended"}]'
write_windows_matrix_output() {
local matrix_json="$1"
{
echo 'windows_matrix<<__MATRIX_EOF__'
echo "${matrix_json}"
echo '__MATRIX_EOF__'
} >> "$GITHUB_OUTPUT"
}
if [[ "$run_windows" == true ]]; then
if [[ "$VARIANT" == all || "$VARIANT" == windows ]]; then
FILTERED="$WINDOWS_MATRIX"
elif [[ "$VARIANT" =~ ^windows-vs ]]; then
FILTERED=$(echo "$WINDOWS_MATRIX" | jq -c --arg v "$VARIANT" '[.[] | select(.name == $v)]')
else
FILTERED='[]'
fi
if [[ $(echo "$FILTERED" | jq 'length') -eq 0 ]]; then
echo "No Windows matrix rows for variant=${VARIANT}" >&2
exit 1
fi
FILTERED=$(echo "$FILTERED" | jq -c '.')
write_windows_matrix_output "${FILTERED}"
else
write_windows_matrix_output '[]'
fi
package-linux-glibc228:
name: Package (linux-x86_64-glibc2.28)
needs: [should-package, resolve-matrix]
if: needs.should-package.outputs.run == 'true' && needs.resolve-matrix.outputs.run_linux == 'true'
# Checkout/cache on host (Node actions need modern glibc); build in manylinux_2_28 via docker run.
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Cache Maven packages
uses: actions/cache@v5
with:
path: ~/.m2
key: linux-glibc228-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: |
linux-glibc228-m2-
- name: Package client-cpp (glibc 2.28 baseline)
shell: bash
run: |
set -euxo pipefail
chmod +x .github/scripts/package-client-cpp-manylinux228.sh
docker run --rm \
-v "${{ github.workspace }}:/workspace" \
-v "${HOME}/.m2:/root/.m2" \
-w /workspace \
-e GITHUB_WORKSPACE=/workspace \
quay.io/pypa/manylinux_2_28_x86_64 \
bash .github/scripts/package-client-cpp-manylinux228.sh
- name: Restore workspace ownership after container build
if: always()
run: sudo chown -R "$(id -u):$(id -g)" "${{ github.workspace }}"
- name: Resolve package zip
id: pkg
shell: bash
run: |
set -euo pipefail
shopt -s nullglob
packages=(iotdb-client/client-cpp/target/iotdb-session-cpp-*-linux-x86_64-glibc2.28.zip)
if [ "${#packages[@]}" -ne 1 ]; then
echo "Expected exactly one package zip, got: ${packages[*]:-(none)}"
exit 1
fi
echo "path=${packages[0]}" >> "$GITHUB_OUTPUT"
echo "name=$(basename "${packages[0]}" .zip)" >> "$GITHUB_OUTPUT"
sha512="${packages[0]}.sha512"
if [ ! -f "${sha512}" ]; then
echo "Expected checksum file: ${sha512}"
exit 1
fi
echo "sha512_path=${sha512}" >> "$GITHUB_OUTPUT"
- name: Upload zip artifact
uses: actions/upload-artifact@v6
with:
name: ${{ steps.pkg.outputs.name }}
path: |
${{ steps.pkg.outputs.path }}
${{ steps.pkg.outputs.sha512_path }}
if-no-files-found: error
package-linux-aarch64-glibc228:
name: Package (linux-aarch64-glibc2.28)
needs: [should-package, resolve-matrix]
if: needs.should-package.outputs.run == 'true' && needs.resolve-matrix.outputs.run_linux == 'true'
# Checkout/cache on host; build in manylinux_2_28 aarch64 via docker run (glibc 2.28 baseline).
runs-on: ubuntu-22.04-arm
steps:
- uses: actions/checkout@v5
- name: Cache Maven packages
uses: actions/cache@v5
with:
path: ~/.m2
key: linux-aarch64-glibc228-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: |
linux-aarch64-glibc228-m2-
- name: Package client-cpp (glibc 2.28 baseline)
shell: bash
run: |
set -euxo pipefail
chmod +x .github/scripts/package-client-cpp-manylinux228.sh
docker run --rm \
-v "${{ github.workspace }}:/workspace" \
-v "${HOME}/.m2:/root/.m2" \
-w /workspace \
-e GITHUB_WORKSPACE=/workspace \
quay.io/pypa/manylinux_2_28_aarch64 \
bash .github/scripts/package-client-cpp-manylinux228.sh
- name: Restore workspace ownership after container build
if: always()
run: sudo chown -R "$(id -u):$(id -g)" "${{ github.workspace }}"
- name: Resolve package zip
id: pkg
shell: bash
run: |
set -euo pipefail
shopt -s nullglob
packages=(iotdb-client/client-cpp/target/iotdb-session-cpp-*-linux-aarch64-glibc2.28.zip)
if [ "${#packages[@]}" -ne 1 ]; then
echo "Expected exactly one package zip, got: ${packages[*]:-(none)}"
exit 1
fi
echo "path=${packages[0]}" >> "$GITHUB_OUTPUT"
echo "name=$(basename "${packages[0]}" .zip)" >> "$GITHUB_OUTPUT"
sha512="${packages[0]}.sha512"
if [ ! -f "${sha512}" ]; then
echo "Expected checksum file: ${sha512}"
exit 1
fi
echo "sha512_path=${sha512}" >> "$GITHUB_OUTPUT"
- name: Upload zip artifact
uses: actions/upload-artifact@v6
with:
name: ${{ steps.pkg.outputs.name }}
path: |
${{ steps.pkg.outputs.path }}
${{ steps.pkg.outputs.sha512_path }}
if-no-files-found: error
package-macos:
name: Package (${{ matrix.name }})
needs: [should-package, resolve-matrix]
if: needs.should-package.outputs.run == 'true' && needs.resolve-matrix.outputs.run_macos == 'true'
strategy:
fail-fast: false
matrix:
include:
- name: macos-x86_64
runs-on: macos-15-intel
- name: macos-arm64
runs-on: macos-latest
runs-on: ${{ matrix.runs-on }}
steps:
- uses: actions/checkout@v5
- name: Set up JDK 17
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: "17"
- name: Install C++ dependencies (macOS)
shell: bash
run: |
set -euxo pipefail
brew install boost openssl llvm@17 bison
ln -sf "$(brew --prefix llvm@17)/bin/clang-format" "$(brew --prefix)/bin/clang-format"
echo "$(brew --prefix bison)/bin" >> "$GITHUB_PATH"
echo "$(brew --prefix llvm@17)/bin" >> "$GITHUB_PATH"
clang-format --version
bison --version
- name: Cache Maven packages
uses: actions/cache@v5
with:
path: ~/.m2
key: macos-${{ matrix.name }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: |
macos-${{ matrix.name }}-m2-
- name: Package client-cpp
shell: bash
env:
MACOSX_DEPLOYMENT_TARGET: "12.0"
run: |
set -euxo pipefail
./mvnw clean package -P with-cpp -pl iotdb-client/client-cpp -am -DskipTests \
-Dspotless.skip=true
- name: Resolve package zip
id: pkg
shell: bash
run: |
set -euo pipefail
shopt -s nullglob
packages=(iotdb-client/client-cpp/target/iotdb-session-cpp-*.zip)
if [ "${#packages[@]}" -ne 1 ]; then
echo "Expected exactly one package zip, got: ${packages[*]:-(none)}"
exit 1
fi
echo "path=${packages[0]}" >> "$GITHUB_OUTPUT"
echo "name=$(basename "${packages[0]}" .zip)" >> "$GITHUB_OUTPUT"
sha512="${packages[0]}.sha512"
if [ ! -f "${sha512}" ]; then
echo "Expected checksum file: ${sha512}"
exit 1
fi
echo "sha512_path=${sha512}" >> "$GITHUB_OUTPUT"
- name: Upload zip artifact
uses: actions/upload-artifact@v6
with:
name: ${{ steps.pkg.outputs.name }}
path: |
${{ steps.pkg.outputs.path }}
${{ steps.pkg.outputs.sha512_path }}
if-no-files-found: error
package-windows:
name: Package (${{ matrix.name }})
needs: [should-package, resolve-matrix]
if: needs.should-package.outputs.run == 'true' && needs.resolve-matrix.outputs.run_windows == 'true'
strategy:
fail-fast: false
matrix:
include: ${{ fromJSON(needs.resolve-matrix.outputs.windows_matrix) }}
runs-on: ${{ matrix.runs-on }}
steps:
- uses: actions/checkout@v5
- name: Set up JDK 17
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: "17"
- name: Install Visual Studio Build Tools (${{ matrix.name }})
if: matrix.vs_choco != ''
shell: pwsh
run: |
$params = '${{ matrix.vs_choco_params }}'
if ($params) {
choco install ${{ matrix.vs_choco }} -y --package-parameters="$params" --no-progress
} else {
choco install ${{ matrix.vs_choco }} -y --no-progress
}
- name: Install C++ dependencies (Windows)
shell: pwsh
run: |
choco install winflexbison3 -y --no-progress
if ('${{ matrix.boost_choco }}' -ne '') {
$boostArgs = @('install', '${{ matrix.boost_choco }}', '-y', '--no-progress')
if ('${{ matrix.boost_choco_version }}' -ne '') {
$boostArgs += @("--version=${{ matrix.boost_choco_version }}")
}
& choco @boostArgs
$boostDir = Get-ChildItem -Path 'C:\local\' -Filter 'boost_*' -ErrorAction SilentlyContinue | Select-Object -First 1
if (-not $boostDir) {
throw "Boost not found under C:\local after installing ${{ matrix.boost_choco }}"
}
echo "BOOST_INCLUDEDIR=$($boostDir.FullName)" >> $env:GITHUB_ENV
}
- name: Cache Maven packages
uses: actions/cache@v5
with:
path: ~/.m2
key: windows-${{ matrix.name }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: |
windows-${{ matrix.name }}-m2-
- name: Package client-cpp
shell: bash
env:
CMAKE_GENERATOR: ${{ matrix.cmake_generator }}
PACKAGE_CLASSIFIER: ${{ matrix.package_classifier }}
run: |
set -euxo pipefail
MVN_ARGS=(./mvnw clean package -P with-cpp -pl iotdb-client/client-cpp -am -DskipTests \
-Dspotless.skip=true \
"-Dclient.cpp.package.classifier=${PACKAGE_CLASSIFIER}")
if [ -n "${BOOST_INCLUDEDIR:-}" ]; then
MVN_ARGS+=("-Dboost.include.dir=${BOOST_INCLUDEDIR}")
fi
if [ -n "${CMAKE_GENERATOR:-}" ]; then
MVN_ARGS+=("-Dcmake.generator=${CMAKE_GENERATOR}")
fi
"${MVN_ARGS[@]}"
- name: Verify Windows SDK is x64
# Guard against accidental Win32 generator defaults on legacy VS matrices.
shell: pwsh
run: |
$dll = "iotdb-client/client-cpp/target/install/lib/iotdb_session.dll"
if (-not (Test-Path $dll)) {
throw "Missing $dll"
}
$bytes = [System.IO.File]::ReadAllBytes($dll)
$peOffset = [BitConverter]::ToInt32($bytes, 0x3C)
$machine = [BitConverter]::ToUInt16($bytes, $peOffset + 4)
if ($machine -ne 0x8664) {
throw "Expected PE32+ x64 (machine=0x8664), got 0x$($machine.ToString('X4'))"
}
Write-Host "Verified x64 DLL: $dll"
- name: Resolve package zip
id: pkg
shell: bash
run: |
set -euo pipefail
shopt -s nullglob
packages=(iotdb-client/client-cpp/target/iotdb-session-cpp-*-${{ matrix.package_classifier }}.zip)
if [ "${#packages[@]}" -ne 1 ]; then
echo "Expected exactly one package zip, got: ${packages[*]:-(none)}"
exit 1
fi
echo "path=${packages[0]}" >> "$GITHUB_OUTPUT"
echo "name=$(basename "${packages[0]}" .zip)" >> "$GITHUB_OUTPUT"
sha512="${packages[0]}.sha512"
if [ ! -f "${sha512}" ]; then
echo "Expected checksum file: ${sha512}"
exit 1
fi
echo "sha512_path=${sha512}" >> "$GITHUB_OUTPUT"
- name: Upload zip artifact
uses: actions/upload-artifact@v6
with:
name: ${{ steps.pkg.outputs.name }}
path: |
${{ steps.pkg.outputs.path }}
${{ steps.pkg.outputs.sha512_path }}
if-no-files-found: error