diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..8bc6e6d --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,56 @@ +name: Tests + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + unit-tests: + name: Unit Tests + runs-on: macos-15 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Swift version + run: swift --version + + - name: Build + run: swift build + + - name: Run unit tests + run: swift test --filter FirebaseAppTests --filter AppCheckTests + + integration-tests: + name: Integration Tests + runs-on: macos-15 + # Only run integration tests on push to main or when PR is from the same repository + # This prevents exposing secrets to forked PRs + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Swift version + run: swift --version + + - name: Build + run: swift build + + - name: Enable integration tests + run: | + # Remove .disabled() from integration test suites + find Tests -name "*.swift" -type f -exec sed -i '' 's/@Suite(\(.*\), \.disabled(\(.*\)))/@Suite(\1)/g' {} + + + - name: Run integration tests with Firebase credentials + env: + FIREBASE_PROJECT_ID: ${{ secrets.FIREBASE_PROJECT_ID }} + FIREBASE_PRIVATE_KEY_ID: ${{ secrets.FIREBASE_PRIVATE_KEY_ID }} + FIREBASE_PRIVATE_KEY: ${{ secrets.FIREBASE_PRIVATE_KEY }} + FIREBASE_CLIENT_EMAIL: ${{ secrets.FIREBASE_CLIENT_EMAIL }} + FIREBASE_CLIENT_ID: ${{ secrets.FIREBASE_CLIENT_ID }} + run: swift test --filter FirestoreTests diff --git a/README.md b/README.md index 84c7332..5655498 100644 --- a/README.md +++ b/README.md @@ -340,6 +340,52 @@ FIREBASE_CLIENT_EMAIL=firebase-adminsdk@my-project.iam.gserviceaccount.com FIREBASE_CLIENT_ID=123456789012345678901 ``` +### CI/CD Setup + +This project includes GitHub Actions workflows for automated testing. + +#### Setting up GitHub Secrets + +To enable integration tests in CI, add the following secrets to your GitHub repository: + +1. Go to **Settings** → **Secrets and variables** → **Actions** +2. Add the following repository secrets: + - `FIREBASE_PROJECT_ID` + - `FIREBASE_PRIVATE_KEY_ID` + - `FIREBASE_PRIVATE_KEY` + - `FIREBASE_CLIENT_EMAIL` + - `FIREBASE_CLIENT_ID` + +#### Security Considerations + +- **Test-only Firebase project**: Use a separate Firebase project for CI/CD testing, not your production project +- **Minimum permissions**: Create a service account with only the permissions needed for tests +- **Fork protection**: Integration tests only run on pushes to main or PRs from the same repository (not from forks) + +#### Workflow Overview + +The CI pipeline runs two jobs: + +1. **Unit Tests**: Run on every push and PR (no secrets required) + - Tests ServiceAccount initialization and configuration + - Tests AppCheck functionality + +2. **Integration Tests**: Run only when secrets are available + - Automatically enables disabled integration test suites + - Tests Firestore operations with real Firebase credentials + - Only runs on main branch or same-repository PRs + +```bash +# Manually run tests locally with environment variables +export FIREBASE_PROJECT_ID="test-project" +export FIREBASE_PRIVATE_KEY_ID="key-id" +export FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n" +export FIREBASE_CLIENT_EMAIL="test@test.iam.gserviceaccount.com" +export FIREBASE_CLIENT_ID="123456789" + +swift test +``` + ## Architecture - **FirebaseApp** - Core initialization and service account management