From f17c0c642f89a204490e819f6be4e4b07d711831 Mon Sep 17 00:00:00 2001 From: Eugene Palchukovsky Date: Fri, 24 Jul 2026 00:22:10 +0300 Subject: [PATCH 1/2] Add C++ vcpkg release delivery --- .github/workflows/release.yml | 395 +++++++++++++++++++- bindings/cpp/CMakeLists.txt | 19 +- bindings/cpp/README.md | 52 ++- bindings/cpp/cmake/OpenPitConfig.cmake.in | 2 +- e2e/README.md | 3 +- e2e/clients/cpp/CMakeLists.txt | 1 + e2e/env/docker/cpp-distributable/Dockerfile | 1 + e2e/env/docker/cpp-vcpkg/Dockerfile | 43 +++ e2e/run.sh | 68 ++++ e2e/scripts/cpp-distributable.sh | 94 ++++- e2e/scripts/cpp-vcpkg.sh | 229 ++++++++++++ justfile | 6 + packaging/vcpkg/openpit/portfile.cmake.in | 50 +++ packaging/vcpkg/openpit/vcpkg.json.in | 18 + pipeline.just | 5 +- scripts/just_helpers.py | 4 + scripts/materialize_vcpkg_port.py | 68 ++++ 17 files changed, 1014 insertions(+), 44 deletions(-) create mode 100644 e2e/env/docker/cpp-vcpkg/Dockerfile create mode 100644 e2e/scripts/cpp-vcpkg.sh create mode 100644 packaging/vcpkg/openpit/portfile.cmake.in create mode 100644 packaging/vcpkg/openpit/vcpkg.json.in create mode 100644 scripts/materialize_vcpkg_port.py diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d6fbdf47..914c46f6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,3 +1,20 @@ +# Copyright The Pit Project Owners. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Please see https://openpit.dev and the OWNERS file for details. + name: Release on: @@ -114,6 +131,9 @@ jobs: - publish-sdist - publish-npm - build-runtime-artifacts + # Keep publication serialized until the managed vcpkg deployment is + # proven in production; then make this dependency parallel again. + - publish-vcpkg-registry runs-on: ubuntu-22.04 permissions: contents: read @@ -164,11 +184,11 @@ jobs: publish-wheels: name: Publish wheels (${{ matrix.name }}) - # Keep the first npm publication serialized before other registries. Restore - # parallel publishing after the npm release path has been proven in production. needs: - - publish-npm - verify-tag + # Keep publication serialized until the managed vcpkg deployment is + # proven in production; then make this dependency parallel again. + - publish-vcpkg-registry runs-on: ${{ matrix.os }} strategy: fail-fast: false @@ -346,6 +366,9 @@ jobs: needs: - publish-wheels - verify-tag + # Keep publication serialized until the managed vcpkg deployment is + # proven in production; then make this dependency parallel again. + - publish-vcpkg-registry runs-on: ubuntu-22.04 steps: - name: Checkout @@ -450,6 +473,9 @@ jobs: needs: - verify - verify-tag + # Keep publication serialized until the managed vcpkg deployment is + # proven in production; then make this dependency parallel again. + - publish-vcpkg-registry runs-on: ubuntu-22.04 permissions: contents: read @@ -738,6 +764,9 @@ jobs: - name: Build C++ binding shell: bash + env: + OPENPIT_PACKAGE_VERSION: ${{ needs.verify-tag.outputs.base_version }} + OPENPIT_RUNTIME_VERSION: ${{ needs.verify-tag.outputs.version }} run: just build-cpp-release - name: Install C++ binding into staging prefix @@ -755,7 +784,7 @@ jobs: - name: Package C++ distributable shell: bash env: - VERSION: ${{ needs.verify-tag.outputs.version }} + OPENPIT_RELEASE_VERSION: ${{ needs.verify-tag.outputs.version }} run: just --justfile "$JUSTFILE" package-cpp /tmp/openpit-cpp-install - name: Upload C++ artifact @@ -775,6 +804,261 @@ jobs: if-no-files-found: error retention-days: 1 + publish-vcpkg-registry: + name: Publish OpenPit vcpkg registry port + needs: + - build-runtime-artifacts + - verify + - verify-tag + runs-on: ubuntu-22.04 + outputs: + registry_baseline: ${{ steps.publish.outputs.registry_baseline }} + permissions: + contents: read + concurrency: + group: openpit-vcpkg-registry + cancel-in-progress: false + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Download Linux runtime artifact + uses: actions/download-artifact@v4 + with: + name: runtime-linux-amd64 + path: ${{ runner.temp }}/openpit-vcpkg-runtime + + - name: Bootstrap vcpkg + shell: bash + run: | + set -euo pipefail + git clone --depth 1 https://github.com/microsoft/vcpkg.git \ + "$RUNNER_TEMP/vcpkg" + "$RUNNER_TEMP/vcpkg/bootstrap-vcpkg.sh" -disableMetrics + + - name: Materialize, publish, and verify the registry port + id: publish + shell: bash + env: + BASE_VERSION: ${{ needs.verify-tag.outputs.base_version }} + RELEASE_MODE: ${{ needs.verify-tag.outputs.release_mode }} + VERSION: ${{ needs.verify-tag.outputs.version }} + VCPKG_REGISTRY_PUSH_TOKEN: ${{ secrets.VCPKG_REGISTRY_PUSH_TOKEN }} + run: | + set -euo pipefail + + VCPKG_ROOT="$RUNNER_TEMP/vcpkg" + RUNTIME_LIBRARY="$RUNNER_TEMP/openpit-vcpkg-runtime/openpit-ffi--linux-amd64-libopenpit_ffi.so" + RENDERED_PORT="$RUNNER_TEMP/openpit-vcpkg-port" + REGISTRY_DIR="$RUNNER_TEMP/openpit-vcpkg-registry" + VERIFY_ROOT="$RUNNER_TEMP/openpit-vcpkg-verify" + SOURCE_REF="v${VERSION}" + if [[ "${RELEASE_MODE}" == "dry-run" ]]; then + SOURCE_REF="${GITHUB_SHA}" + fi + + if [[ ! -f "${RUNTIME_LIBRARY}" ]]; then + echo "::error::missing Linux runtime artifact: ${RUNTIME_LIBRARY}" + exit 1 + fi + + source_archive="$RUNNER_TEMP/openpit-source.tar.gz" + curl --proto '=https' --tlsv1.2 --retry 3 --fail --location \ + --silent --show-error \ + "https://github.com/openpitkit/pit/archive/${SOURCE_REF}.tar.gz" \ + -o "${source_archive}" + source_sha512="$(sha512sum "${source_archive}" | awk '{print $1}')" + python3 scripts/materialize_vcpkg_port.py \ + --destination "${RENDERED_PORT}" \ + --package-version "${BASE_VERSION}" \ + --runtime-version "${VERSION}" \ + --source-ref "${SOURCE_REF}" \ + --source-sha512 "${source_sha512}" \ + --version "${VERSION}" + + if [[ "${RELEASE_MODE}" == "production" ]]; then + if [[ -z "${VCPKG_REGISTRY_PUSH_TOKEN}" ]]; then + echo "::error::VCPKG_REGISTRY_PUSH_TOKEN is required for production releases" + exit 1 + fi + git clone --depth 1 --branch main \ + "https://x-access-token:${VCPKG_REGISTRY_PUSH_TOKEN}@github.com/openpitkit/vcpkg-registry.git" \ + "${REGISTRY_DIR}" + else + mkdir -p "${REGISTRY_DIR}" + git -C "${REGISTRY_DIR}" init --initial-branch=main + fi + git -C "${REGISTRY_DIR}" config user.name "github-actions[bot]" + git -C "${REGISTRY_DIR}" config user.email "github-actions[bot]@users.noreply.github.com" + + mkdir -p "${REGISTRY_DIR}/ports" + if [[ -d "${REGISTRY_DIR}/ports/openpit" ]] \ + && cmp -s "${RENDERED_PORT}/portfile.cmake" "${REGISTRY_DIR}/ports/openpit/portfile.cmake" \ + && cmp -s "${RENDERED_PORT}/vcpkg.json" "${REGISTRY_DIR}/ports/openpit/vcpkg.json"; then + echo "OpenPit vcpkg port ${VERSION} is already materialized" + else + rm -rf "${REGISTRY_DIR}/ports/openpit" + cp -R "${RENDERED_PORT}" "${REGISTRY_DIR}/ports/openpit" + git -C "${REGISTRY_DIR}" add ports/openpit + git -C "${REGISTRY_DIR}" commit -m "Add OpenPit v${VERSION}" + "${VCPKG_ROOT}/vcpkg" x-add-version openpit \ + --x-builtin-ports-root="${REGISTRY_DIR}/ports" \ + --x-builtin-registry-versions-dir="${REGISTRY_DIR}/versions" + git -C "${REGISTRY_DIR}" add versions + git -C "${REGISTRY_DIR}" commit --amend --no-edit + fi + + registry_baseline="$(git -C "${REGISTRY_DIR}" rev-parse HEAD)" + vcpkg_baseline="$(git -C "${VCPKG_ROOT}" rev-parse HEAD)" + + mkdir -p "${VERIFY_ROOT}" + cp -R e2e/clients/cpp "${VERIFY_ROOT}/consumer" + cat > "${VERIFY_ROOT}/vcpkg.json" < "${VERIFY_ROOT}/vcpkg-configuration.json" < Installing OpenPit from the clean vcpkg registry" + ( + cd "${VERIFY_ROOT}" + OPENPIT_VCPKG_RUNTIME_LIBRARY="${RUNTIME_LIBRARY}" \ + "${VCPKG_ROOT}/vcpkg" install --triplet x64-linux + ) + cmake -S "${VERIFY_ROOT}/consumer" -B "${VERIFY_ROOT}/consumer-build" \ + -DCMAKE_TOOLCHAIN_FILE="${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" \ + -DVCPKG_MANIFEST_DIR="${VERIFY_ROOT}" \ + -DVCPKG_INSTALLED_DIR="${VERIFY_ROOT}/vcpkg_installed" \ + -DVCPKG_TARGET_TRIPLET=x64-linux \ + -DOPENPIT_RUNTIME_LIBRARY="${RUNTIME_LIBRARY}" + cmake --build "${VERIFY_ROOT}/consumer-build" --parallel + "${VERIFY_ROOT}/consumer-build/openpit_cpp_consumer" + + if [[ "${RELEASE_MODE}" == "production" ]]; then + git -C "${REGISTRY_DIR}" push origin HEAD:main + fi + echo "registry_baseline=${registry_baseline}" >> "$GITHUB_OUTPUT" + + if [[ "${RELEASE_MODE}" == "dry-run" ]]; then + STAGING_REGISTRY="$RUNNER_TEMP/openpit-vcpkg-dry-run-registry" + mkdir -p "${STAGING_REGISTRY}/ports" "${STAGING_REGISTRY}/versions/o-" + cp -R "${RENDERED_PORT}" "${STAGING_REGISTRY}/ports/openpit" + cat > "${STAGING_REGISTRY}/versions/baseline.json" < "${STAGING_REGISTRY}/versions/o-/openpit.json" < "${BODY_FILE}" + if [[ "${RELEASE_MODE}" == "dry-run" ]]; then + cat < "${BODY_FILE}" + Draft release used only to validate authentic asset downloads. + It must not be published or treated as a package release. + EOF + else + cat < "${BODY_FILE}" Install from package registries: - crates.io: https://crates.io/crates/openpit - - PyPI: https://pypi.org/project/openpit/${{ needs.verify-tag.outputs.version }}/ + - PyPI: https://pypi.org/project/openpit/${VERSION}/ Runtime artifacts for SDK delivery are attached to this release (\`.so\`, \`.dylib\`, \`.dll\`, Windows \`.dll.lib\`, and \`.sha256\` files per target). - The C++ distributable (\`openpit-cpp--${{ needs.verify-tag.outputs.version }}.tar.gz\`) + The C++ distributable (\`openpit-cpp--${VERSION}.tar.gz\`) contains the public headers and CMake config-file package. + + vcpkg users can consume OpenPit from + https://github.com/openpitkit/vcpkg-registry.git at baseline + \`${VCPKG_REGISTRY_BASELINE}\`. EOF + fi mapfile -t ASSETS < <(find release-assets -type f | sort) - GH_TOKEN="${{ github.token }}" gh release create "${{ github.ref_name }}" \ - --title "${{ github.ref_name }}" \ - --generate-notes \ - --notes-file "${BODY_FILE}" \ - --latest \ - "${ASSETS[@]}" + release_tag="v${VERSION}" + release_args=( + --title "${release_tag}" + --generate-notes + --notes-file "${BODY_FILE}" + ) + if [[ "${RELEASE_MODE}" == "dry-run" ]]; then + if GH_TOKEN="${{ github.token }}" \ + gh release view "${release_tag}" >/dev/null 2>&1; then + GH_TOKEN="${{ github.token }}" \ + gh release delete "${release_tag}" --yes --cleanup-tag + fi + release_args+=(--draft --target "${GITHUB_SHA}") + else + release_args+=(--latest) + fi + + GH_TOKEN="${{ github.token }}" gh release create "${release_tag}" \ + "${release_args[@]}" "${ASSETS[@]}" + + release-e2e: + name: Release e2e + needs: + - publish-github-release + - publish-vcpkg-registry + - verify-tag + if: ${{ needs.verify-tag.outputs.release_mode == 'dry-run' }} + runs-on: ubuntu-22.04 + permissions: + contents: write + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Download dry-run vcpkg registry + uses: actions/download-artifact@v4 + with: + name: openpit-vcpkg-dry-run-registry + path: ${{ runner.temp }}/openpit-vcpkg-dry-run-registry + + - name: Setup just + uses: extractions/setup-just@v3 + + - name: Setup QEMU + uses: docker/setup-qemu-action@v3 + + - name: Run release e2e against draft assets + shell: bash + env: + OPENPIT_RELEASE_DOWNLOAD_TOKEN: ${{ github.token }} + OPENPIT_RELEASE_E2E_TARGETS: cpp-amd64 cpp-vcpkg-amd64 + OPENPIT_VCPKG_REGISTRY_PATH: + ${{ runner.temp }}/openpit-vcpkg-dry-run-registry + run: just --justfile "$JUSTFILE" test-release-e2e "${{ needs.verify-tag.outputs.version }}" + + - name: Delete dry-run draft release + if: ${{ always() }} + shell: bash + env: + GH_TOKEN: ${{ github.token }} + VERSION: ${{ needs.verify-tag.outputs.version }} + run: gh release delete "v${VERSION}" --yes --cleanup-tag release-e2e-advisory: name: Release e2e advisory needs: - publish-github-release + - publish-vcpkg-registry - verify-tag - if: ${{ always() && needs.publish-github-release.result == 'success' }} + if: ${{ always() && needs.verify-tag.outputs.release_mode == 'production' && needs.publish-github-release.result == 'success' }} runs-on: ubuntu-22.04 permissions: contents: read @@ -1016,6 +1378,9 @@ jobs: - name: Run release e2e id: release-e2e shell: bash + env: + OPENPIT_VCPKG_REGISTRY_BASELINE: + ${{ needs.publish-vcpkg-registry.outputs.registry_baseline }} run: just --justfile "$JUSTFILE" test-release-e2e "${{ needs.verify-tag.outputs.version }}" - name: Summarize release e2e success diff --git a/bindings/cpp/CMakeLists.txt b/bindings/cpp/CMakeLists.txt index 28ad52b3..3bfa9099 100644 --- a/bindings/cpp/CMakeLists.txt +++ b/bindings/cpp/CMakeLists.txt @@ -21,11 +21,12 @@ if(POLICY CMP0091) cmake_policy(SET CMP0091 NEW) endif() -# Single-source the version from the workspace Cargo manifest unless the caller -# pins it through the OPENPIT_RUNTIME_VERSION cache variable. +# Single-source the package version from the workspace Cargo manifest unless the +# caller pins it explicitly. Runtime release tags may include a prerelease suffix +# that CMake's project(VERSION) grammar does not accept. set(OPENPIT_CARGO_MANIFEST "${CMAKE_CURRENT_SOURCE_DIR}/../../crates/openpit/Cargo.toml") -if(DEFINED OPENPIT_RUNTIME_VERSION AND NOT OPENPIT_RUNTIME_VERSION STREQUAL "") - set(OPENPIT_VERSION "${OPENPIT_RUNTIME_VERSION}") +if(DEFINED OPENPIT_PACKAGE_VERSION AND NOT OPENPIT_PACKAGE_VERSION STREQUAL "") + set(OPENPIT_VERSION "${OPENPIT_PACKAGE_VERSION}") elseif(EXISTS "${OPENPIT_CARGO_MANIFEST}") file(READ "${OPENPIT_CARGO_MANIFEST}" _openpit_cargo_toml) string(REGEX MATCH "(^|\n)version[ \t]*=[ \t]*\"([0-9][^\"]*)\"" @@ -35,7 +36,7 @@ elseif(EXISTS "${OPENPIT_CARGO_MANIFEST}") endif() if(NOT OPENPIT_VERSION) message(FATAL_ERROR - "OpenPit: could not determine version; set OPENPIT_RUNTIME_VERSION") + "OpenPit: could not determine version; set OPENPIT_PACKAGE_VERSION") endif() project(OpenPit @@ -48,9 +49,11 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") # GitHub repository hosting the prebuilt runtime release assets. set(OPENPIT_RUNTIME_REPO "openpitkit/pit" CACHE STRING "GitHub owner/repo hosting OpenPit runtime releases") -# Make the version visible to the runtime resolver and the installed config. -set(OPENPIT_RUNTIME_VERSION "${OPENPIT_VERSION}" - CACHE STRING "OpenPit prebuilt runtime version") +# Make the release tag visible to the runtime resolver and the installed config. +if(NOT DEFINED OPENPIT_RUNTIME_VERSION OR OPENPIT_RUNTIME_VERSION STREQUAL "") + set(OPENPIT_RUNTIME_VERSION "${OPENPIT_VERSION}" + CACHE STRING "OpenPit prebuilt runtime version") +endif() # Detect standalone vs add_subdirectory/FetchContent embedding. Both lead to the # same OpenPit::openpit alias. diff --git a/bindings/cpp/README.md b/bindings/cpp/README.md index 73bb3622..f0d419a0 100644 --- a/bindings/cpp/README.md +++ b/bindings/cpp/README.md @@ -31,9 +31,11 @@ phase. ## Getting Started -Use the package generated by `cmake --install` and consume it from another -CMake project: +### [CMake](https://cmake.org/) `find_package` +Use the package generated by `cmake --install` from another CMake project: + + ```cmake find_package(OpenPit CONFIG REQUIRED) target_link_libraries(your_target PRIVATE OpenPit::openpit) @@ -50,6 +52,52 @@ Include `` for the complete SDK surface, or include `` in precompiled headers when only forward declarations are needed. +### [vcpkg](https://vcpkg.io/) + +When the port version has merged into the public +[`microsoft/vcpkg`](https://github.com/microsoft/vcpkg) registry, add OpenPit +to the project manifest and pin the public registry baseline: + + +```json +{ + "name": "your-project", + "version-string": "0", + "builtin-baseline": "", + "dependencies": ["openpit"] +} +``` + +The managed +[`openpitkit/vcpkg-registry`](https://github.com/openpitkit/vcpkg-registry) +receives each OpenPit release first. Before the public port is merged, or when +pinning a specific OpenPit release, add `vcpkg-configuration.json` beside the +manifest. The manifest baseline pins the public vcpkg registry; the managed +registry baseline comes from the OpenPit release notes. + + +```json +{ + "registries": [ + { + "kind": "git", + "repository": "https://github.com/openpitkit/vcpkg-registry.git", + "baseline": "", + "packages": ["openpit"] + } + ] +} +``` + + +```cmake +find_package(OpenPit CONFIG REQUIRED) +target_link_libraries(your_target PRIVATE OpenPit::openpit) +``` + +Configure your project with the vcpkg toolchain file. The normal OpenPit runtime +resolver then downloads and verifies the matching released runtime asset. + ## Examples Runnable end-to-end examples live in [`examples/cpp/`](https://github.com/openpitkit/pit/tree/main/examples/cpp): diff --git a/bindings/cpp/cmake/OpenPitConfig.cmake.in b/bindings/cpp/cmake/OpenPitConfig.cmake.in index 155f9f01..2df171eb 100644 --- a/bindings/cpp/cmake/OpenPitConfig.cmake.in +++ b/bindings/cpp/cmake/OpenPitConfig.cmake.in @@ -23,7 +23,7 @@ include(CMakeFindDependencyMacro) -set(OPENPIT_RUNTIME_VERSION "@OPENPIT_VERSION@" +set(OPENPIT_RUNTIME_VERSION "@OPENPIT_RUNTIME_VERSION@" CACHE STRING "OpenPit prebuilt runtime version") set(OPENPIT_RUNTIME_REPO "@OPENPIT_RUNTIME_REPO@" CACHE STRING "GitHub owner/repo hosting OpenPit runtime releases") diff --git a/e2e/README.md b/e2e/README.md index 7397b542..b17264e2 100644 --- a/e2e/README.md +++ b/e2e/README.md @@ -26,7 +26,8 @@ just test-release-e2e 0.4.0 The suite builds and checks these scenarios, then prints a pass/fail summary: `rust-amd64`, `rust-arm64`, `python-wheel-amd64`, `python-wheel-arm64`, -`python-source-arm64`, `go-amd64`, `cpp-amd64`, `js-amd64`. +`python-source-arm64`, `go-amd64`, `cpp-amd64`, `cpp-vcpkg-amd64`, +`js-amd64`. ## How to run the tests diff --git a/e2e/clients/cpp/CMakeLists.txt b/e2e/clients/cpp/CMakeLists.txt index be4fa43f..79b7208e 100644 --- a/e2e/clients/cpp/CMakeLists.txt +++ b/e2e/clients/cpp/CMakeLists.txt @@ -25,6 +25,7 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) +# Source: bindings/cpp/README.md - Getting Started find_package(OpenPit CONFIG REQUIRED) add_executable(openpit_cpp_consumer main.cpp) diff --git a/e2e/env/docker/cpp-distributable/Dockerfile b/e2e/env/docker/cpp-distributable/Dockerfile index 7d43b151..36435208 100644 --- a/e2e/env/docker/cpp-distributable/Dockerfile +++ b/e2e/env/docker/cpp-distributable/Dockerfile @@ -25,6 +25,7 @@ RUN apt-get update \ g++ \ git \ make \ + python3 \ && rm -rf /var/lib/apt/lists/* WORKDIR /opt/e2e diff --git a/e2e/env/docker/cpp-vcpkg/Dockerfile b/e2e/env/docker/cpp-vcpkg/Dockerfile new file mode 100644 index 00000000..9e361088 --- /dev/null +++ b/e2e/env/docker/cpp-vcpkg/Dockerfile @@ -0,0 +1,43 @@ +# Copyright The Pit Project Owners. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Please see https://openpit.dev and the OWNERS file for details. + +FROM debian:bookworm + +RUN apt-get update \ + && apt-get install --yes --no-install-recommends \ + ca-certificates \ + cmake \ + curl \ + g++ \ + git \ + make \ + python3 \ + tar \ + unzip \ + zip \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /opt/e2e + +COPY e2e/scripts/cpp-vcpkg.sh /usr/local/bin/run-release-e2e +COPY e2e/clients/cpp /opt/e2e/cpp-consumer +COPY examples/cpp /opt/e2e/examples +COPY examples/tables /opt/e2e/tables + +RUN chmod +x /usr/local/bin/run-release-e2e + +ENTRYPOINT ["/usr/local/bin/run-release-e2e"] diff --git a/e2e/run.sh b/e2e/run.sh index 259fd4a5..4ee0853c 100755 --- a/e2e/run.sh +++ b/e2e/run.sh @@ -27,6 +27,40 @@ if [[ -z "${VERSION}" ]]; then exit 1 fi +known_targets=( + rust-amd64 + rust-arm64 + python-wheel-amd64 + python-wheel-arm64 + python-source-arm64 + go-amd64 + cpp-amd64 + cpp-vcpkg-amd64 + js-amd64 +) +requested_targets=() +if [[ -n "${OPENPIT_RELEASE_E2E_TARGETS:-}" ]]; then + read -r -a requested_targets <<< "${OPENPIT_RELEASE_E2E_TARGETS}" + if [[ ${#requested_targets[@]} -eq 0 ]]; then + echo "OPENPIT_RELEASE_E2E_TARGETS did not select any targets" >&2 + exit 1 + fi + for requested_target in "${requested_targets[@]}"; do + known=false + for target in "${known_targets[@]}"; do + if [[ "${requested_target}" == "${target}" ]]; then + known=true + break + fi + done + if [[ "${known}" != true ]]; then + echo "unknown release e2e target: ${requested_target}" >&2 + printf 'known targets: %s\n' "${known_targets[*]}" >&2 + exit 1 + fi + done +fi + run_case() { local name="$1" local dockerfile="$2" @@ -40,6 +74,24 @@ run_case() { run_args+=(--platform "${platform}") fi + for env_name in \ + OPENPIT_RELEASE_DOWNLOAD_TOKEN \ + OPENPIT_RELEASE_REPOSITORY \ + OPENPIT_VCPKG_REGISTRY_BASELINE \ + OPENPIT_VCPKG_REGISTRY_REPOSITORY; do + if [[ -n "${!env_name:-}" ]]; then + run_args+=(--env "${env_name}") + fi + done + + if [[ "${name}" == cpp-vcpkg-* \ + && -n "${OPENPIT_VCPKG_REGISTRY_PATH:-}" ]]; then + run_args+=( + --env OPENPIT_VCPKG_REGISTRY_PATH=/opt/e2e/vcpkg-registry + --volume "${OPENPIT_VCPKG_REGISTRY_PATH}:/opt/e2e/vcpkg-registry:ro" + ) + fi + echo echo "==> Building ${name} image" docker build --pull \ @@ -72,6 +124,21 @@ run_or_record() { local dockerfile="$2" local platform="${3:-}" + if [[ ${#requested_targets[@]} -ne 0 ]]; then + local selected=false + local target + for target in "${requested_targets[@]}"; do + if [[ "${target}" == "${name}" ]]; then + selected=true + break + fi + done + if [[ "${selected}" != true ]]; then + printf '==> %s checks skipped\n' "${name}" + return + fi + fi + if run_case "${name}" "${dockerfile}" "${platform}"; then passes=$((passes + 1)) passed_cases+=("${name}") @@ -92,6 +159,7 @@ run_or_record "python-wheel-arm64" "${ROOT_DIR}/e2e/env/docker/python-wheel/Dock run_or_record "python-source-arm64" "${ROOT_DIR}/e2e/env/docker/python-sdist/Dockerfile" "linux/arm64" run_or_record "go-amd64" "${ROOT_DIR}/e2e/env/docker/go-module/Dockerfile" "linux/amd64" run_or_record "cpp-amd64" "${ROOT_DIR}/e2e/env/docker/cpp-distributable/Dockerfile" "linux/amd64" +run_or_record "cpp-vcpkg-amd64" "${ROOT_DIR}/e2e/env/docker/cpp-vcpkg/Dockerfile" "linux/amd64" run_or_record "js-amd64" "${ROOT_DIR}/e2e/env/docker/js-package/Dockerfile" "linux/amd64" if [[ "${failures}" -ne 0 ]]; then diff --git a/e2e/scripts/cpp-distributable.sh b/e2e/scripts/cpp-distributable.sh index ea89dfc7..6b6ba3e0 100644 --- a/e2e/scripts/cpp-distributable.sh +++ b/e2e/scripts/cpp-distributable.sh @@ -22,6 +22,7 @@ set -euo pipefail asset="openpit-cpp--${OPENPIT_VERSION}.tar.gz" base_url="https://github.com/openpitkit/pit/releases/download/v${OPENPIT_VERSION}" +release_api="https://api.github.com/repos/${OPENPIT_RELEASE_REPOSITORY:-openpitkit/pit}" work_root="/tmp/openpit-cpp-release-e2e" install_dir="${work_root}/install" examples_root="/tmp/openpit-cpp-examples" @@ -29,28 +30,88 @@ examples_root="/tmp/openpit-cpp-examples" rm -rf "${work_root}" "${examples_root}" mkdir -p "${work_root}" "${install_dir}" +download_release_asset() { + local name="$1" + local destination="$2" + + if [[ -z "${OPENPIT_RELEASE_DOWNLOAD_TOKEN:-}" ]]; then + curl -fsSL "${base_url}/${name}" -o "${destination}" + return + fi + + local metadata="${work_root}/release.json" + curl -fsSL \ + --header "Authorization: Bearer ${OPENPIT_RELEASE_DOWNLOAD_TOKEN}" \ + --header "Accept: application/vnd.github+json" \ + "${release_api}/releases/tags/v${OPENPIT_VERSION}" \ + -o "${metadata}" + local asset_id + asset_id="$(python3 - "${metadata}" "${name}" <<'PY' +import json +import sys + +metadata_path, asset_name = sys.argv[1:] +with open(metadata_path, encoding="utf-8") as metadata_file: + release = json.load(metadata_file) +for release_asset in release["assets"]: + if release_asset["name"] == asset_name: + print(release_asset["id"]) + break +else: + raise SystemExit(f"release asset not found: {asset_name}") +PY +)" + curl -fsSL \ + --header "Authorization: Bearer ${OPENPIT_RELEASE_DOWNLOAD_TOKEN}" \ + --header "Accept: application/octet-stream" \ + "${release_api}/releases/assets/${asset_id}" \ + -o "${destination}" +} + +verify_sha256() { + local artifact="$1" + local sidecar="$2" + local expected_sha + local actual_sha + + expected_sha="$(tr -d '[:space:]' < "${sidecar}")" + if command -v sha256sum >/dev/null 2>&1; then + actual_sha="$(sha256sum "${artifact}" | awk '{print $1}')" + else + actual_sha="$(shasum -a 256 "${artifact}" | awk '{print $1}')" + fi + if [[ "${actual_sha}" != "${expected_sha}" ]]; then + echo "sha256 mismatch for ${artifact}" >&2 + echo "expected: ${expected_sha}" >&2 + echo "actual: ${actual_sha}" >&2 + exit 1 + fi +} + echo "==> Downloading ${asset}" -curl -fsSL "${base_url}/${asset}" -o "${work_root}/${asset}" -curl -fsSL "${base_url}/${asset}.sha256" -o "${work_root}/${asset}.sha256" - -expected_sha="$(tr -d '[:space:]' < "${work_root}/${asset}.sha256")" -if command -v sha256sum >/dev/null 2>&1; then - actual_sha="$(sha256sum "${work_root}/${asset}" | awk '{print $1}')" -else - actual_sha="$(shasum -a 256 "${work_root}/${asset}" | awk '{print $1}')" -fi -if [[ "${actual_sha}" != "${expected_sha}" ]]; then - echo "sha256 mismatch for ${asset}" >&2 - echo "expected: ${expected_sha}" >&2 - echo "actual: ${actual_sha}" >&2 - exit 1 -fi +download_release_asset "${asset}" "${work_root}/${asset}" +download_release_asset "${asset}.sha256" "${work_root}/${asset}.sha256" + +verify_sha256 "${work_root}/${asset}" "${work_root}/${asset}.sha256" tar -xzf "${work_root}/${asset}" -C "${install_dir}" +runtime_args=() +if [[ -n "${OPENPIT_RELEASE_DOWNLOAD_TOKEN:-}" ]]; then + runtime_asset="openpit-ffi--linux-amd64-libopenpit_ffi.so" + runtime_path="${work_root}/libopenpit_ffi.so" + echo "==> Downloading ${runtime_asset} for the draft-release resolver" + download_release_asset "${runtime_asset}" "${runtime_path}" + download_release_asset "${runtime_asset}.sha256" "${runtime_path}.sha256" + verify_sha256 "${runtime_path}" "${runtime_path}.sha256" + runtime_args+=("-DOPENPIT_RUNTIME_LIBRARY=${runtime_path}") +fi + +# Source: bindings/cpp/README.md - Getting Started / CMake find_package echo "==> Building minimal C++ consumer" cmake -S /opt/e2e/cpp-consumer -B "${work_root}/consumer-build" \ - -DCMAKE_PREFIX_PATH="${install_dir}" + -DCMAKE_PREFIX_PATH="${install_dir}" \ + "${runtime_args[@]}" cmake --build "${work_root}/consumer-build" --parallel "${work_root}/consumer-build/openpit_cpp_consumer" @@ -67,6 +128,7 @@ run_example() { echo "==> Building C++ example ${name}" cmake -S "${src}" -B "${build}" \ -DCMAKE_PREFIX_PATH="${install_dir}" \ + "${runtime_args[@]}" \ "$@" cmake --build "${build}" --parallel diff --git a/e2e/scripts/cpp-vcpkg.sh b/e2e/scripts/cpp-vcpkg.sh new file mode 100644 index 00000000..de48abd9 --- /dev/null +++ b/e2e/scripts/cpp-vcpkg.sh @@ -0,0 +1,229 @@ +#!/usr/bin/env bash +# Copyright The Pit Project Owners. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Please see https://openpit.dev and the OWNERS file for details. + +set -euo pipefail + +: "${OPENPIT_VERSION:?OPENPIT_VERSION is required}" + +work_root="/tmp/openpit-cpp-vcpkg-release-e2e" +examples_root="/tmp/openpit-cpp-vcpkg-examples" +vcpkg_root="${work_root}/vcpkg" +release_api="https://api.github.com/repos/${OPENPIT_RELEASE_REPOSITORY:-openpitkit/pit}" +release_metadata="${work_root}/release.json" + +rm -rf "${work_root}" "${examples_root}" +mkdir -p "${work_root}" + +download_release_metadata() { + local curl_args=(-fsSL) + if [[ -n "${OPENPIT_RELEASE_DOWNLOAD_TOKEN:-}" ]]; then + curl_args+=( + --header "Authorization: Bearer ${OPENPIT_RELEASE_DOWNLOAD_TOKEN}" + --header "Accept: application/vnd.github+json" + ) + fi + curl "${curl_args[@]}" \ + "${release_api}/releases/tags/v${OPENPIT_VERSION}" \ + -o "${release_metadata}" +} + +download_draft_runtime() { + if [[ -z "${OPENPIT_RELEASE_DOWNLOAD_TOKEN:-}" ]]; then + return + fi + + local asset="openpit-ffi--linux-amd64-libopenpit_ffi.so" + download_release_metadata + local asset_id + asset_id="$(python3 - "${release_metadata}" "${asset}" <<'PY' +import json +import sys + +metadata_path, asset_name = sys.argv[1:] +with open(metadata_path, encoding="utf-8") as metadata_file: + release = json.load(metadata_file) +for release_asset in release["assets"]: + if release_asset["name"] == asset_name: + print(release_asset["id"]) + break +else: + raise SystemExit(f"release asset not found: {asset_name}") +PY +)" + OPENPIT_VCPKG_RUNTIME_LIBRARY="${work_root}/libopenpit_ffi.so" + curl -fsSL \ + --header "Authorization: Bearer ${OPENPIT_RELEASE_DOWNLOAD_TOKEN}" \ + --header "Accept: application/octet-stream" \ + "${release_api}/releases/assets/${asset_id}" \ + -o "${OPENPIT_VCPKG_RUNTIME_LIBRARY}" + local sha_asset_id + sha_asset_id="$(python3 - "${release_metadata}" "${asset}.sha256" <<'PY' +import json +import sys + +metadata_path, asset_name = sys.argv[1:] +with open(metadata_path, encoding="utf-8") as metadata_file: + release = json.load(metadata_file) +for release_asset in release["assets"]: + if release_asset["name"] == asset_name: + print(release_asset["id"]) + break +else: + raise SystemExit(f"release asset not found: {asset_name}") +PY +)" + curl -fsSL \ + --header "Authorization: Bearer ${OPENPIT_RELEASE_DOWNLOAD_TOKEN}" \ + --header "Accept: application/octet-stream" \ + "${release_api}/releases/assets/${sha_asset_id}" \ + -o "${OPENPIT_VCPKG_RUNTIME_LIBRARY}.sha256" + expected_sha="$(tr -d '[:space:]' < "${OPENPIT_VCPKG_RUNTIME_LIBRARY}.sha256")" + actual_sha="$(sha256sum "${OPENPIT_VCPKG_RUNTIME_LIBRARY}" | awk '{print $1}')" + if [[ "${actual_sha}" != "${expected_sha}" ]]; then + echo "sha256 mismatch for ${asset}" >&2 + exit 1 + fi + export OPENPIT_VCPKG_RUNTIME_LIBRARY +} + +resolve_registry_baseline() { + if [[ -n "${OPENPIT_VCPKG_REGISTRY_PATH:-}" \ + || -n "${OPENPIT_VCPKG_REGISTRY_BASELINE:-}" ]]; then + return + fi + + if [[ ! -f "${release_metadata}" ]]; then + download_release_metadata + fi + OPENPIT_VCPKG_REGISTRY_BASELINE="$(python3 - "${release_metadata}" <<'PY' +import json +import re +import sys + +with open(sys.argv[1], encoding="utf-8") as metadata_file: + release = json.load(metadata_file) +match = re.search( + r"vcpkg-registry\.git at baseline\s+`([0-9a-f]{40})`", + release.get("body") or "", +) +if match is None: + raise SystemExit( + "could not resolve the OpenPit vcpkg registry baseline from release notes" + ) +print(match.group(1)) +PY +)" + export OPENPIT_VCPKG_REGISTRY_BASELINE +} + +write_vcpkg_configuration() { + if [[ -n "${OPENPIT_VCPKG_REGISTRY_PATH:-}" ]]; then + cat > "${work_root}/vcpkg-configuration.json" < "${work_root}/vcpkg-configuration.json" < Bootstrapping isolated vcpkg" +git clone --depth 1 https://github.com/microsoft/vcpkg.git "${vcpkg_root}" +"${vcpkg_root}/bootstrap-vcpkg.sh" -disableMetrics +vcpkg_baseline="$(git -C "${vcpkg_root}" rev-parse HEAD)" +# Source: bindings/cpp/README.md - Getting Started / vcpkg +cat > "${work_root}/vcpkg.json" < Installing OpenPit from vcpkg" +( + cd "${work_root}" + "${vcpkg_root}/vcpkg" install --triplet x64-linux +) + +cmake_args=( + "-DCMAKE_TOOLCHAIN_FILE=${vcpkg_root}/scripts/buildsystems/vcpkg.cmake" + "-DVCPKG_MANIFEST_DIR=${work_root}" + "-DVCPKG_INSTALLED_DIR=${work_root}/vcpkg_installed" + "-DVCPKG_TARGET_TRIPLET=x64-linux" +) +if [[ -n "${OPENPIT_VCPKG_RUNTIME_LIBRARY:-}" ]]; then + cmake_args+=("-DOPENPIT_RUNTIME_LIBRARY=${OPENPIT_VCPKG_RUNTIME_LIBRARY}") +fi + +echo "==> Building minimal C++ consumer through vcpkg" +cmake -S /opt/e2e/cpp-consumer -B "${work_root}/consumer-build" \ + "${cmake_args[@]}" +cmake --build "${work_root}/consumer-build" --parallel +"${work_root}/consumer-build/openpit_cpp_consumer" + +mkdir -p "${examples_root}/cpp" +cp -R /opt/e2e/examples/. "${examples_root}/cpp" +cp -R /opt/e2e/tables "${examples_root}/tables" + +run_example() { + local name="$1" + shift + local src="${examples_root}/cpp/${name}" + local build="${work_root}/examples/${name}" + + echo "==> Building C++ example ${name} through vcpkg" + cmake -S "${src}" -B "${build}" "${cmake_args[@]}" "$@" + cmake --build "${build}" --parallel + + echo "==> Testing C++ example ${name} through vcpkg" + ctest --test-dir "${build}" --output-on-failure +} + +run_example "rate_pnl_killswitch" \ + -DOPENPIT_EXAMPLE_USE_INSTALLED_PACKAGE=ON +run_example "spot_funds" +run_example "spot_table" \ + -DOPENPIT_USE_FIND_PACKAGE=ON +run_example "spot_loadtest" \ + -DOPENPIT_USE_FIND_PACKAGE=ON diff --git a/justfile b/justfile index 236292c0..8337d4f6 100644 --- a/justfile +++ b/justfile @@ -910,6 +910,12 @@ _build-cpp mode: *) echo "unsupported OS for pit-ffi runtime lookup" >&2; exit 1 ;; esac cmake_args=(-DOPENPIT_RUNTIME_LIBRARY="$lib" -DCMAKE_BUILD_TYPE="$config") + if [[ -n "${OPENPIT_PACKAGE_VERSION:-}" ]]; then + cmake_args+=(-DOPENPIT_PACKAGE_VERSION="$OPENPIT_PACKAGE_VERSION") + fi + if [[ -n "${OPENPIT_RUNTIME_VERSION:-}" ]]; then + cmake_args+=(-DOPENPIT_RUNTIME_VERSION="$OPENPIT_RUNTIME_VERSION") + fi if [[ -n "${implib:-}" ]]; then cmake_args+=(-DOPENPIT_RUNTIME_IMPORT_LIBRARY="$implib") fi diff --git a/packaging/vcpkg/openpit/portfile.cmake.in b/packaging/vcpkg/openpit/portfile.cmake.in new file mode 100644 index 00000000..8fb10f61 --- /dev/null +++ b/packaging/vcpkg/openpit/portfile.cmake.in @@ -0,0 +1,50 @@ +# Copyright The Pit Project Owners. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Please see https://openpit.dev and the OWNERS file for details. + +vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH + REPO openpitkit/pit + REF "@OPENPIT_SOURCE_REF@" + SHA512 @OPENPIT_SOURCE_SHA512@ + HEAD_REF main) + +set(openpit_cmake_options + "-DOPENPIT_CPP_BUILD_TESTS=OFF" + "-DOPENPIT_PACKAGE_VERSION=@OPENPIT_PACKAGE_VERSION@" + "-DOPENPIT_RUNTIME_VERSION=@OPENPIT_RUNTIME_VERSION@") + +# The release pipeline supplies a local runtime only while its GitHub release +# is not public yet. Normal registry consumers resolve the published runtime. +if(DEFINED ENV{OPENPIT_VCPKG_RUNTIME_LIBRARY} + AND NOT "$ENV{OPENPIT_VCPKG_RUNTIME_LIBRARY}" STREQUAL "") + list(APPEND openpit_cmake_options + "-DOPENPIT_RUNTIME_LIBRARY=$ENV{OPENPIT_VCPKG_RUNTIME_LIBRARY}") +endif() + +vcpkg_cmake_configure( + SOURCE_PATH "${SOURCE_PATH}/bindings/cpp" + OPTIONS ${openpit_cmake_options}) + +vcpkg_cmake_install() +vcpkg_cmake_config_fixup(CONFIG_PATH lib/cmake/OpenPit) + +file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug") +file(INSTALL "${SOURCE_PATH}/LICENSE" + DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}") +file(INSTALL "${SOURCE_PATH}/OWNERS" + DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}") +vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE") diff --git a/packaging/vcpkg/openpit/vcpkg.json.in b/packaging/vcpkg/openpit/vcpkg.json.in new file mode 100644 index 00000000..107b1dc2 --- /dev/null +++ b/packaging/vcpkg/openpit/vcpkg.json.in @@ -0,0 +1,18 @@ +{ + "name": "openpit", + "version-semver": "@OPENPIT_VERSION@", + "description": "C++17 binding for the OpenPit pre-trade risk SDK", + "homepage": "https://openpit.dev", + "license": "Apache-2.0", + "supports": "((linux | osx) & (x64 | arm64)) | (windows & x64 & !uwp & !mingw)", + "dependencies": [ + { + "name": "vcpkg-cmake", + "host": true + }, + { + "name": "vcpkg-cmake-config", + "host": true + } + ] +} diff --git a/pipeline.just b/pipeline.just index 8d0c818f..7ffa6be2 100644 --- a/pipeline.just +++ b/pipeline.just @@ -482,7 +482,10 @@ package-runtime target goos goarch lib_name: package-cpp cpp_install_dir: #!/usr/bin/env bash set -euo pipefail - VERSION="$(grep -m1 '^version[[:space:]]*=' crates/openpit/Cargo.toml | sed 's/^version[[:space:]]*=[[:space:]]*"\([^"]*\)".*/\1/')" + VERSION="${OPENPIT_RELEASE_VERSION:-}" + if [[ -z "${VERSION}" ]]; then + VERSION="$(grep -m1 '^version[[:space:]]*=' crates/openpit/Cargo.toml | sed 's/^version[[:space:]]*=[[:space:]]*"\([^"]*\)".*/\1/')" + fi : "${VERSION:?could not read version from crates/openpit/Cargo.toml}" INSTALL_DIR="{{ cpp_install_dir }}" diff --git a/scripts/just_helpers.py b/scripts/just_helpers.py index 56ec8667..530043b7 100644 --- a/scripts/just_helpers.py +++ b/scripts/just_helpers.py @@ -892,6 +892,10 @@ def command_build_cpp(args: argparse.Namespace) -> None: f"-DOPENPIT_RUNTIME_LIBRARY={lib}", f"-DCMAKE_BUILD_TYPE={cmake_build_type(mode)}", ] + if args.kind == "binding": + for variable in ("OPENPIT_PACKAGE_VERSION", "OPENPIT_RUNTIME_VERSION"): + if value := os.environ.get(variable): + cmake_args.append(f"-D{variable}={value}") if is_windows(): import_library = ensure_windows_runtime_import_library(lib) cmake_args.append(f"-DOPENPIT_RUNTIME_IMPORT_LIBRARY={import_library}") diff --git a/scripts/materialize_vcpkg_port.py b/scripts/materialize_vcpkg_port.py new file mode 100644 index 00000000..69d2a56b --- /dev/null +++ b/scripts/materialize_vcpkg_port.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 +# Copyright The Pit Project Owners. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Please see https://openpit.dev and the OWNERS file for details. + +"""Render a versioned OpenPit vcpkg port from the tracked registry template.""" + +from __future__ import annotations + +import argparse +from pathlib import Path + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--destination", type=Path, required=True) + parser.add_argument("--package-version", required=True) + parser.add_argument("--runtime-version", required=True) + parser.add_argument("--source-ref", required=True) + parser.add_argument("--source-sha512", required=True) + parser.add_argument("--version", required=True) + return parser.parse_args() + + +def render(template: Path, replacements: dict[str, str]) -> str: + contents = template.read_text(encoding="utf-8") + for placeholder, value in replacements.items(): + contents = contents.replace(placeholder, value) + if "@OPENPIT_" in contents: + raise ValueError(f"unresolved OpenPit template placeholder in {template}") + return contents + + +def main() -> None: + args = parse_args() + root = Path(__file__).resolve().parent.parent / "packaging" / "vcpkg" / "openpit" + replacements = { + "@OPENPIT_PACKAGE_VERSION@": args.package_version, + "@OPENPIT_RUNTIME_VERSION@": args.runtime_version, + "@OPENPIT_SOURCE_REF@": args.source_ref, + "@OPENPIT_SOURCE_SHA512@": args.source_sha512, + "@OPENPIT_VERSION@": args.version, + } + + args.destination.mkdir(parents=True, exist_ok=True) + (args.destination / "portfile.cmake").write_text( + render(root / "portfile.cmake.in", replacements), encoding="utf-8" + ) + (args.destination / "vcpkg.json").write_text( + render(root / "vcpkg.json.in", replacements), encoding="utf-8" + ) + + +if __name__ == "__main__": + main() From be9e50d370beff979bdb5937bc234a9dc7110323 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Jul 2026 20:10:29 +0000 Subject: [PATCH 2/2] Bump postcss from 8.5.15 to 8.5.23 in /bindings/js Bumps [postcss](https://github.com/postcss/postcss) from 8.5.15 to 8.5.23. - [Release notes](https://github.com/postcss/postcss/releases) - [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/postcss/postcss/compare/8.5.15...8.5.23) --- updated-dependencies: - dependency-name: postcss dependency-version: 8.5.23 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- bindings/js/package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/bindings/js/package-lock.json b/bindings/js/package-lock.json index 708c93b0..92dd34aa 100644 --- a/bindings/js/package-lock.json +++ b/bindings/js/package-lock.json @@ -2924,9 +2924,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.12", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", - "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", "dev": true, "funding": [ { @@ -3114,9 +3114,9 @@ } }, "node_modules/postcss": { - "version": "8.5.15", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", - "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "version": "8.5.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.23.tgz", + "integrity": "sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==", "dev": true, "funding": [ { @@ -3134,7 +3134,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.12", + "nanoid": "^3.3.16", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" },