PoC: binary xcframework release pipeline #6
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: Release Build | |
| # Build xcframework on a GitHub-hosted macOS runner, resolving Swift package | |
| # dependencies through the curated Artifactory pull-through cache (ADR Rule 3). | |
| # Produces a build attestation binding the artifact digest to the source commit. | |
| on: | |
| push: | |
| pull_request: | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| id-token: write | |
| attestations: write | |
| jobs: | |
| build_xcframework: | |
| runs-on: macos-15 | |
| env: | |
| ARTIFACT_NAME: Segment.xcframework.zip | |
| ARTIFACTORY_URL: https://twilio.jfrog.io | |
| SWIFT_VIRTUAL_REPO: virtual-swift-thirdparty | |
| outputs: | |
| artifact-digest: ${{ steps.digest.outputs.sha256 }} | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| - name: Select Xcode | |
| run: sudo xcode-select -s /Applications/Xcode_16.2.app/Contents/Developer | |
| # Exchange GitHub OIDC token for a short-lived Artifactory read token. | |
| # The segmentio org uses provider_name "github-actions-segmentio". | |
| # Token lands in sdk-build-readers group (read access to virtual repos). | |
| - name: Get Artifactory token via OIDC | |
| run: | | |
| set -euo pipefail | |
| OIDC_JWT=$(curl -sS "${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=${ARTIFACTORY_URL}" \ | |
| -H "Authorization: Bearer ${ACTIONS_ID_TOKEN_REQUEST_TOKEN}" | jq -r '.value') | |
| ART_TOKEN=$(curl -sS "${ARTIFACTORY_URL}/access/api/v1/oidc/token" \ | |
| -H 'Content-Type: application/json' \ | |
| -d "{\"grant_type\":\"urn:ietf:params:oauth:grant-type:token-exchange\", | |
| \"subject_token_type\":\"urn:ietf:params:oauth:token-type:id_token\", | |
| \"subject_token\":\"${OIDC_JWT}\", | |
| \"provider_name\":\"github-actions-segmentio\"}" | jq -r '.access_token') | |
| echo "::add-mask::$ART_TOKEN" | |
| echo "ART_TOKEN=$ART_TOKEN" >> "$GITHUB_ENV" | |
| # Configure SPM to resolve dependencies through the Artifactory Swift | |
| # pull-through cache instead of hitting GitHub directly. | |
| - name: Configure SPM to resolve through Artifactory | |
| run: | | |
| set -euo pipefail | |
| MIRROR_BASE="${ARTIFACTORY_URL}/artifactory/api/swift/${SWIFT_VIRTUAL_REPO}" | |
| # Set up netrc for git authentication to Artifactory | |
| echo "machine twilio.jfrog.io login token password ${ART_TOKEN}" > ~/.netrc | |
| chmod 600 ~/.netrc | |
| # Mirror each dependency through Artifactory | |
| swift package config set-mirror \ | |
| --original-url https://github.com/segmentio/sovran-swift.git \ | |
| --mirror-url "${MIRROR_BASE}/segmentio/sovran-swift.git" | |
| swift package config set-mirror \ | |
| --original-url https://github.com/segmentio/jsonsafeencoding-swift.git \ | |
| --mirror-url "${MIRROR_BASE}/segmentio/jsonsafeencoding-swift.git" | |
| - name: Resolve dependencies | |
| run: swift package resolve | |
| # Build xcframework for all supported platforms | |
| - name: Build xcframework | |
| run: | | |
| set -euo pipefail | |
| ARCHIVE_DIR="$(pwd)/.build/archives" | |
| XCFRAMEWORK_DIR="$(pwd)/.build/xcframework" | |
| mkdir -p "$ARCHIVE_DIR" "$XCFRAMEWORK_DIR" | |
| declare -a PLATFORMS=( | |
| "iOS:generic/platform=iOS" | |
| "iOS-Simulator:generic/platform=iOS Simulator" | |
| "macOS:generic/platform=macOS" | |
| "tvOS:generic/platform=tvOS" | |
| "tvOS-Simulator:generic/platform=tvOS Simulator" | |
| "watchOS:generic/platform=watchOS" | |
| "watchOS-Simulator:generic/platform=watchOS Simulator" | |
| ) | |
| FRAMEWORK_ARGS=() | |
| for entry in "${PLATFORMS[@]}"; do | |
| NAME="${entry%%:*}" | |
| DEST="${entry#*:}" | |
| ARCHIVE_PATH="$ARCHIVE_DIR/$NAME.xcarchive" | |
| xcodebuild archive \ | |
| -scheme Segment \ | |
| -destination "$DEST" \ | |
| -archivePath "$ARCHIVE_PATH" \ | |
| -derivedDataPath .build/derived-data \ | |
| SKIP_INSTALL=NO \ | |
| BUILD_LIBRARY_FOR_DISTRIBUTION=YES \ | |
| SWIFT_SERIALIZE_DEBUGGING_OPTIONS=NO | |
| FRAMEWORK_ARGS+=("-framework" "$ARCHIVE_PATH/Products/Library/Frameworks/Segment.framework") | |
| done | |
| xcodebuild -create-xcframework \ | |
| "${FRAMEWORK_ARGS[@]}" \ | |
| -output "$XCFRAMEWORK_DIR/Segment.xcframework" | |
| cd "$XCFRAMEWORK_DIR" | |
| ditto -c -k --sequesterRsrc --keepParent Segment.xcframework "${{ env.ARTIFACT_NAME }}" | |
| mv "${{ env.ARTIFACT_NAME }}" "$GITHUB_WORKSPACE/" | |
| - name: Compute artifact digest | |
| id: digest | |
| run: | | |
| SHA256=$(shasum -a 256 "${{ env.ARTIFACT_NAME }}" | awk '{print $1}') | |
| echo "sha256=$SHA256" >> "$GITHUB_OUTPUT" | |
| echo "Artifact digest: $SHA256" | |
| - name: Attest build provenance | |
| uses: actions/attest-build-provenance@1c608d11d69870c2092266b3f9a6f3abbf17002c # v1.4.3 | |
| with: | |
| subject-path: ${{ env.ARTIFACT_NAME }} | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: xcframework-release | |
| path: ${{ env.ARTIFACT_NAME }} | |
| retention-days: 30 |