Build and Release XCFramework #11
This file contains 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: Build and Release XCFramework | ||
on: | ||
push: | ||
branches: [ main ] | ||
tags: | ||
- 'v*' # This will trigger the workflow on any tag starting with 'v' | ||
pull_request: | ||
branches: [ main ] | ||
workflow_dispatch: | ||
inputs: | ||
release_version: | ||
description: 'Release version (must start with "v", e.g., v0.1.6)' | ||
required: false | ||
default: '' | ||
env: | ||
OUTPUT_DIR: ${{ github.workspace }}/output | ||
jobs: | ||
build: | ||
runs-on: macos-latest | ||
strategy: | ||
matrix: | ||
config: | ||
- { sdk: 'macosx', arch: 'arm64', platform: 'MacOSX' } | ||
- { sdk: 'macosx', arch: 'x86_64', platform: 'MacOSX' } | ||
- { sdk: 'iphoneos', arch: 'arm64', platform: 'iPhoneOS' } | ||
- { sdk: 'iphonesimulator', arch: 'x86_64', platform: 'iPhoneSimulator' } | ||
- { sdk: 'iphonesimulator', arch: 'arm64', platform: 'iPhoneSimulator' } | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Get Xcode version | ||
id: xcode-version | ||
run: echo "version=$(xcodebuild -version | grep Xcode | awk '{print $2}')" >> $GITHUB_OUTPUT | ||
- name: Get macOS version | ||
id: macos-version | ||
run: echo "version=$(sw_vers -productVersion)" >> $GITHUB_OUTPUT | ||
- name: Cache build results | ||
uses: actions/cache@v4 | ||
id: cache | ||
with: | ||
path: ${{ env.OUTPUT_DIR }} | ||
key: ${{ runner.os }}-build-${{ matrix.config.sdk }}-${{ matrix.config.arch }}-${{ hashFiles('**/*.c', '**/*.cpp', '**/*.h', '**/*.m', '**/*.mm', '.github/actions/*.sh') }}-${{ steps.xcode-version.outputs.version }}-${{ steps.macos-version.outputs.version }} | ||
Check failure on line 48 in .github/workflows/build_xcframework.yml GitHub Actions / Build and Release XCFrameworkInvalid workflow file
|
||
- name: Set up Xcode | ||
if: steps.cache.outputs.cache-hit != 'true' | ||
uses: maxim-lobanov/setup-xcode@v1 | ||
with: | ||
xcode-version: latest-stable | ||
- name: Install autotools | ||
if: steps.cache.outputs.cache-hit != 'true' | ||
run: brew install autoconf automake libtool | ||
- name: Setup build environment | ||
if: steps.cache.outputs.cache-hit != 'true' | ||
run: | | ||
aclocal && autoconf && automake --add-missing | ||
mkdir -p "$OUTPUT_DIR" | ||
- name: Build for ${{ matrix.config.sdk }} ${{ matrix.config.arch }} | ||
if: steps.cache.outputs.cache-hit != 'true' | ||
run: | | ||
./.github/actions/build_library.sh ${{ matrix.config.sdk }} ${{ matrix.config.arch }} ${{ matrix.config.platform }} | ||
- name: Upload build artifact | ||
uses: actions/upload-artifact@v4 | ||
with: | ||
name: build-${{ matrix.config.sdk }}-${{ matrix.config.arch }} | ||
path: ${{ env.OUTPUT_DIR }} | ||
retention-days: 1 | ||
create-xcframework: | ||
needs: build | ||
runs-on: macos-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Download all build artifacts | ||
uses: actions/download-artifact@v4 | ||
with: | ||
path: ${{ env.OUTPUT_DIR }} | ||
- name: List downloaded artifacts | ||
run: | | ||
echo "Contents of OUTPUT_DIR:" | ||
ls -R ${{ env.OUTPUT_DIR }} | ||
- name: Create fat libraries using lipo | ||
run: | | ||
mkdir -p "${OUTPUT_DIR}/fat" | ||
MACOS_ARCHS="arm64 x86_64" | ||
IPHONEOS_ARCHS="arm64" | ||
IPHONESIMULATOR_ARCHS="x86_64 arm64" | ||
LIBRARIES="libopencore-amrnb libopencore-amrwb" | ||
for lib in $LIBRARIES; do | ||
# For macOS | ||
lipo -create $(for arch in $MACOS_ARCHS; do echo "${OUTPUT_DIR}/build-macosx-${arch}/macosx-${arch}-MacOSX/lib/${lib}.a"; done) \ | ||
-output "${OUTPUT_DIR}/fat/${lib}-macos.a" | ||
# For iOS device | ||
cp "${OUTPUT_DIR}/build-iphoneos-arm64/iphoneos-arm64-iPhoneOS/lib/${lib}.a" "${OUTPUT_DIR}/fat/${lib}-iphoneos.a" | ||
# For iOS simulator | ||
lipo -create $(for arch in $IPHONESIMULATOR_ARCHS; do echo "${OUTPUT_DIR}/build-iphonesimulator-${arch}/iphonesimulator-${arch}-iPhoneSimulator/lib/${lib}.a"; done) \ | ||
-output "${OUTPUT_DIR}/fat/${lib}-iphonesimulator.a" | ||
done | ||
- name: Create XCFrameworks | ||
run: | | ||
mkdir -p "${OUTPUT_DIR}/Headers/" | ||
LIBRARIES="opencore-amrnb opencore-amrwb" | ||
PLATFORMS="macos iphoneos iphonesimulator" | ||
for lib in $LIBRARIES; do | ||
rm -rf ${OUTPUT_DIR}/Headers/* | ||
rm -rf ${OUTPUT_DIR}/${lib}.xcframework | ||
# Copy headers | ||
case $lib in | ||
opencore-amrnb) | ||
cp -a amrnb/interf_dec.h amrnb/interf_enc.h ${OUTPUT_DIR}/Headers/ | ||
;; | ||
opencore-amrwb) | ||
cp -a amrwb/dec_if.h amrwb/if_rom.h ${OUTPUT_DIR}/Headers/ | ||
;; | ||
esac | ||
# Prepare xcodebuild command | ||
cmd="xcodebuild -create-xcframework" | ||
for platform in $PLATFORMS; do | ||
cmd+=" -library ${OUTPUT_DIR}/fat/lib${lib}-${platform}.a" | ||
cmd+=" -headers ${OUTPUT_DIR}/Headers" | ||
done | ||
cmd+=" -output ${OUTPUT_DIR}/${lib}.xcframework" | ||
# Execute xcodebuild command | ||
eval $cmd | ||
done | ||
- name: Zip XCFrameworks | ||
run: | | ||
cd ${{ env.OUTPUT_DIR }} | ||
for framework in *.xcframework; do | ||
zip -r "${framework%.xcframework}.xcframework.zip" "$framework" | ||
done | ||
ls -la | ||
- name: Upload XCFrameworks | ||
uses: actions/upload-artifact@v4 | ||
with: | ||
name: XCFrameworks | ||
path: ${{ env.OUTPUT_DIR }}/*.xcframework.zip | ||
if-no-files-found: error | ||
release: | ||
needs: create-xcframework | ||
runs-on: ubuntu-latest | ||
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch' | ||
steps: | ||
- name: Download XCFrameworks | ||
uses: actions/download-artifact@v4 | ||
with: | ||
name: XCFrameworks | ||
- name: Determine Release Version | ||
id: version | ||
run: | | ||
if [[ $GITHUB_REF == refs/tags/* ]]; then | ||
VERSION=${GITHUB_REF#refs/tags/} | ||
elif [[ "${{ github.event.inputs.release_version }}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | ||
VERSION=${{ github.event.inputs.release_version }} | ||
else | ||
echo "Error: Invalid version format. Must start with 'v' followed by semantic versioning." | ||
exit 1 | ||
fi | ||
echo "version=$VERSION" >> $GITHUB_OUTPUT | ||
- name: Create Release and Upload XCFrameworks | ||
uses: softprops/action-gh-release@v2 | ||
with: | ||
tag_name: ${{ steps.version.outputs.version }} | ||
name: Release ${{ steps.version.outputs.version }} | ||
draft: false | ||
prerelease: false | ||
generate_release_notes: true | ||
fail_on_unmatched_files: true | ||
files: | | ||
*.xcframework.zip | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
- name: Check Release | ||
run: | | ||
echo "Checking release ${{ steps.version.outputs.version }}" | ||
release_info=$(curl -sS -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ | ||
https://api.github.com/repos/${{ github.repository }}/releases/tags/${{ steps.version.outputs.version }}) | ||
echo "Release info:" | ||
echo "$release_info" | jq '.' | ||
assets=$(echo "$release_info" | jq -r '.assets[].name') | ||
echo "Release assets:" | ||
echo "$assets" |