Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
0f3e065
Prototype: SPM distribution via prebuilt xcframework (Apple)
bmehta001 Jun 18, 2026
5e3687e
Prototype: SPM release workflow + parallel 3-component SemVer tag
bmehta001 Jun 18, 2026
ba7ba4c
Fix local SPM xcframework consumption
bmehta001 Jun 18, 2026
308e031
Copy only public ObjC headers into xcframework
bmehta001 Jun 18, 2026
dd97234
Align SPM package with xcframework contents
bmehta001 Jun 18, 2026
accb600
Generate SPM availability from xcframework build
bmehta001 Jun 18, 2026
4e03dff
Address SPM prototype review refinements
bmehta001 Jun 18, 2026
0edd5f1
Align Apple SPM docs and module availability
bmehta001 Jun 18, 2026
6d27fba
Add macOS slice to SPM xcframework
bmehta001 Jun 19, 2026
d242830
Add Mac Catalyst slice to SPM xcframework
bmehta001 Jun 19, 2026
1d89f6d
Add visionOS slices to SPM xcframework
bmehta001 Jun 19, 2026
0246847
Address SPM release review comments
bmehta001 Jun 19, 2026
9634894
Address follow-up SPM review comments
bmehta001 Jun 19, 2026
5923e5c
Validate SPM Apple platforms in release workflow
bmehta001 Jun 19, 2026
ccceaa5
Skip package creation for xcframework slices
bmehta001 Jun 19, 2026
5c6f574
Clean up Apple SPM README
bmehta001 Jun 19, 2026
79f55fa
Remove status label from Apple SPM README
bmehta001 Jun 19, 2026
27049fe
Assert SPM platforms in release workflow
bmehta001 Jun 19, 2026
55c4ce5
Clean up xcframework build script comments
bmehta001 Jun 19, 2026
9a18330
Use fresh build cache for each xcframework slice
bmehta001 Jun 19, 2026
279ffd3
Use portable shell comparison in iOS build
bmehta001 Jun 19, 2026
7bc7415
Quote ${IOS_PLAT}/${IOS_ARCH} in Apple if() conditions
bmehta001 Jun 19, 2026
9d52266
Rename public Clang module ObjCModule -> MATTelemetryObjC
bmehta001 Jun 19, 2026
2b5bdd5
docs(apple): note xcframework expects system sqlite3/zlib
bmehta001 Jun 19, 2026
f2c5fc9
Use PIIKind alias in SemanticContext.setUserID signature
bmehta001 Jun 19, 2026
06caea2
Fix SemanticContext.setUserID dropping the caller's piiKind
bmehta001 Jun 19, 2026
a57c2a1
Address Swift package review refinements
bmehta001 Jun 19, 2026
5aa9d43
Surface per-batch record count (param2) in HTTP response debug events…
mogiligarimidi23 Jun 22, 2026
62cef16
Fix GUID_t::operator< to be a valid strict-weak-ordering (#1490)
bmehta001 Jun 22, 2026
beba0e8
Fix inverted oneds_memcpy_s result in CompactBinaryProtocolReader::Re…
bmehta001 Jun 22, 2026
c093ac1
New flag to scrub IP addresses (#1161)
maxgolov Jun 23, 2026
6c37993
vcpkg port: release-bump workflow, overlay port bump, and consumer bi…
bmehta001 Jun 23, 2026
edf33f8
Prepare for new release - 3.10.173.1 (#1489)
bmehta001 Jun 23, 2026
5d73b5d
Merge branch 'main' into bhamehta/spm-xcframework-prototype
bmehta001 Jun 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
172 changes: 172 additions & 0 deletions .github/workflows/spm-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
name: SPM release (xcframework)

# On a published SDK release, build MATTelemetry.xcframework, upload it to the
# GitHub Release, and publish a 3-component SemVer tag for Swift Package Manager
# whose Package.swift binaryTarget points at the uploaded artifact + checksum.
#
# Why a separate tag: the SDK's own release tags are 4-component (vX.Y.Z.W),
# which is NOT valid SemVer, so Swift Package Manager ignores them. This derives
# a 3-component tag (X.Y.Z) from the same release that SPM can resolve.
#
# Prerequisites:
# * The root Package.swift (the SPM manifest) must exist at the release tag
# (i.e. this prototype merged to main before the release is cut).
# * Uses the default GITHUB_TOKEN (needs contents: write). No extra secrets.

on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: "4-component release tag to publish for SPM (e.g. v3.10.161.1)"
required: true
type: string

permissions:
contents: write

concurrency:
group: spm-release-${{ github.event.release.tag_name || inputs.tag }}
cancel-in-progress: false

jobs:
spm:
name: Publish SPM xcframework + tag
# Skip drafts/pre-releases; always allow manual dispatch.
if: >-
${{ github.event_name == 'workflow_dispatch' ||
(github.event.release.draft == false && github.event.release.prerelease == false) }}
runs-on: macos-15 # provides Xcode with Apple platform SDKs (xcodebuild, swift)
env:
ARTIFACT: MATTelemetry.xcframework.zip
steps:
- name: Resolve tag and derive SPM version
id: ver
env:
# Pass untrusted tag values through the environment rather than
# interpolating ${{ ... }} into the script body.
RELEASE_TAG: ${{ github.event.release.tag_name }}
INPUT_TAG: ${{ inputs.tag }}
run: |
set -euo pipefail
TAG="${RELEASE_TAG:-$INPUT_TAG}"
if [ -z "$TAG" ]; then echo "::error::No release tag could be resolved."; exit 1; fi
# Only act on 4-component version tags vX.Y.Z.W.
if ! printf '%s' "$TAG" | grep -Eq '^v[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$'; then
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "::error::Tag '$TAG' is not a 4-component version tag (expected vX.Y.Z.W)."
exit 1
fi
echo "::notice::Tag '$TAG' is not a 4-component version tag; nothing to publish."
echo "skip=true" >> "$GITHUB_OUTPUT"
exit 0
fi
VERSION="${TAG#v}" # X.Y.Z.W
SPM_VERSION="${VERSION%.*}" # X.Y.Z (drop the trailing build component)
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
echo "spm_version=$SPM_VERSION" >> "$GITHUB_OUTPUT"
echo "Release $TAG -> SPM tag $SPM_VERSION"

- name: Checkout the release tag
if: ${{ steps.ver.outputs.skip != 'true' }}
uses: actions/checkout@v4
with:
ref: ${{ steps.ver.outputs.tag }}
fetch-depth: 0
# The private lib/modules submodule is intentionally NOT fetched; the
# xcframework ships the core SDK + Obj-C wrappers, matching the vcpkg
# port (the optional modules are excluded there too).
submodules: false

- name: Build MATTelemetry.xcframework
if: ${{ steps.ver.outputs.skip != 'true' }}
run: |
set -euo pipefail
chmod +x tools/apple/build-xcframework.sh
tools/apple/build-xcframework.sh release
test -f "build/apple/$ARTIFACT"

- name: Validate SwiftPM package consumption
if: ${{ steps.ver.outputs.skip != 'true' }}
run: |
set -euo pipefail
swift package dump-package > package.json
python3 - <<'PY'
import json
expected = {
"ios": "12.0",
"maccatalyst": "14.0",
"macos": "10.15",
"visionos": "1.0",
}
with open("package.json", encoding="utf-8") as f:
platforms = {
item["platformName"]: item["version"]
for item in json.load(f)["platforms"]
}
if platforms != expected:
raise SystemExit(f"Unexpected Package.swift platforms: {platforms}")
PY
swift build
xcodebuild -scheme OneDSSwift -destination 'generic/platform=iOS Simulator' build
xcodebuild -scheme OneDSSwift -destination 'platform=macOS,variant=Mac Catalyst' build
xcodebuild -scheme OneDSSwift -destination 'generic/platform=visionOS Simulator' build

- name: Compute SPM checksum
id: sum
if: ${{ steps.ver.outputs.skip != 'true' }}
run: |
set -euo pipefail
checksum="$(swift package compute-checksum "build/apple/$ARTIFACT")"
echo "checksum=$checksum" >> "$GITHUB_OUTPUT"

- name: Upload xcframework to the release
if: ${{ steps.ver.outputs.skip != 'true' }}
env:
GH_TOKEN: ${{ github.token }}
run: gh release upload "${{ steps.ver.outputs.tag }}" "build/apple/$ARTIFACT" --clobber

- name: Point Package.swift at the released artifact
if: ${{ steps.ver.outputs.skip != 'true' }}
env:
ASSET_URL: https://github.com/${{ github.repository }}/releases/download/${{ steps.ver.outputs.tag }}/MATTelemetry.xcframework.zip
CHECKSUM: ${{ steps.sum.outputs.checksum }}
run: |
set -euo pipefail
python3 - "$ASSET_URL" "$CHECKSUM" <<'PY'
import re, sys
url, checksum = sys.argv[1], sys.argv[2]
path = "Package.swift"
src = open(path).read()
repl = (
'.binaryTarget(\n'
' name: "MATTelemetry",\n'
f' url: "{url}",\n'
f' checksum: "{checksum}")'
)
out = re.sub(
r'\.binaryTarget\(\s*name:\s*"MATTelemetry",\s*path:\s*"[^"]*"\s*\)',
repl, src, count=1)
assert out != src, "binaryTarget(path:) block not found in Package.swift"
open(path, "w").write(out)
PY

- name: Commit manifest and push the 3-component SPM tag
if: ${{ steps.ver.outputs.skip != 'true' }}
run: |
set -euo pipefail
if git ls-remote --exit-code --tags origin "refs/tags/${{ steps.ver.outputs.spm_version }}" >/dev/null; then
echo "::notice::SPM tag ${{ steps.ver.outputs.spm_version }} already exists; skipping tag publish."
exit 0
fi
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add Package.swift tools/apple/MATTelemetryAvailability.json
git commit -m "[spm] ${{ steps.ver.outputs.spm_version }}: pin xcframework url + checksum"
# The SPM tag points at this commit (release source + resolved
# binaryTarget). It is published as a tag only, not merged to a branch.
git tag -a "${{ steps.ver.outputs.spm_version }}" \
-m "Swift Package Manager release ${{ steps.ver.outputs.spm_version }} (from ${{ steps.ver.outputs.tag }})"
git push origin "refs/tags/${{ steps.ver.outputs.spm_version }}"
echo "Published SPM tag ${{ steps.ver.outputs.spm_version }}"
193 changes: 193 additions & 0 deletions .github/workflows/vcpkg-release-bump.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
name: Vcpkg release bump

# Opens a version-bump pull request against microsoft/vcpkg for the
# `cpp-client-telemetry` port whenever a new SDK release is published.
#
# It runs ONLY when a new version is cut:
# * automatically on a published, non-draft, non-prerelease GitHub Release
# whose tag looks like a version (vMAJOR.MINOR.PATCH.BUILD), or
# * manually via workflow_dispatch for a specific tag (recovery / re-run).
# It never runs on ordinary pushes, and it opens no PR if the port already
# matches the release (no version change).
#
# One-time setup required in this repository:
# * Variable VCPKG_FORK_REPO -> the vcpkg fork to push branches to,
# e.g. "your-org/vcpkg".
# * Secret VCPKG_BUMP_TOKEN -> a PAT (classic: repo+workflow, or
# fine-grained: Contents+Pull requests RW on
# the fork) able to push to VCPKG_FORK_REPO and
# open pull requests on microsoft/vcpkg.

on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: "Release tag to bump the vcpkg port to (e.g. v3.10.161.1)"
required: true
type: string

permissions:
contents: read

concurrency:
group: vcpkg-release-bump-${{ github.event.release.tag_name || github.event.inputs.tag }}
cancel-in-progress: false

jobs:
bump:
name: Bump cpp-client-telemetry port
# Skip drafts and pre-releases; always allow manual dispatch.
if: >-
${{ github.event_name == 'workflow_dispatch' ||
(github.event.release.draft == false && github.event.release.prerelease == false) }}
runs-on: ubuntu-latest
env:
UPSTREAM_REPO: ${{ github.repository }} # microsoft/cpp_client_telemetry
VCPKG_UPSTREAM: microsoft/vcpkg
VCPKG_FORK_REPO: ${{ vars.VCPKG_FORK_REPO }}
PORT: cpp-client-telemetry
steps:
- name: Validate configuration
env:
VCPKG_BUMP_TOKEN: ${{ secrets.VCPKG_BUMP_TOKEN }}
run: |
set -euo pipefail
if [ -z "${VCPKG_FORK_REPO}" ]; then
echo "::error::Repository variable VCPKG_FORK_REPO is not set (e.g. 'your-org/vcpkg')."
exit 1
fi
if [ -z "${VCPKG_BUMP_TOKEN}" ]; then
echo "::error::Secret VCPKG_BUMP_TOKEN is not set. Provide a token that can push to ${VCPKG_FORK_REPO} and open PRs on ${VCPKG_UPSTREAM}."
exit 1
fi

- name: Resolve tag and version
id: ver
env:
# Pass untrusted tag values through the environment instead of
# interpolating ${{ ... }} directly into the script body, so a tag
# containing shell metacharacters cannot inject commands into this
# step (which shares a runner with later PAT-bearing steps).
RELEASE_TAG: ${{ github.event.release.tag_name }}
INPUT_TAG: ${{ github.event.inputs.tag }}
run: |
set -euo pipefail
TAG="${RELEASE_TAG:-$INPUT_TAG}"
if [ -z "${TAG}" ]; then echo "::error::No release tag could be resolved."; exit 1; fi
# Only act on version tags: vMAJOR.MINOR.PATCH.BUILD. A non-matching
# tag from the automatic release trigger is a clean no-op (the SDK also
# has historical 3-part tags such as v3.3.8); a non-matching tag from a
# manual workflow_dispatch is user error and fails loudly.
if ! printf '%s' "${TAG}" | grep -Eq '^v[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$'; then
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "::error::Tag '${TAG}' is not a version tag (expected vX.Y.Z.W)."
exit 1
fi
echo "::notice::Tag '${TAG}' is not a version tag (expected vX.Y.Z.W); nothing to bump."
echo "skip=true" >> "$GITHUB_OUTPUT"
exit 0
fi
VERSION="${TAG#v}"
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "branch=port/${PORT}-${VERSION}" >> "$GITHUB_OUTPUT"
echo "Bumping ${PORT} -> tag=${TAG} version=${VERSION}"

- name: Compute source archive SHA512
id: sha
if: ${{ steps.ver.outputs.skip != 'true' }}
run: |
set -euo pipefail
URL="https://github.com/${UPSTREAM_REPO}/archive/${{ steps.ver.outputs.tag }}.tar.gz"
echo "Downloading ${URL}"
curl -fsSL --retry 3 "${URL}" -o source.tar.gz
SHA512="$(sha512sum source.tar.gz | cut -d' ' -f1)"
echo "sha512=${SHA512}" >> "$GITHUB_OUTPUT"
echo "SHA512=${SHA512}"

- name: Clone vcpkg fork and branch off upstream master
if: ${{ steps.ver.outputs.skip != 'true' }}
env:
GH_TOKEN: ${{ secrets.VCPKG_BUMP_TOKEN }}
run: |
set -euo pipefail
# Authenticate git via gh's credential helper instead of embedding the
# token in the clone URL (which would persist it in .git/config and
# risk leaking it if git echoes the remote). The helper is written to
# the global gitconfig and reused by the later push step.
gh auth setup-git
git clone --depth 1 "https://github.com/${VCPKG_FORK_REPO}.git" vcpkg
cd vcpkg
git remote add upstream "https://github.com/${VCPKG_UPSTREAM}.git"
git fetch --depth 1 upstream master
git checkout -B "${{ steps.ver.outputs.branch }}" upstream/master
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"

- name: Bootstrap vcpkg
if: ${{ steps.ver.outputs.skip != 'true' }}
run: cd vcpkg && ./bootstrap-vcpkg.sh -disableMetrics

- name: Update port REF, SHA512 and version
if: ${{ steps.ver.outputs.skip != 'true' }}
run: |
set -euo pipefail
cd vcpkg
PORTFILE="ports/${PORT}/portfile.cmake"
MANIFEST="ports/${PORT}/vcpkg.json"
if [ ! -f "${PORTFILE}" ] || [ ! -f "${MANIFEST}" ]; then
echo "::error::${PORT} port not found in ${VCPKG_UPSTREAM}. The port must already be in the registry before it can be bumped."
exit 1
fi
sed -i -E "s|^([[:space:]]*REF[[:space:]]+).*$|\1${{ steps.ver.outputs.tag }}|" "${PORTFILE}"
sed -i -E "s|^([[:space:]]*SHA512[[:space:]]+).*$|\1${{ steps.sha.outputs.sha512 }}|" "${PORTFILE}"
jq --arg v "${{ steps.ver.outputs.version }}" '.version = $v | del(."port-version")' "${MANIFEST}" > "${MANIFEST}.tmp"
mv "${MANIFEST}.tmp" "${MANIFEST}"
./vcpkg format-manifest "${MANIFEST}"

- name: Detect change
id: diff
if: ${{ steps.ver.outputs.skip != 'true' }}
run: |
set -euo pipefail
cd vcpkg
if git diff --quiet -- "ports/${PORT}"; then
echo "changed=false" >> "$GITHUB_OUTPUT"
echo "No change: ${PORT} is already at ${{ steps.ver.outputs.version }} with this REF/SHA512. Nothing to do."
else
echo "changed=true" >> "$GITHUB_OUTPUT"
fi

- name: Commit, update version DB, push and open PR
if: ${{ steps.ver.outputs.skip != 'true' && steps.diff.outputs.changed == 'true' }}
env:
GH_TOKEN: ${{ secrets.VCPKG_BUMP_TOKEN }}
run: |
set -euo pipefail
cd vcpkg
# gh auth setup-git ran in the clone step; reuse that credential helper
# so 'git push' authenticates without a token in the remote URL.
BR="${{ steps.ver.outputs.branch }}"
git add "ports/${PORT}"
git commit -m "[${PORT}] Update to ${{ steps.ver.outputs.version }}"
./vcpkg x-add-version "${PORT}" --overwrite-version
git add versions
git commit -m "[${PORT}] Update version database"
# Ensure a remote-tracking ref exists so --force-with-lease has a lease
# to compare against on reruns: the bump branch may already exist on the
# fork but be absent from this fresh clone. Ignore failure on the first
# run, when the branch does not exist remotely yet.
git fetch origin "+refs/heads/${BR}:refs/remotes/origin/${BR}" || true
git push --force-with-lease origin "${BR}"
if [ -n "$(gh pr list --repo "${VCPKG_UPSTREAM}" --head "$(printf '%s' "${VCPKG_FORK_REPO}" | cut -d/ -f1):${BR}" --state open --json number --jq '.[0].number // empty' 2>/dev/null)" ]; then
echo "An open PR already exists for ${BR}; the force-pushed branch refreshes it."
else
gh pr create \
--repo "${VCPKG_UPSTREAM}" \
--base master \
--head "$(printf '%s' "${VCPKG_FORK_REPO}" | cut -d/ -f1):${BR}" \
--title "[${PORT}] Update to ${{ steps.ver.outputs.version }}" \
--body "Automated port bump to [\`${UPSTREAM_REPO}@${{ steps.ver.outputs.tag }}\`](https://github.com/${UPSTREAM_REPO}/releases/tag/${{ steps.ver.outputs.tag }}). Generated by the \`vcpkg-release-bump\` workflow."
fi
Loading
Loading