diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..e4bad9c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,188 @@ +name: CI/CD Pipeline + +on: + push: + branches: [main] + tags: ['v*'] + pull_request: + branches: [main] + +env: + CARGO_TERM_COLOR: always + +jobs: + # ═══════════════════════════════════════════════════════════════ + # 1. Lint + # ═══════════════════════════════════════════════════════════════ + + lint: + name: Lint + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt, clippy + + - name: Cache cargo + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: ${{ runner.os }}-cargo-lint-${{ hashFiles('**/Cargo.lock') }} + + - name: Format check + run: cargo fmt --all -- --check + + - name: Clippy + run: cargo clippy --all-targets -- -D warnings + + # ═══════════════════════════════════════════════════════════════ + # 2. Test + # ═══════════════════════════════════════════════════════════════ + + test: + name: Test + runs-on: ubuntu-latest + timeout-minutes: 15 + needs: lint + steps: + - uses: actions/checkout@v4 + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + + - name: Cache cargo + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: ${{ runner.os }}-cargo-test-${{ hashFiles('**/Cargo.lock') }} + + - name: Test (all crates) + run: cargo test --workspace + + - name: Test doc + run: cargo test --doc --workspace + + # ═══════════════════════════════════════════════════════════════ + # 3. Build + # ═══════════════════════════════════════════════════════════════ + + build: + name: Build + runs-on: ubuntu-latest + timeout-minutes: 15 + needs: test + steps: + - uses: actions/checkout@v4 + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + + - name: Cache cargo + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: ${{ runner.os }}-cargo-build-${{ hashFiles('**/Cargo.lock') }} + + - name: Build release (all crates) + run: cargo build --release --workspace + + - name: Verify FFI lib + run: | + test -f target/release/libzx_document_ffi.a && echo "FFI lib OK" + test -f target/release/libzx_document_core.a && echo "Core lib OK" + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: linux-libs + path: target/release/libzx_document_*.a + retention-days: 7 + + # ═══════════════════════════════════════════════════════════════ + # 4. Release (tagged versions only) + # ═══════════════════════════════════════════════════════════════ + + release: + name: Release + runs-on: ${{ matrix.os }} + timeout-minutes: 30 + needs: build + if: startsWith(github.ref, 'refs/tags/v') + strategy: + fail-fast: false + matrix: + include: + - os: macos-15 + target: aarch64-apple-ios + rust-target: aarch64-apple-ios + - os: macos-15 + target: aarch64-apple-ios-sim + rust-target: aarch64-apple-ios-sim + + steps: + - uses: actions/checkout@v4 + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + with: + targets: ${{ matrix.rust-target }} + + - name: Build FFI for ${{ matrix.target }} + run: cargo build --release -p zx_document_ffi --target ${{ matrix.rust-target }} + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: lib-${{ matrix.target }} + path: target/${{ matrix.rust-target }}/release/libzx_document_ffi.a + + # ═══════════════════════════════════════════════════════════════ + # 5. Package xcframework (tagged macOS only) + # ═══════════════════════════════════════════════════════════════ + + package-xcframework: + name: Package xcframework + runs-on: macos-15 + timeout-minutes: 10 + needs: release + if: startsWith(github.ref, 'refs/tags/v') + steps: + - uses: actions/checkout@v4 + + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + + - name: Create xcframework + run: | + mkdir -p xcframework_staging + cp artifacts/lib-aarch64-apple-ios/libzx_document_ffi.a xcframework_staging/libzx_document_ffi_ios.a + cp artifacts/lib-aarch64-apple-ios-sim/libzx_document_ffi.a xcframework_staging/libzx_document_ffi_ios_sim.a + + xcodebuild -create-xcframework \ + -library xcframework_staging/libzx_document_ffi_ios.a \ + -library xcframework_staging/libzx_document_ffi_ios_sim.a \ + -output ZxDocumentRuntime.xcframework + + # Package + zip -r ZxDocumentRuntime.xcframework.zip ZxDocumentRuntime.xcframework/ + + - name: Upload release asset + uses: softprops/action-gh-release@v2 + with: + files: ZxDocumentRuntime.xcframework.zip + generate_release_notes: true