Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
4f92304
Reorganize repo to make better use of Xcode features
redaranj Sep 11, 2025
323508e
Update web service property names
redaranj Sep 11, 2025
938bd66
Example app cleanup
redaranj Sep 12, 2025
f00d357
Differentiate dev/release Package.swift files
redaranj Sep 12, 2025
d6408da
Update README to reflect new project structure and build steps
redaranj Sep 16, 2025
e85c061
Update signing server base URL config
redaranj Sep 22, 2025
837f625
Update xcode version
redaranj Sep 24, 2025
ab4f593
Fix Swift concurrency build errors
redaranj Sep 24, 2025
e534af8
Fix xcframework location
redaranj Sep 24, 2025
5627ce7
More makefile updates
redaranj Sep 24, 2025
6e24a89
Fix build output lookup
redaranj Sep 24, 2025
8d37256
Update Package.swift for release v0.0.3
actions-user Sep 24, 2025
d41a4a2
Update gitignore
redaranj Sep 24, 2025
9da85c0
Update Package.swift
redaranj Sep 24, 2025
1e51e8b
Update ios-framework task
redaranj Sep 24, 2025
977527c
Remove release build step
redaranj Sep 24, 2025
cd37a29
Update Package.swift for release v0.0.4
actions-user Sep 24, 2025
d942aab
Update C2PAC binary target URL to version 0.0.4
redaranj Sep 24, 2025
f4d6ba9
Update plist and release path
redaranj Sep 24, 2025
4e87023
Update Package.swift for release v0.0.5
actions-user Sep 24, 2025
39d1408
Release process fixes
redaranj Sep 25, 2025
5249975
Fix C2PAC plist values
redaranj Sep 29, 2025
b0e5474
Allow custom headers on WebServiceSigner
redaranj Sep 29, 2025
21971bd
Merge branch 'main' into chore/reorganize-repo
redaranj Sep 29, 2025
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
72 changes: 21 additions & 51 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,83 +4,53 @@ on:
workflow_dispatch:
inputs:
version:
description: 'Version for the release (e.g. v1.0.0)'
description: "Version for the release (e.g. v1.0.0)"
required: true
type: string

