Repository navigation
chore: start 0.83.1 development #1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| types: [opened, synchronize, reopened, ready_for_review, converted_to_draft] | |
| concurrency: | |
| group: ci-${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| SWIFT_VERSION: 6.3.3 | |
| SWIFTLY_VERSION: 1.1.3 | |
| SWIFTLY_SIGNING_FINGERPRINT: E813C892820A6FA13755B268F167DF1ACF9CE069 | |
| jobs: | |
| changes: | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 5 | |
| outputs: | |
| macos-tests: ${{ steps.macos-tests.outputs.macos-tests }} | |
| macos-tests-deferred: ${{ steps.macos-tests.outputs.macos-tests-deferred }} | |
| macos-tests-reason: ${{ steps.macos-tests.outputs.macos-tests-reason }} | |
| linux-cli-build: ${{ steps.macos-tests.outputs.linux-cli-build }} | |
| linux-cli-build-reason: ${{ steps.macos-tests.outputs.linux-cli-build-reason }} | |
| changed-path-count: ${{ steps.macos-tests.outputs.changed-path-count }} | |
| linux-musl-build: ${{ steps.linux-musl-build.outputs.linux-musl-build }} | |
| linux-musl-build-reason: ${{ steps.linux-musl-build.outputs.linux-musl-build-reason }} | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| fetch-depth: 0 | |
| - name: Detect Swift build and test impact | |
| id: macos-tests | |
| shell: bash | |
| env: | |
| CI_PULL_REQUEST_DRAFT: ${{ github.event.pull_request.draft || false }} | |
| run: | | |
| set -euo pipefail | |
| if [[ "${{ github.event_name }}" == "pull_request" ]]; then | |
| base_sha="${{ github.event.pull_request.base.sha }}" | |
| else | |
| base_sha="${{ github.event.before }}" | |
| fi | |
| changed_paths="${RUNNER_TEMP}/changed-paths.txt" | |
| if [[ -z "$base_sha" || "$base_sha" =~ ^0+$ ]]; then | |
| git ls-files | awk '{ print "A\t" $0 }' > "$changed_paths" | |
| elif ! git cat-file -e "${base_sha}^{commit}" 2>/dev/null; then | |
| echo "Base commit ${base_sha} is unavailable; running Swift builds and tests conservatively." | |
| git ls-files | awk '{ print "A\t" $0 }' > "$changed_paths" | |
| else | |
| git diff --name-status "$base_sha" "$GITHUB_SHA" > "$changed_paths" | |
| fi | |
| printf 'Changed paths:\n' | |
| sed 's/^/- /' "$changed_paths" | |
| ./Scripts/ci_macos_test_gate.sh "$changed_paths" | |
| - name: Detect Linux musl build impact | |
| id: linux-musl-build | |
| shell: bash | |
| run: ./Scripts/ci_linux_musl_build_gate.sh "$RUNNER_TEMP/changed-paths.txt" | |
| - name: Summarize CI path gates | |
| if: ${{ always() }} | |
| shell: bash | |
| env: | |
| MACOS_TESTS: ${{ steps.macos-tests.outputs.macos-tests }} | |
| MACOS_TESTS_REASON: ${{ steps.macos-tests.outputs.macos-tests-reason }} | |
| LINUX_CLI_BUILD: ${{ steps.macos-tests.outputs.linux-cli-build }} | |
| LINUX_CLI_BUILD_REASON: ${{ steps.macos-tests.outputs.linux-cli-build-reason }} | |
| CHANGED_PATH_COUNT: ${{ steps.macos-tests.outputs.changed-path-count }} | |
| LINUX_MUSL_BUILD: ${{ steps.linux-musl-build.outputs.linux-musl-build }} | |
| LINUX_MUSL_BUILD_REASON: ${{ steps.linux-musl-build.outputs.linux-musl-build-reason }} | |
| run: | | |
| set -euo pipefail | |
| reason="${MACOS_TESTS_REASON:-<unset>}" | |
| reason="${reason//|/\\|}" | |
| linux_reason="${LINUX_CLI_BUILD_REASON:-<unset>}" | |
| linux_reason="${linux_reason//|/\\|}" | |
| musl_reason="${LINUX_MUSL_BUILD_REASON:-<unset>}" | |
| musl_reason="${musl_reason//|/\\|}" | |
| { | |
| printf '### CI path gates\n\n' | |
| printf '| Field | Value |\n' | |
| printf '| --- | --- |\n' | |
| printf '| macOS Swift tests required | `%s` |\n' "${MACOS_TESTS:-<unset>}" | |
| printf '| macOS reason | %s |\n' "$reason" | |
| printf '| Linux glibc CLI matrix required | `%s` |\n' "${LINUX_CLI_BUILD:-<unset>}" | |
| printf '| Linux glibc reason | %s |\n' "$linux_reason" | |
| printf '| Linux musl build required | `%s` |\n' "${LINUX_MUSL_BUILD:-<unset>}" | |
| printf '| Linux musl reason | %s |\n' "$musl_reason" | |
| printf '| Changed path entries | `%s` |\n' "${CHANGED_PATH_COUNT:-<unset>}" | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| lint: | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Install lint tools | |
| run: ./Scripts/install_lint_tools.sh swiftlint oxlint oxfmt typescript | |
| - name: Lint | |
| run: ./Scripts/lint.sh lint-linux | |
| swift-test-macos: | |
| needs: changes | |
| if: ${{ needs.changes.outputs.macos-tests == 'true' && needs.changes.outputs.macos-tests-deferred != 'true' }} | |
| # Apple-Silicon runners: ~2-4x faster Swift builds than the retired-path | |
| # Intel pool and much shorter queues (see #2585 for the measurements). | |
| # GitHub's Xcode 27 image (macOS 27 base); CI builds and tests with Xcode 27 only. | |
| runs-on: xcode-27 | |
| timeout-minutes: 90 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Select Xcode 27 | |
| run: | | |
| set -euo pipefail | |
| sudo xcode-select -s /Applications/Xcode_27.0.app/Contents/Developer | |
| echo "DEVELOPER_DIR=/Applications/Xcode_27.0.app/Contents/Developer" >> "$GITHUB_ENV" | |
| [[ "$(/usr/bin/xcodebuild -version)" == Xcode\ 27* ]] | |
| /usr/bin/xcodebuild -version | |
| - name: Identify SwiftPM build context | |
| id: build-context | |
| run: python3 Scripts/ci_swiftpm_cache.py context --lane xcode27-arm64 | |
| - name: Restore compiled SwiftPM cache | |
| id: compiled-cache | |
| uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| path: .build | |
| key: ${{ steps.build-context.outputs.prefix }}${{ github.sha }} | |
| restore-keys: ${{ steps.build-context.outputs.prefix }} | |
| - name: Restore legacy dependency cache on a compiled-cache miss | |
| if: ${{ !steps.compiled-cache.outputs.cache-matched-key }} | |
| uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| path: | | |
| .build | |
| ~/Library/Caches/org.swift.swiftpm | |
| key: swiftpm-xcode27-arm64-${{ hashFiles('Package.resolved', 'Package.swift') }} | |
| restore-keys: | | |
| swiftpm-xcode27-arm64- | |
| - name: Swift toolchain version | |
| run: | | |
| set -euo pipefail | |
| swift --version | |
| swift package --version | |
| - name: Check app locales and Swift formatting | |
| run: ./Scripts/lint.sh lint-macos | |
| - name: Verify cached inputs and record current checkout | |
| env: | |
| BUILD_CONTEXT: ${{ steps.build-context.outputs.context }} | |
| COMPILED_CACHE_KEY: ${{ steps.compiled-cache.outputs.cache-matched-key }} | |
| run: | | |
| set -euo pipefail | |
| if [[ -z "$COMPILED_CACHE_KEY" ]]; then | |
| rm -f .build/ci-inputs.json | |
| fi | |
| python3 Scripts/ci_swiftpm_cache.py restore --context "$BUILD_CONTEXT" --clean-fallback | |
| # Record inputs before compiling; cache publication also requires a clean tree. | |
| python3 Scripts/ci_swiftpm_cache.py snapshot --context "$BUILD_CONTEXT" | |
| - name: Swift Test | |
| # Batch short suites; the runner isolates expensive suites without changing their deadlines. | |
| timeout-minutes: 75 | |
| run: | | |
| touch "$RUNNER_TEMP/codexbar-tests-started" | |
| echo "Hosted tests run the complete inventory with two verified direct workers." | |
| CODEXBAR_TEST_GROUP_SIZE=8 \ | |
| CODEXBAR_TEST_SUITE_TIMEOUT=120 \ | |
| CODEXBAR_TEST_RETRY_NON_TIMEOUT_FAILURES=0 \ | |
| ./Scripts/test.sh --direct-workers 2 | |
| - name: Provider plugin engine A/B goldens | |
| run: ./Scripts/test-plugin-engines.sh | |
| - name: Verify checkout before publishing compiled cache | |
| if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} | |
| run: git diff --exit-code HEAD -- | |
| - name: Save successful main build for subsequent checkouts | |
| if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' && steps.compiled-cache.outputs.cache-hit != 'true' }} | |
| uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| path: .build | |
| key: ${{ steps.build-context.outputs.prefix }}${{ github.sha }} | |
| - name: Collect crash reports on failure | |
| if: ${{ failure() }} | |
| shell: bash | |
| run: | | |
| if [[ -f "$RUNNER_TEMP/codexbar-tests-started" ]]; then | |
| python3 Scripts/swift_test_diagnostics.py --since "$RUNNER_TEMP/codexbar-tests-started" | |
| fi | |
| - name: Summarize macOS tests | |
| if: ${{ always() }} | |
| shell: bash | |
| env: | |
| COMPILED_CACHE_KEY: ${{ steps.compiled-cache.outputs.cache-matched-key }} | |
| run: | | |
| set -euo pipefail | |
| xcode_version="$(/usr/bin/xcodebuild -version 2>/dev/null | tr '\n' ' ' || true)" | |
| { | |
| printf '### macOS Swift tests\n\n' | |
| printf '| Field | Value |\n' | |
| printf '| --- | --- |\n' | |
| printf '| Coverage | Full discovered inventory |\n' | |
| printf '| Workers | `2` direct workers on one runner |\n' | |
| printf '| Runner | `%s` |\n' "${RUNNER_NAME:-unknown}" | |
| printf '| Xcode | `%s` |\n' "${xcode_version:-unknown}" | |
| printf '| Compiled cache | `%s` |\n' "${COMPILED_CACHE_KEY:-miss}" | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| prune-swiftpm-caches: | |
| needs: [swift-test-macos] | |
| if: ${{ always() && github.event_name == 'push' && github.ref == 'refs/heads/main' }} | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 5 | |
| permissions: | |
| contents: read | |
| actions: write | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Keep one main compiled snapshot per macOS lane | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: python3 Scripts/ci_prune_swiftpm_cache.py --repository "$GITHUB_REPOSITORY" | |
| lint-build-test: | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 5 | |
| needs: | |
| - changes | |
| - lint | |
| - swift-test-macos | |
| - build-linux-musl-cli | |
| - build-linux-cli | |
| if: ${{ always() && !cancelled() }} | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Verify required CI jobs | |
| run: | | |
| ./Scripts/ci_verify_test_jobs.sh \ | |
| "${{ needs.lint.result }}" \ | |
| "${{ needs.changes.result }}" \ | |
| "${{ needs.changes.outputs.macos-tests }}" \ | |
| "${{ needs.swift-test-macos.result }}" \ | |
| "${{ needs.changes.outputs.macos-tests-deferred }}" \ | |
| "${{ needs.changes.outputs.linux-musl-build }}" \ | |
| "${{ needs.build-linux-musl-cli.result }}" \ | |
| "${{ needs.build-linux-cli.result }}" \ | |
| "${{ needs.changes.outputs.linux-cli-build }}" | |
| - name: Summarize aggregate CI gate | |
| if: ${{ always() }} | |
| shell: bash | |
| env: | |
| LINT_RESULT: ${{ needs.lint.result }} | |
| CHANGES_RESULT: ${{ needs.changes.result }} | |
| MACOS_TESTS: ${{ needs.changes.outputs.macos-tests }} | |
| MACOS_TESTS_DEFERRED: ${{ needs.changes.outputs.macos-tests-deferred }} | |
| MACOS_TESTS_REASON: ${{ needs.changes.outputs.macos-tests-reason }} | |
| MACOS_RESULT: ${{ needs.swift-test-macos.result }} | |
| LINUX_MUSL_BUILD: ${{ needs.changes.outputs.linux-musl-build }} | |
| LINUX_MUSL_BUILD_REASON: ${{ needs.changes.outputs.linux-musl-build-reason }} | |
| LINUX_MUSL_RESULT: ${{ needs.build-linux-musl-cli.result }} | |
| LINUX_RESULT: ${{ needs.build-linux-cli.result }} | |
| LINUX_CLI_BUILD: ${{ needs.changes.outputs.linux-cli-build }} | |
| LINUX_CLI_BUILD_REASON: ${{ needs.changes.outputs.linux-cli-build-reason }} | |
| run: | | |
| set -euo pipefail | |
| reason="${MACOS_TESTS_REASON:-<unset>}" | |
| reason="${reason//|/\\|}" | |
| linux_reason="${LINUX_CLI_BUILD_REASON:-<unset>}" | |
| linux_reason="${linux_reason//|/\\|}" | |
| musl_reason="${LINUX_MUSL_BUILD_REASON:-<unset>}" | |
| musl_reason="${musl_reason//|/\\|}" | |
| { | |
| printf '### Aggregate CI gate\n\n' | |
| printf '| Field | Value |\n' | |
| printf '| --- | --- |\n' | |
| printf '| lint result | `%s` |\n' "$LINT_RESULT" | |
| printf '| changes result | `%s` |\n' "$CHANGES_RESULT" | |
| printf '| macOS Swift tests required | `%s` |\n' "${MACOS_TESTS:-<unset>}" | |
| printf '| macOS Swift tests deferred | `%s` |\n' "${MACOS_TESTS_DEFERRED:-<unset>}" | |
| printf '| macOS gate reason | %s |\n' "$reason" | |
| printf '| swift-test-macos result | `%s` |\n' "$MACOS_RESULT" | |
| printf '| Linux musl build required | `%s` |\n' "${LINUX_MUSL_BUILD:-<unset>}" | |
| printf '| Linux musl gate reason | %s |\n' "$musl_reason" | |
| printf '| build-linux-musl-cli result | `%s` |\n' "$LINUX_MUSL_RESULT" | |
| printf '| Linux glibc CLI matrix required | `%s` |\n' "${LINUX_CLI_BUILD:-<unset>}" | |
| printf '| Linux glibc gate reason | %s |\n' "$linux_reason" | |
| printf '| build-linux-cli matrix result | `%s` |\n' "$LINUX_RESULT" | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| build-linux-musl-cli: | |
| needs: changes | |
| if: ${{ needs.changes.outputs.linux-musl-build == 'true' }} | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 20 | |
| env: | |
| SWIFT_VERSION: 6.3.3 | |
| SWIFT_STATIC_LINUX_SDK: swift-6.3.3-RELEASE_static-linux-0.1.0 | |
| SWIFT_STATIC_LINUX_SDK_TRIPLE: x86_64-swift-linux-musl | |
| SWIFT_STATIC_LINUX_SDK_ARCH: x86_64 | |
| SWIFT_STATIC_LINUX_SDK_URL: https://download.swift.org/swift-6.3.3-release/static-sdk/swift-6.3.3-RELEASE/swift-6.3.3-RELEASE_static-linux-0.1.0.artifactbundle.tar.gz | |
| SWIFT_STATIC_LINUX_SDK_CHECKSUM: 87c3eaf908e67c0e13a84367119e12273cec1d2cd3d81f7d74bb36722d6b607b | |
| SQLITE_AMALGAMATION_VERSION: "3530400" | |
| SQLITE_AMALGAMATION_SHA3_256: 628a44cfe82c66aed1ccbbe85a562d2e33ebe64b3288981ed76285612227934e | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Runner info | |
| run: | | |
| set -euo pipefail | |
| uname -a | |
| uname -m | |
| swift --version | |
| - name: Install Swift ${{ env.SWIFT_VERSION }} via swiftly | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| if ! command -v gpg >/dev/null 2>&1; then | |
| sudo apt-get update | |
| sudo apt-get install -y ca-certificates gpg | |
| fi | |
| SWIFTLY_ARCH="$(uname -m)" | |
| SWIFTLY_ARCHIVE="$RUNNER_TEMP/swiftly-${SWIFTLY_VERSION}-${SWIFTLY_ARCH}.tar.gz" | |
| SWIFTLY_SIGNATURE="${SWIFTLY_ARCHIVE}.sig" | |
| SWIFTLY_HOME_DIR="$HOME/.local/share/swiftly" | |
| SWIFTLY_BIN_DIR="$HOME/.local/bin" | |
| SWIFT_GNUPGHOME="$(mktemp -d)" | |
| SWIFT_KEYS="$RUNNER_TEMP/swift-signing-keys.asc" | |
| POST_INSTALL_SCRIPT="$(mktemp)" | |
| mkdir -p "$SWIFTLY_BIN_DIR" | |
| chmod 700 "$SWIFT_GNUPGHOME" | |
| curl -fsSL "https://download.swift.org/swiftly/linux/swiftly-${SWIFTLY_VERSION}-${SWIFTLY_ARCH}.tar.gz" -o "$SWIFTLY_ARCHIVE" | |
| curl -fsSL "https://download.swift.org/swiftly/linux/swiftly-${SWIFTLY_VERSION}-${SWIFTLY_ARCH}.tar.gz.sig" -o "$SWIFTLY_SIGNATURE" | |
| curl -fsSL --compressed "https://www.swift.org/keys/all-keys.asc" -o "$SWIFT_KEYS" | |
| GNUPGHOME="$SWIFT_GNUPGHOME" gpg --batch --import "$SWIFT_KEYS" | |
| SIGNATURE_STATUS="$(GNUPGHOME="$SWIFT_GNUPGHOME" gpg --batch --status-fd=1 \ | |
| --verify "$SWIFTLY_SIGNATURE" "$SWIFTLY_ARCHIVE" 2>&1)" | |
| printf '%s\n' "$SIGNATURE_STATUS" | |
| grep -Fq "[GNUPG:] VALIDSIG ${SWIFTLY_SIGNING_FINGERPRINT} " <<< "$SIGNATURE_STATUS" | |
| tar -xzf "$SWIFTLY_ARCHIVE" -C /tmp | |
| /tmp/swiftly init --assume-yes --skip-install | |
| . "$SWIFTLY_HOME_DIR/env.sh" | |
| echo "$SWIFTLY_BIN_DIR" >> "$GITHUB_PATH" | |
| echo "SWIFTLY_HOME_DIR=$SWIFTLY_HOME_DIR" >> "$GITHUB_ENV" | |
| echo "SWIFTLY_BIN_DIR=$SWIFTLY_BIN_DIR" >> "$GITHUB_ENV" | |
| swiftly install "$SWIFT_VERSION" --use --assume-yes --verify --post-install-file "$POST_INSTALL_SCRIPT" | |
| if [[ -s "$POST_INSTALL_SCRIPT" ]]; then | |
| sudo apt-get update | |
| sudo bash "$POST_INSTALL_SCRIPT" | |
| fi | |
| hash -r | |
| swift --version | |
| - name: Install Swift Static Linux SDK | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| ./Scripts/install_swift_static_sdk.sh | |
| swift sdk list | grep -Fx "$SWIFT_STATIC_LINUX_SDK" | |
| sdk_root="$( | |
| find "$HOME" -type d -path "*/${SWIFT_STATIC_LINUX_SDK}.artifactbundle/${SWIFT_STATIC_LINUX_SDK}/swift-linux-musl" | head -n1 | |
| )" | |
| if [[ -z "$sdk_root" ]]; then | |
| echo "Swift SDK root not found." >&2 | |
| exit 1 | |
| fi | |
| python3 - "$sdk_root/swift-sdk.json" "$SWIFT_STATIC_LINUX_SDK_TRIPLE" <<'PY' | |
| import json | |
| import sys | |
| sdk_json_path, target_triple = sys.argv[1], sys.argv[2] | |
| with open(sdk_json_path, encoding="utf-8") as handle: | |
| sdk_json = json.load(handle) | |
| target_triples = sdk_json.get("targetTriples", {}) | |
| if target_triple not in target_triples: | |
| raise SystemExit(f"Swift SDK target triple not found: {target_triple}") | |
| sdk_json["targetTriples"] = {target_triple: target_triples[target_triple]} | |
| with open(sdk_json_path, "w", encoding="utf-8") as handle: | |
| json.dump(sdk_json, handle, indent=2) | |
| handle.write("\n") | |
| PY | |
| for sdk_arch in "$sdk_root"/musl-1.2.5.sdk/*; do | |
| if [[ "$(basename "$sdk_arch")" != "$SWIFT_STATIC_LINUX_SDK_ARCH" ]]; then | |
| rm -rf "$sdk_arch" | |
| fi | |
| done | |
| - name: Build static SQLite for musl SDK | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| missing_packages=() | |
| for tool in clang openssl unzip; do | |
| if ! command -v "$tool" >/dev/null 2>&1; then | |
| missing_packages+=("$tool") | |
| fi | |
| done | |
| if [[ "${#missing_packages[@]}" -gt 0 ]]; then | |
| sudo apt-get update | |
| sudo apt-get install -y "${missing_packages[@]}" | |
| fi | |
| sqlite_zip="$RUNNER_TEMP/sqlite-amalgamation-${SQLITE_AMALGAMATION_VERSION}.zip" | |
| sqlite_src="$RUNNER_TEMP/sqlite-src" | |
| sqlite_out="$RUNNER_TEMP/sqlite-${SWIFT_STATIC_LINUX_SDK_TRIPLE}" | |
| curl -fsSL "https://www.sqlite.org/2026/sqlite-amalgamation-${SQLITE_AMALGAMATION_VERSION}.zip" -o "$sqlite_zip" | |
| actual_sha3="$(openssl dgst -sha3-256 "$sqlite_zip" | awk '{print $NF}')" | |
| if [[ "$actual_sha3" != "$SQLITE_AMALGAMATION_SHA3_256" ]]; then | |
| echo "SQLite amalgamation checksum mismatch: $actual_sha3" >&2 | |
| exit 1 | |
| fi | |
| rm -rf "$sqlite_src" "$sqlite_out" | |
| mkdir -p "$sqlite_src" "$sqlite_out/build" "$sqlite_out/lib" | |
| unzip -q "$sqlite_zip" -d "$sqlite_src" | |
| sdk_bundle="$( | |
| find "$HOME" -type d -name "${SWIFT_STATIC_LINUX_SDK}.artifactbundle" | head -n1 | |
| )" | |
| if [[ -z "$sdk_bundle" ]]; then | |
| echo "Swift SDK artifact bundle not found." >&2 | |
| exit 1 | |
| fi | |
| sysroot="$sdk_bundle/$SWIFT_STATIC_LINUX_SDK/swift-linux-musl/musl-1.2.5.sdk/$SWIFT_STATIC_LINUX_SDK_ARCH" | |
| if [[ ! -d "$sysroot" ]]; then | |
| echo "Swift SDK sysroot not found: $sysroot" >&2 | |
| exit 1 | |
| fi | |
| sqlite_amalgamation="$sqlite_src/sqlite-amalgamation-${SQLITE_AMALGAMATION_VERSION}" | |
| mkdir -p "$sysroot/usr/include" | |
| install -m 0644 "$sqlite_amalgamation/sqlite3.h" "$sysroot/usr/include/sqlite3.h" | |
| clang \ | |
| -target "$SWIFT_STATIC_LINUX_SDK_TRIPLE" \ | |
| --sysroot="$sysroot" \ | |
| -O2 \ | |
| -DSQLITE_OMIT_LOAD_EXTENSION=1 \ | |
| -c "$sqlite_amalgamation/sqlite3.c" \ | |
| -o "$sqlite_out/build/sqlite3.o" | |
| llvm-ar crs "$sqlite_out/lib/libsqlite3.a" "$sqlite_out/build/sqlite3.o" | |
| echo "CODEXBAR_SQLITE3_LIB_DIR=$sqlite_out/lib" >> "$GITHUB_ENV" | |
| - name: Build CodexBarCLI (release, Linux musl x86_64) | |
| run: >- | |
| swift build -c release --product CodexBarCLI | |
| --swift-sdk "$SWIFT_STATIC_LINUX_SDK" | |
| --triple "$SWIFT_STATIC_LINUX_SDK_TRIPLE" | |
| - name: Smoke test Codex cost scan (Linux musl x86_64, #4672) | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| BIN_DIR="$(swift build -c release --product CodexBarCLI \ | |
| --swift-sdk "$SWIFT_STATIC_LINUX_SDK" \ | |
| --triple "$SWIFT_STATIC_LINUX_SDK_TRIPLE" \ | |
| --show-bin-path)" | |
| BIN="$BIN_DIR/CodexBarCLI" | |
| file "$BIN" | |
| bash Scripts/check-linux-cli-codex-cost-smoke.sh "$BIN" | |
| build-linux-cli: | |
| needs: changes | |
| if: ${{ needs.changes.outputs.linux-cli-build == 'true' }} | |
| timeout-minutes: 20 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - name: linux-x64 | |
| runs-on: ubuntu-24.04 | |
| - name: linux-arm64 | |
| runs-on: ubuntu-24.04-arm | |
| runs-on: ${{ matrix.runs-on }} | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Runner info | |
| run: | | |
| set -euo pipefail | |
| uname -a | |
| uname -m | |
| - name: Restore Swift toolchain cache | |
| id: swift-toolchain-cache | |
| uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| path: ~/.local/share/swiftly | |
| key: swift-${{ runner.os }}-${{ runner.arch }}-${{ env.SWIFT_VERSION }}-swiftly-${{ env.SWIFTLY_VERSION }} | |
| - name: Install Swift ${{ env.SWIFT_VERSION }} via swiftly | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| missing_packages=() | |
| for package in ca-certificates gpg libcurl4-openssl-dev; do | |
| if ! dpkg-query -W -f='${Status}' "$package" 2>/dev/null | grep -q "install ok installed"; then | |
| missing_packages+=("$package") | |
| fi | |
| done | |
| if [[ "${#missing_packages[@]}" -gt 0 ]]; then | |
| sudo apt-get update | |
| sudo apt-get install -y "${missing_packages[@]}" | |
| fi | |
| SWIFTLY_ARCH="$(uname -m)" | |
| SWIFTLY_ARCHIVE="$RUNNER_TEMP/swiftly-${SWIFTLY_VERSION}-${SWIFTLY_ARCH}.tar.gz" | |
| SWIFTLY_SIGNATURE="${SWIFTLY_ARCHIVE}.sig" | |
| SWIFTLY_HOME_DIR="$HOME/.local/share/swiftly" | |
| SWIFTLY_BIN_DIR="$HOME/.local/bin" | |
| SWIFT_GNUPGHOME="$(mktemp -d)" | |
| SWIFT_KEYS="$RUNNER_TEMP/swift-signing-keys.asc" | |
| POST_INSTALL_SCRIPT="$(mktemp)" | |
| mkdir -p "$SWIFTLY_BIN_DIR" | |
| chmod 700 "$SWIFT_GNUPGHOME" | |
| echo "Swift toolchain cache hit: ${{ steps.swift-toolchain-cache.outputs.cache-hit }}" | |
| curl -fsSL "https://download.swift.org/swiftly/linux/swiftly-${SWIFTLY_VERSION}-${SWIFTLY_ARCH}.tar.gz" -o "$SWIFTLY_ARCHIVE" | |
| curl -fsSL "https://download.swift.org/swiftly/linux/swiftly-${SWIFTLY_VERSION}-${SWIFTLY_ARCH}.tar.gz.sig" -o "$SWIFTLY_SIGNATURE" | |
| curl -fsSL --compressed "https://www.swift.org/keys/all-keys.asc" -o "$SWIFT_KEYS" | |
| GNUPGHOME="$SWIFT_GNUPGHOME" gpg --batch --import "$SWIFT_KEYS" | |
| SIGNATURE_STATUS="$(GNUPGHOME="$SWIFT_GNUPGHOME" gpg --batch --status-fd=1 \ | |
| --verify "$SWIFTLY_SIGNATURE" "$SWIFTLY_ARCHIVE" 2>&1)" | |
| printf '%s\n' "$SIGNATURE_STATUS" | |
| grep -Fq "[GNUPG:] VALIDSIG ${SWIFTLY_SIGNING_FINGERPRINT} " <<< "$SIGNATURE_STATUS" | |
| tar -xzf "$SWIFTLY_ARCHIVE" -C /tmp | |
| /tmp/swiftly init --assume-yes --skip-install | |
| . "$SWIFTLY_HOME_DIR/env.sh" | |
| echo "$SWIFTLY_BIN_DIR" >> "$GITHUB_PATH" | |
| echo "SWIFTLY_HOME_DIR=$SWIFTLY_HOME_DIR" >> "$GITHUB_ENV" | |
| echo "SWIFTLY_BIN_DIR=$SWIFTLY_BIN_DIR" >> "$GITHUB_ENV" | |
| swiftly install "$SWIFT_VERSION" --use --assume-yes --verify --post-install-file "$POST_INSTALL_SCRIPT" | |
| if [[ -s "$POST_INSTALL_SCRIPT" ]]; then | |
| sudo apt-get update | |
| sudo bash "$POST_INSTALL_SCRIPT" | |
| fi | |
| hash -r | |
| swift --version | |
| - name: Build CodexBarCLI (release, static Swift stdlib) | |
| run: swift build -c release --product CodexBarCLI --static-swift-stdlib | |
| - name: Swift Test (Linux only) | |
| run: | | |
| source Scripts/test_environment.sh | |
| swift test --parallel | |
| - name: Verify procfs teardown releases empty read buffers | |
| run: python3 Scripts/test_linux_procfs_reads.py | |
| - name: Smoke test CodexBarCLI | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| BIN_DIR="$(swift build -c release --product CodexBarCLI --static-swift-stdlib --show-bin-path)" | |
| BIN="$BIN_DIR/CodexBarCLI" | |
| "$BIN" --help >/dev/null | |
| "$BIN" --version >/dev/null | |
| if "$BIN" usage --provider codex --web >/dev/null 2>&1; then | |
| echo "Expected --web to fail on Linux" | |
| exit 1 | |
| fi | |
| "$BIN" usage --provider codex --web 2>&1 | tee /tmp/codexbarcli-stderr.txt >/dev/null || true | |
| grep -q "macOS" /tmp/codexbarcli-stderr.txt | |
| bash Scripts/check-linux-cli-codex-cost-smoke.sh "$BIN" | |
| - name: Verify CodexBarCLI does not link libxml2 | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| BIN_DIR="$(swift build -c release --product CodexBarCLI --static-swift-stdlib --show-bin-path)" | |
| BIN="$BIN_DIR/CodexBarCLI" | |
| bash Scripts/check-linux-cli-linkage.sh "$BIN" | |
| - name: Summarize Linux CLI build | |
| if: ${{ always() }} | |
| shell: bash | |
| env: | |
| MATRIX_NAME: ${{ matrix.name }} | |
| MATRIX_RUNS_ON: ${{ matrix.runs-on }} | |
| SWIFT_CACHE_HIT: ${{ steps.swift-toolchain-cache.outputs.cache-hit }} | |
| run: | | |
| set -euo pipefail | |
| { | |
| printf '### Linux CLI build\n\n' | |
| printf '| Field | Value |\n' | |
| printf '| --- | --- |\n' | |
| printf '| Matrix | `%s` |\n' "$MATRIX_NAME" | |
| printf '| Runner label | `%s` |\n' "$MATRIX_RUNS_ON" | |
| printf '| Swift version | `%s` |\n' "$SWIFT_VERSION" | |
| printf '| Swift toolchain cache hit | `%s` |\n' "${SWIFT_CACHE_HIT:-false}" | |
| } >> "$GITHUB_STEP_SUMMARY" |