From 1e241b0ac24b751d231e0837fc7e0b36fa1c9af4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garc=C3=ADa?= Date: Fri, 13 Nov 2026 18:48:46 +0100 Subject: [PATCH] Test the published SDK package by default in the SDK live tests --- .github/workflows/sdk-live-tests.yml | 109 ++++++++++++++++++++++++--- tools/sdk-live-tests/run.sh | 8 +- 2 files changed, 103 insertions(+), 14 deletions(-) diff --git a/.github/workflows/sdk-live-tests.yml b/.github/workflows/sdk-live-tests.yml index 94562a01..0ddabc31 100644 --- a/.github/workflows/sdk-live-tests.yml +++ b/.github/workflows/sdk-live-tests.yml @@ -2,18 +2,23 @@ name: SDK live tests permissions: {} # Runs the live-server end-to-end tests of bitwarden/sdk-internal against this branch, see tools/sdk-live-tests/run.sh. -# It builds the SDK too, so it runs daily against the SDK's main branch, by hand, and on changes to the test seeder or -# the runner. +# By default it tests the latest @bitwarden/sdk-internal on npm, which the SDK publishes for every commit to its main +# branch, with the e2e tests from that commit. A manual run can name an npm version instead, or a branch, tag or commit +# to build the SDK from. It runs daily, by hand, and on changes to the test seeder or the runner. on: schedule: # 04:15 UTC, off the top of the hour, when GitHub may delay or drop scheduled runs - cron: "15 4 * * *" workflow_dispatch: inputs: + sdk_npm_version: + description: "Version of @bitwarden/sdk-internal on npm to test (empty for the latest)" + required: false + default: "" sdk_ref: - description: "Branch, tag or commit of bitwarden/sdk-internal to test with" - required: true - default: "main" + description: "Or a branch, tag or commit of bitwarden/sdk-internal to build and test (slower)" + required: false + default: "" pull_request: paths: - ".github/workflows/sdk-live-tests.yml" @@ -29,6 +34,9 @@ jobs: name: SDK live tests runs-on: ubuntu-24.04 timeout-minutes: 90 + env: + # Less to compile and link, and a smaller cache. Panics still show file and line. + CARGO_PROFILE_DEV_DEBUG: "0" steps: - name: "Install dependencies Ubuntu" run: sudo apt-get update && sudo apt-get install -y --no-install-recommends build-essential libssl-dev pkg-config @@ -38,26 +46,80 @@ jobs: with: persist-credentials: false + # A published package (npm) or a build from a git ref (git), and the sdk-internal commit to check out + - name: "Pick the SDK" + id: sdk + env: + NPM_VERSION: ${{ inputs.sdk_npm_version }} + GIT_REF: ${{ inputs.sdk_ref }} + run: | + if [[ -n "${NPM_VERSION}" && -n "${GIT_REF}" ]]; then + echo "::error::Give an npm version or a git ref, not both" + exit 1 + fi + if [[ -n "${GIT_REF}" ]]; then + { + echo "source=git" + echo "ref=${GIT_REF}" + } >> "${GITHUB_OUTPUT}" + echo "SDK: bitwarden/sdk-internal \`${GIT_REF}\`, built from source" >> "${GITHUB_STEP_SUMMARY}" + exit 0 + fi + spec="${NPM_VERSION:-latest}" + if [[ ! "${spec}" =~ ^[0-9A-Za-z.+-]+$ ]]; then + echo "::error::That is not an npm version or tag" + exit 1 + fi + manifest="$(curl -fsS --retry 3 "https://registry.npmjs.org/@bitwarden%2Fsdk-internal/${spec}")" + version="$(jq -r .version <<< "${manifest}")" + commit="$(jq -r .gitHead <<< "${manifest}")" + if [[ ! "${commit}" =~ ^[0-9a-f]{40}$ ]]; then + echo "::error::@bitwarden/sdk-internal@${version} doesn't name the commit it was built from" + exit 1 + fi + { + echo "source=npm" + echo "version=${version}" + echo "ref=${commit}" + } >> "${GITHUB_OUTPUT}" + echo "SDK: @bitwarden/sdk-internal ${version} from npm, e2e tests at ${commit}" >> "${GITHUB_STEP_SUMMARY}" + - name: "Checkout sdk-internal" uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: repository: bitwarden/sdk-internal - ref: ${{ inputs.sdk_ref || 'main' }} + ref: ${{ steps.sdk.outputs.ref }} path: sdk-internal persist-credentials: false - # Each checkout pins its own toolchain in rust-toolchain.toml + # Each checkout pins its own toolchain in rust-toolchain.toml. The SDK's is only needed to build it. - name: "Install toolchains" + env: + SDK_SOURCE: ${{ steps.sdk.outputs.source }} run: | rustup toolchain install - cd sdk-internal - rustup toolchain install - rustup target add wasm32-unknown-unknown - rustup component add rust-src + if [[ "${SDK_SOURCE}" == git ]]; then + cd sdk-internal + rustup toolchain install + rustup target add wasm32-unknown-unknown + rustup component add rust-src + fi + # One cache per SDK source, so that neither restores the other's - name: "Cache Rust builds" + if: ${{ steps.sdk.outputs.source == 'npm' }} uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3 with: + key: sdk-live-tests-npm + add-job-id-key: false + workspaces: ". -> target" + + - name: "Cache Rust builds (with the SDK)" + if: ${{ steps.sdk.outputs.source == 'git' }} + uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3 + with: + key: sdk-live-tests-sdk-build + add-job-id-key: false workspaces: | . -> target sdk-internal -> target @@ -67,8 +129,31 @@ jobs: with: node-version-file: sdk-internal/.nvmrc + # Where the SDK's build would put it + - name: "Download the SDK package" + if: ${{ steps.sdk.outputs.source == 'npm' }} + env: + SDK_VERSION: ${{ steps.sdk.outputs.version }} + SDK_COMMIT: ${{ steps.sdk.outputs.ref }} + run: | + # npm checks the tarball against the registry's checksum + tarball="$(npm pack "@bitwarden/sdk-internal@${SDK_VERSION}" --pack-destination "${RUNNER_TEMP}" --json | jq -r '.[0].filename')" + package_dir=sdk-internal/crates/bitwarden-wasm-internal/npm + tar -xzf "${RUNNER_TEMP}/${tarball}" --strip-components=1 -C "${package_dir}" + if [[ "$(cat "${package_dir}/VERSION")" != "${SDK_COMMIT}" ]]; then + echo "::error::The package's VERSION doesn't match its commit ${SDK_COMMIT}" + exit 1 + fi + - name: "Run the SDK live tests" - run: tools/sdk-live-tests/run.sh --sdk-dir sdk-internal + env: + SDK_SOURCE: ${{ steps.sdk.outputs.source }} + run: | + args=(--sdk-dir sdk-internal) + if [[ "${SDK_SOURCE}" == npm ]]; then + args+=(--skip-sdk-build) + fi + tools/sdk-live-tests/run.sh "${args[@]}" - name: "Upload logs" if: ${{ !cancelled() }} diff --git a/tools/sdk-live-tests/run.sh b/tools/sdk-live-tests/run.sh index d5d9456f..d57183e0 100755 --- a/tools/sdk-live-tests/run.sh +++ b/tools/sdk-live-tests/run.sh @@ -3,6 +3,9 @@ # # Usage: tools/sdk-live-tests/run.sh --sdk-dir [--skip-sdk-build] [--mode vectors|seeder] [-- ] # +# --skip-sdk-build uses the package already in the SDK's crates/bitwarden-wasm-internal/npm: an earlier build, or a +# published @bitwarden/sdk-internal unpacked there. +# # The server is built with `unsafe_test_mode`, whose test seeder (src/api/test_seeder.rs) creates the test accounts. # - vectors: for SDK versions whose live tests log in to one given account. Every user test vector with a master # password gets a fresh server, is seeded there with its vault, and the tests run on it (they rotate its keys). @@ -13,7 +16,8 @@ # Every vector runs even after a failure; a summary follows, and the exit code is 1 if any failed. The server logs are # in /sdk-live-tests/. BW_LIVE_CLIENT_VERSION defaults to 2026.10.1, the minimum for V2 accounts. # -# Needs: the SDK's Rust toolchain with the wasm32-unknown-unknown target and rust-src, Node.js >= 22.12, curl, python3. +# Needs: Node.js >= 22.12, curl, python3, and to build the SDK its Rust toolchain with the wasm32-unknown-unknown target +# and rust-src. set -euo pipefail VW_DIR="$(cd "$(dirname "$0")/../.." && pwd)" @@ -52,8 +56,8 @@ echo "Mode: ${MODE}, client version ${BW_LIVE_CLIENT_VERSION}" (cd "${VW_DIR}" && cargo build --features sqlite,unsafe_test_mode) if [[ ${BUILD_SDK} -eq 1 ]]; then bash "${SDK_DIR}/crates/bitwarden-wasm-internal/build.sh" - (cd "${TESTS_DIR}" && npm ci) fi +(cd "${TESTS_DIR}" && npm ci) server="" trap 'if [[ -n "${server}" ]]; then kill "${server}" 2>/dev/null || true; fi' EXIT