jobs:
build-and-release:
runs-on: macos-latest
runs-on: macos-15

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Validate version format
run: |
if [[ ! "${{ github.event.inputs.version }}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "::error::Version must be in format vX.Y.Z (e.g., v1.0.0)"
exit 1
fi

run: make validate-version VERSION="${{ github.event.inputs.version }}"

- name: Display release information
run: |
echo "Starting release process for version ${{ github.event.inputs.version }}"
echo "This workflow will:"
echo "1. Download pre-built binaries from GitHub releases"
echo "2. Build iOS XCFramework"
echo "3. Create and publish Swift Package"
echo "4. Create GitHub release with artifacts"
echo "1. Build iOS XCFramework"
echo "2. Create and publish Swift Package"
echo "3. Create GitHub release with artifacts"

- name: Set up Xcode 16.4
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: 16.4

- name: Verify Xcode version
run: xcodebuild -version

- name: Select Xcode version
run: |
sudo xcode-select -s /Applications/Xcode_15.4.app
xcodebuild -version

- name: Run tests before release
run: |
cd example
xcodebuild test \
-scheme C2PAExample \
-destination 'platform=iOS Simulator,name=iPhone 16 Pro,OS=18.4' \
| xcpretty --test --color

- name: Build iOS Framework
run: make ios-framework

- name: Zip XCFramework for distribution
run: |
cd output
zip -r C2PAC.xcframework.zip C2PAC.xcframework

- name: Compute checksum for XCFramework
id: compute-checksum
run: |
cd output
CHECKSUM=$(swift package compute-checksum C2PAC.xcframework.zip)
CHECKSUM=$(make compute-checksum | tail -1)
echo "CHECKSUM=$CHECKSUM" >> $GITHUB_ENV
echo "Checksum: $CHECKSUM"

- name: Archive Swift Package
run: |
cd output
zip -r C2PA-Swift-Package.zip C2PA-iOS/

- name: Copy Package.swift from template to root
run: |
cp template/Package.swift ./Package.swift
run: make package-swift

- name: Update Package.swift with release URL and checksum
run: |
VERSION="${{ github.event.inputs.version }}"
CHECKSUM="${{ env.CHECKSUM }}"

# Replace the path with URL and checksum (using # as delimiter)
sed -i '' 's# path: "Frameworks/C2PAC.xcframework"# url: "https://github.com/${{ github.repository }}/releases/download/'${VERSION}'/C2PAC.xcframework.zip",\n checksum: "'${CHECKSUM}'"#g' ./Package.swift

# Replace the path to the Swift file
sed -i '' 's# path: "Sources/C2PA"# path: "src"#g' ./Package.swift

make update-package-swift VERSION="${{ github.event.inputs.version }}" CHECKSUM="${{ env.CHECKSUM }}" GITHUB_REPOSITORY="${{ github.repository }}"
# Show the updated file
cat ./Package.swift

Expand Down Expand Up @@ -137,4 +107,4 @@ jobs:

See the README.md for detailed integration instructions.
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
186 changes: 54 additions & 132 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,39 @@ on:
workflow_dispatch:

env:
SCHEME: C2PAExample
SCHEME: Library

jobs:
lint:
name: Lint
runs-on: macos-15
steps:
- uses: actions/checkout@v4

- name: Set up Xcode
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: "16.4"

- name: Install SwiftLint
run: brew install swiftlint

- name: Run SwiftLint
run: make lint

test:
name: ${{ matrix.device }} Xcode ${{ matrix.xcode }}
runs-on: macos-14
runs-on: macos-15
strategy:
fail-fast: false
matrix:
xcode: ["16.1"]
xcode: ["16.4"]
device:
[
"iPhone 16 Pro",
"iPhone 16",
"iPhone SE (3rd generation)",
"iPad Pro 11-inch (M4)",
"iPhone 16"
]
ios: ["18.1"]
ios: ["18.5"]

steps:
- uses: actions/checkout@v4
Expand All @@ -37,178 +52,85 @@ jobs:
- name: Verify Xcode version
run: xcodebuild -version

- name: Build iOS Framework
run: make ios-framework

- name: Setup Signing Server
run: |
echo "Setting up C2PA signing server..."
make setup-server

- name: Build Signing Server
run: |
cd signing-server
swift build
- name: Build Library
run: make library DESTINATION="platform=iOS Simulator,name=${{ matrix.device }},OS=${{ matrix.ios }}"

- name: Start Signing Server
run: |
cd signing-server
DYLD_LIBRARY_PATH=libs:$DYLD_LIBRARY_PATH .build/debug/Run serve --env development --hostname 127.0.0.1 --port 8080 &
echo $! > ../server.pid
echo "Server started with PID $(cat ../server.pid)"
make signing-server-start
sleep 5

- name: Wait for Server to be Ready
run: |
echo "Waiting for signing server to be ready..."
max_attempts=30
attempt=0
while [ $attempt -lt $max_attempts ]; do
if curl -s http://127.0.0.1:8080/health > /dev/null 2>&1; then
echo "✓ Signing server is ready"
break
fi
echo "Waiting for server... (attempt $((attempt + 1))/$max_attempts)"
sleep 2
attempt=$((attempt + 1))
done

if [ $attempt -eq $max_attempts ]; then
echo "❌ Server failed to start after $max_attempts attempts"
exit 1
fi
run: make signing-server-wait

- name: Verify Server Endpoints
run: |
echo "Testing server endpoints..."
curl -v http://127.0.0.1:8080/health || echo "Health check failed"
echo ""
echo "Server is listening on:"
lsof -i :8080 || echo "No process on port 8080"

- name: Clean Build Directory
run: |
cd example
xcodebuild clean -project C2PAExample.xcodeproj -scheme "$SCHEME"

- name: Resolve Package Dependencies
run: |
cd example
xcodebuild -resolvePackageDependencies -project C2PAExample.xcodeproj -scheme "$SCHEME"
run: make signing-server-verify

- name: Build & Test
run: |
set -o pipefail
cd example
echo "CI environment variable: true"
echo "Testing with server at http://127.0.0.1:8080"
TEST_RUNNER_CI=true xcrun xcodebuild test \
-project C2PAExample.xcodeproj \
-scheme "$SCHEME" \
-sdk iphonesimulator \
-destination "platform=iOS Simulator,name=${{ matrix.device }},OS=${{ matrix.ios }}" \
-resultBundlePath TestResults \
-enableCodeCoverage YES \
| xcpretty --test --color
TEST_RUNNER_CI=true make test-library DESTINATION="platform=iOS Simulator,name=${{ matrix.device }},OS=${{ matrix.ios }}"

- name: Generate test summary
if: always()
run: |
cd example
if [ -d TestResults.xcresult ]; then
echo "=== Test Summary ==="
xcrun xcresulttool get test-results summary --path TestResults.xcresult || true
echo ""
echo "=== Test Results ==="
xcrun xcresulttool get test-results tests --path TestResults.xcresult || true
echo ""
echo "=== Exporting JSON ==="
# Use the legacy flag as required by newer versions
xcrun xcresulttool get --legacy --path TestResults.xcresult --format json > test-results.json 2>&1 || echo "Failed to export JSON"
if [ -s test-results.json ]; then
echo "Successfully exported test results to JSON ($(wc -c < test-results.json) bytes)"
else
echo "Warning: test-results.json is empty or not created"
fi
else
echo "TestResults.xcresult not found"
fi
run: make test-summary

- name: Upload test summary
if: always()
uses: actions/upload-artifact@v4
with:
name: TestSummary-${{ matrix.xcode }}-${{ matrix.device }}
path: |
example/test-results.json
example/TestResults.xcresult
TestResults.xcresult
if-no-files-found: warn

- name: Export coverage LCOV
if: success()
run: |
cd example

# Get DerivedData path from xcodebuild
DERIVED_DATA=$(xcodebuild -showBuildSettings -project C2PAExample.xcodeproj -scheme C2PAExample -sdk iphonesimulator | grep -m 1 " BUILD_DIR " | sed 's/.*= //' | sed 's|/Build/Products||')
echo "Derived data path: $DERIVED_DATA"

# Find Coverage.profdata - search in common locations
PROFDATA_PATH=$(find ~/Library/Developer/Xcode/DerivedData -path "*/Build/ProfileData/*/Coverage.profdata" -type f 2>/dev/null | grep -i c2paexample | head -1 || true)

echo "Coverage.profdata path: $PROFDATA_PATH"

# Find the test binary
TEST_BINARY_PATH=$(find ~/Library/Developer/Xcode/DerivedData -path "*/C2PAExampleTests.xctest/C2PAExampleTests" -type f 2>/dev/null | grep -i c2paexample | head -1 || true)

echo "Test binary path: $TEST_BINARY_PATH"

# Try to generate LCOV if we have both files
if [ -n "$PROFDATA_PATH" ] && [ -n "$TEST_BINARY_PATH" ]; then
# Export to LCOV format
# Use a sanitized filename to avoid shell issues with special characters
DEVICE_NAME="${{ matrix.device }}"
SANITIZED_DEVICE=$(echo "$DEVICE_NAME" | tr ' ()' '---')

xcrun llvm-cov export \
-format=lcov \
-instr-profile="$PROFDATA_PATH" \
"$TEST_BINARY_PATH" \
> "../coverage-${{ matrix.xcode }}-${SANITIZED_DEVICE}.lcov"

echo "LCOV coverage report generated successfully"
else
echo "ERROR: Could not generate LCOV report - missing profdata or binary"
echo "PROFDATA_PATH: $PROFDATA_PATH"
echo "TEST_BINARY_PATH: $TEST_BINARY_PATH"
exit 1
make coverage-lcov
# Also keep the JSON for better Codecov support
if [ -f "coverage.json" ]; then
echo "Coverage JSON found ($(wc -c < coverage.json) bytes)"
fi
if [ -f "coverage.lcov" ]; then
echo "Coverage LCOV found ($(wc -c < coverage.lcov) bytes)"
# Create a copy with device/xcode info
SANITIZED_DEVICE=$(echo "${{ matrix.device }}" | tr ' ()' '---')
cp coverage.lcov "coverage-${{ matrix.xcode }}-${SANITIZED_DEVICE}.lcov"
fi

- name: Upload coverage report to GitHub
if: success()
uses: actions/upload-artifact@v4
with:
name: coverage-${{ matrix.xcode }}-${{ matrix.device }}
path: coverage-*.lcov
path: |
coverage.lcov
coverage.json
coverage-*.lcov
if-no-files-found: warn

- name: Upload coverage report to Codecov
if: success()
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
slug: contentauth/c2pa-ios
files: ./coverage.lcov,./coverage.json
flags: unittests
name: c2pa-ios-${{ matrix.device }}
fail_ci_if_error: false
verbose: true

- name: Stop Signing Server
if: always()
run: |
if [ -f server.pid ]; then
SERVER_PID=$(cat server.pid)
echo "Stopping signing server (PID: $SERVER_PID)..."
kill $SERVER_PID || true
rm server.pid
fi
run: make signing-server-stop || true

- name: Upload Server Logs
if: failure()
uses: actions/upload-artifact@v4
with:
name: server-logs-${{ matrix.xcode }}-${{ matrix.device }}
path: signing-server/.build/debug/*.log
path: signing-server.log
Loading