-
Notifications
You must be signed in to change notification settings - Fork 0
275 lines (246 loc) · 10.4 KB
/
Copy pathbuild-plugin-binary.yml
File metadata and controls
275 lines (246 loc) · 10.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
name: Build Plugin Binary
on:
workflow_call:
inputs:
coretoolkit_ref:
description: CoreToolkit ref used for the reusable workflow checkout.
required: false
default: main
type: string
dependency_repos:
description: Newline-separated plugin repositories that must be exported to Conan before building.
required: false
default: ''
type: string
jobs:
build:
name: Build (${{ matrix.os }})
runs-on: ${{ matrix.os }}
permissions:
contents: write
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
os_slug: linux
arch_slug: x86_64
- os: macos-latest
os_slug: darwin
arch_slug: arm64
# windows-2022 (not windows-latest): ConanCenter publishes prebuilt
# binaries for MSVC 194 (VS 2022). windows-latest has begun moving to
# newer images whose MSVC (195) has NO prebuilt binaries on ConanCenter,
# which forced duckdb/boost/fmt/zlib/onetbb/... to all compile from
# source — and duckdb's bundled fmt fails to compile under MSVC 195,
# failing the job (so the Conan cache never got saved → every run cold).
- os: windows-2022
os_slug: windows
arch_slug: x86_64
outputs:
plugin_key: ${{ steps.bundle.outputs.plugin_key }}
plugin_version: ${{ steps.bundle.outputs.plugin_version }}
steps:
- name: Check out plugin repository
uses: actions/checkout@v4
with:
path: plugin
- name: Check out CoreToolkit
uses: actions/checkout@v4
with:
repository: ${{ github.repository_owner }}/CoreToolkit
ref: ${{ inputs.coretoolkit_ref }}
path: coretoolkit
- name: Set up MSVC developer shell
if: runner.os == 'Windows'
uses: ilammy/msvc-dev-cmd@v1
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install Conan and zstandard
shell: bash
run: |
set -euo pipefail
python -m pip install --upgrade pip conan zstandard
conan profile detect --force
# All third-party deps (duckdb, boost, onetbb, spdlog, fmt, zlib, ...) have
# prebuilt ConanCenter binaries for these pinned CI toolchains, so a clean
# run downloads rather than compiling. Persist the Conan package store
# between runs anyway so warm runs skip even the export/build of CoreToolkit
# itself. Keyed on CoreToolkit's conanfile so a dependency/option change
# invalidates the cache; restore-keys give a warm partial hit otherwise.
# Bump the v1 token to force a clean rebuild.
- name: Cache Conan packages
uses: actions/cache@v4
with:
path: ~/.conan2/p
key: conan-v1-${{ matrix.os }}-${{ hashFiles('coretoolkit/conanfile.py') }}
restore-keys: |
conan-v1-${{ matrix.os }}-
- name: Build plugin
id: build
shell: bash
run: |
set -euo pipefail
plugin_dir="$PWD/plugin"
coretoolkit_dir="$PWD/coretoolkit"
install_dir="$PWD/.ci-install"
mkdir -p "$install_dir"
conan export "$coretoolkit_dir"
coretoolkit_version="$(conan inspect "$coretoolkit_dir" --format=json | python3 -c 'import json,sys; print(json.load(sys.stdin)["version"])')"
if [[ -n '${{ inputs.dependency_repos }}' ]]; then
while IFS= read -r dependency_repo; do
dependency_repo="$(printf '%s' "$dependency_repo" | xargs)"
[[ -z "$dependency_repo" ]] && continue
dependency_dir="$PWD/$(basename "$dependency_repo")"
git clone --depth 1 "https://github.com/${GITHUB_REPOSITORY_OWNER}/${dependency_repo}" "$dependency_dir"
conan export "$dependency_dir"
done <<'EOF'
${{ inputs.dependency_repos }}
EOF
fi
# Volt's own C++ (CoreToolkit + the plugin) is C++23 and forces that
# standard through CMake (CMAKE_CXX_STANDARD 23 / cxx_std_23), so it
# does NOT rely on Conan's cppstd setting. Build the third-party deps
# at C++17 instead: it clears every dep's minimum on every compiler
# (including MSVC, whose detected default is 14), and the prebuilt
# ConanCenter binaries (duckdb, boost, ...) are available at cppstd=17,
# so they download rather than compiling. CoreToolkit is pinned back to
# 23 so its own package_id stays honest.
conan_args=(
-o "hwloc/*:shared=True"
--build=missing
-s build_type=Release
-s compiler.cppstd=17
-s "coretoolkit/*:compiler.cppstd=23"
)
# boost/*:without_stacktrace=True is a LINUX-ONLY fix. On Linux, boost
# 1.88 builds libboost_stacktrace_from_exception.a, which interposes
# __cxa_allocate_exception; linking the plugin with -static-libstdc++
# then hits "multiple definition of __cxa_allocate_exception" against
# libstdc++.a, so we drop the stacktrace libs (we only use Boost
# headers). It must NOT be set on macOS/Windows: ConanCenter ships no
# prebuilt boost binary with without_stacktrace=True for any OS, so
# setting it there forces boost to compile from source. macOS/Windows
# have no -static-libstdc++, so they don't need the fix anyway.
if [[ '${{ runner.os }}' == 'Linux' ]]; then
conan_args+=(-o "boost/*:without_stacktrace=True")
fi
# On Windows, pin MSVC to 194. ConanCenter only publishes prebuilt
# binaries for msvc 194 (not 195); if the runner image detects a newer
# toolset, every dep would compile from source (and duckdb's bundled fmt
# fails to build under MSVC 195). Do NOT set compiler.update — the
# published binaries carry no update value, so adding one breaks the
# package_id match.
if [[ '${{ runner.os }}' == 'Windows' ]]; then
conan_args+=(-s "compiler.version=194")
fi
conan install --requires="coretoolkit/${coretoolkit_version}" "${conan_args[@]}"
conan install "$plugin_dir" "${conan_args[@]}" \
--output-folder "$plugin_dir/build"
toolchain_path="$(find "$plugin_dir/build" -path '*/generators/conan_toolchain.cmake' | head -n 1)"
if [[ -z "$toolchain_path" ]]; then
echo 'Unable to locate conan_toolchain.cmake' >&2
exit 1
fi
build_dir="$(cd "$(dirname "$toolchain_path")/.." && pwd)"
cmake_args=(
-S "$plugin_dir"
-B "$build_dir"
"-DCMAKE_TOOLCHAIN_FILE=$toolchain_path"
-DCMAKE_BUILD_TYPE=Release
"-DCMAKE_INSTALL_PREFIX=$install_dir"
)
if [[ '${{ runner.os }}' == 'Linux' ]]; then
cmake_args+=(
"-DCMAKE_EXE_LINKER_FLAGS=-static-libstdc++ -static-libgcc -Wl,--disable-new-dtags"
'-DCMAKE_INSTALL_RPATH=$ORIGIN/../lib'
)
elif [[ '${{ runner.os }}' == 'macOS' ]]; then
cmake_args+=('-DCMAKE_INSTALL_RPATH=@loader_path/../lib')
fi
cmake "${cmake_args[@]}"
cmake --build "$build_dir" --config Release --parallel
cmake --install "$build_dir" --config Release
echo "install_dir=$install_dir" >> "$GITHUB_OUTPUT"
echo "plugin_dir=$plugin_dir" >> "$GITHUB_OUTPUT"
- name: Bundle plugin
id: bundle
shell: bash
env:
PLUGIN_DIR: ${{ steps.build.outputs.plugin_dir }}
INSTALL_DIR: ${{ steps.build.outputs.install_dir }}
OS_SLUG: ${{ matrix.os_slug }}
ARCH_SLUG: ${{ matrix.arch_slug }}
run: |
set -euo pipefail
mkdir -p artifacts
python "$GITHUB_WORKSPACE/coretoolkit/.github/scripts/build_plugin_bundle.py" \
--plugin-dir "$PLUGIN_DIR" \
--install-dir "$INSTALL_DIR" \
--os "$OS_SLUG" \
--arch "$ARCH_SLUG" \
--output-dir "$PWD/artifacts"
- name: Upload bundle artifact
if: steps.bundle.outputs.plugin_key != ''
uses: actions/upload-artifact@v4
with:
name: bundle-${{ matrix.os_slug }}-${{ matrix.arch_slug }}
path: artifacts/*
retention-days: 7
if-no-files-found: error
release:
name: Publish release
needs: build
if: needs.build.outputs.plugin_key != '' && startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Download bundles
uses: actions/download-artifact@v4
with:
path: artifacts
pattern: bundle-*
merge-multiple: true
- name: Publish release
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ needs.build.outputs.plugin_version }}
name: ${{ needs.build.outputs.plugin_key }} v${{ needs.build.outputs.plugin_version }}
files: artifacts/*
fail_on_unmatched_files: false
publish:
name: Publish to registry
needs: build
if: needs.build.outputs.plugin_key != '' && startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
steps:
- name: Check out plugin repository
uses: actions/checkout@v4
with:
path: plugin
- name: Download bundles
uses: actions/download-artifact@v4
with:
path: artifacts
pattern: bundle-*
merge-multiple: true
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install vpm
run: npm install -g @voltstack/vpm
- name: Verify committed vpm.json
run: test -f plugin/vpm.json || { echo "::error::plugin/vpm.json is required (the registry manifest is no longer generated)"; exit 1; }
- name: Publish to registry
env:
VPM_NO_KEYRING: '1'
VPM_PUBLISH_TOKEN: ${{ secrets.VPM_PUBLISH_TOKEN }}
run: |
vpm publish plugin --token "$VPM_PUBLISH_TOKEN" \
--bundle linux-x86_64=$(ls artifacts/*-linux-x86_64.tar.zst) \
--bundle darwin-arm64=$(ls artifacts/*-darwin-arm64.tar.zst) \
--bundle windows-x86_64=$(ls artifacts/*-windows-x86_64.tar.zst)