Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 7 additions & 2 deletions .github/actions/notices_generation/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,16 @@ runs:
cd "${{ github.action_path }}"
bundle install
if ${{ inputs.search-local-pod-version == 'true' }} ; then
ruby app.rb --pods ${{ inputs.pods }} --sources ${{ inputs.sources }} --min_ios_version ${{ inputs.min-ios-version }} --search_local_pod_version --notices_path ${{ inputs.notices-path }}
ruby app.rb --pods ${INPUTS_PODS} --sources ${INPUTS_SOURCES} --min_ios_version ${INPUTS_MIN_IOS_VERSION} --search_local_pod_version --notices_path ${INPUTS_NOTICES_PATH}
else
ruby app.rb --pods ${{ inputs.pods }} --sources ${{ inputs.sources }} --min_ios_version ${{ inputs.min-ios-version }} --notices_path ${{ inputs.notices-path }}
ruby app.rb --pods ${INPUTS_PODS} --sources ${INPUTS_SOURCES} --min_ios_version ${INPUTS_MIN_IOS_VERSION} --notices_path ${INPUTS_NOTICES_PATH}
fi
shell: bash
env:
INPUTS_PODS: ${{ inputs.pods }}
INPUTS_SOURCES: ${{ inputs.sources }}
INPUTS_MIN_IOS_VERSION: ${{ inputs.min-ios-version }}
INPUTS_NOTICES_PATH: ${{ inputs.notices-path }}
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
Expand Down
8 changes: 6 additions & 2 deletions .github/workflows/api_diff_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,21 @@ jobs:
- name: Generate API files for PR branch
run: |
python ~/api_diff_report/api_info.py \
--file_list ${{ steps.get_changed_files.outputs.file_list }} \
--file_list ${STEPS_GET_CHANGED_FILES_OUTPUTS_FILE_LIST} \
--output_dir ${{ env.PR_API_OUTPUT }}
env:
STEPS_GET_CHANGED_FILES_OUTPUTS_FILE_LIST: ${{ steps.get_changed_files.outputs.file_list }}

- name: Checkout Base branch
run: git checkout HEAD^

- name: Generate API files for Base branch
run: |
python ~/api_diff_report/api_info.py \
--file_list ${{ steps.get_changed_files.outputs.file_list }} \
--file_list ${STEPS_GET_CHANGED_FILES_OUTPUTS_FILE_LIST} \
--output_dir ${{ env.BASE_API_OUTPUT }}
env:
STEPS_GET_CHANGED_FILES_OUTPUTS_FILE_LIST: ${{ steps.get_changed_files.outputs.file_list }}

- name: Generate API Diff Report
run: |
Expand Down
19 changes: 14 additions & 5 deletions .github/workflows/common_quickstart.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,18 @@ jobs:
- name: Xcode
run: sudo xcode-select -s /Applications/Xcode_16.4.app/Contents/Developer
- name: Run setup command.
run: ${{ inputs.setup_command }}
run: ${INPUTS_SETUP_COMMAND}
env:
INPUTS_SETUP_COMMAND: ${{ inputs.setup_command }}
- name: Install Secret GoogleService-Info.plist
run: |
scripts/decrypt_gha_secret.sh \
${{ inputs.plist_src_path }} \
${{ inputs.plist_dst_path }} \
${INPUTS_PLIST_SRC_PATH} \
${INPUTS_PLIST_DST_PATH} \
"$plist_secret"
env:
INPUTS_PLIST_SRC_PATH: ${{ inputs.plist_src_path }}
INPUTS_PLIST_DST_PATH: ${{ inputs.plist_dst_path }}
- name: Build ${{ inputs.product }} Quickstart (${{ inputs.quickstart_type }} / ${{ inputs.is_legacy && 'Legacy' || 'Non-Legacy' }})
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3
with:
Expand All @@ -102,11 +107,15 @@ jobs:
- id: lowercase_product
if: failure()
run: |
lowercase_product=$(echo "${{ inputs.product }}" | tr '[:upper:]' '[:lower:]')
lowercase_product=$(echo "${INPUTS_PRODUCT}" | tr '[:upper:]' '[:lower:]')
echo "lowercase_product=$lowercase_product" >> $GITHUB_OUTPUT
env:
INPUTS_PRODUCT: ${{ inputs.product }}
- name: Remove data before upload.
if: failure()
run: scripts/remove_data.sh ${{ steps.lowercase_product.outputs.lowercase_product }}
run: scripts/remove_data.sh ${STEPS_LOWERCASE_PRODUCT_OUTPUTS_LOWERCASE_PRODUCT}
env:
STEPS_LOWERCASE_PRODUCT_OUTPUTS_LOWERCASE_PRODUCT: ${{ steps.lowercase_product.outputs.lowercase_product }}
- uses: actions/upload-artifact@v4
if: failure()
with:
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/firebaseai.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,18 @@ jobs:
target: iOS
xcode: Xcode_26.0
runs-on: ${{ matrix.os }}
needs: spm
# needs: spm
env:
TEST_RUNNER_FIRAAppCheckDebugToken: ${{ secrets.VERTEXAI_INTEGRATION_FAC_DEBUG_TOKEN }}
TEST_RUNNER_VTXIntegrationImagen: ${{ github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' }}
FIREBASECI_USE_LATEST_GOOGLEAPPMEASUREMENT: 1
secrets_passphrase: ${{ secrets.GHASecretsGPGPassphrase1 }}
steps:
- uses: actions/checkout@v4
- uses: actions/cache/restore@v4
with:
path: .build
key: ${{ needs.spm.outputs.cache_key }}
# - uses: actions/cache/restore@v4
# with:
# path: .build
# key: ${{ needs.spm.outputs.cache_key }}
- name: Run integration tests
run: scripts/repo.sh tests run --secrets ./scripts/secrets/AI.json --platforms ${{ matrix.target }} --xcode ${{ matrix.xcode }} AI
- name: Upload xcodebuild logs
Expand Down
13 changes: 8 additions & 5 deletions .github/workflows/health-metrics-presubmit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ jobs:
env:
pr_branch: ${{ github.event.pull_request.head.ref }}
run: |
if [ ! -z "${{ env.METRICS_SERVICE_SECRET }}" ]; then
if [ ! -z "${METRICS_SERVICE_SECRET}" ]; then
./scripts/health_metrics/get_updated_files.sh
fi

Expand Down Expand Up @@ -312,7 +312,7 @@ jobs:

# Activate the service account for Metrics Service.
scripts/decrypt_gha_secret.sh scripts/gha-encrypted/metrics_service_access.json.gpg \
metrics-access.json "${{ env.METRICS_SERVICE_SECRET }}"
metrics-access.json "${METRICS_SERVICE_SECRET}"
gcloud auth activate-service-account --key-file metrics-access.json
- uses: actions/download-artifact@v4.1.7
id: download
Expand All @@ -322,9 +322,10 @@ jobs:
if: github.event.pull_request.merged != true && github.event.action != 'closed' && github.event.pull_request.head.repo.full_name == github.repository && github.event.pull_request.base.ref == 'main'
env:
base_commit: ${{ needs.check.outputs.target_branch_head }}
STEPS_DOWNLOAD_OUTPUTS_DOWNLOAD_PATH: ${{steps.download.outputs.download-path}}
run: |
# Get Head commit of the branch, instead of a merge commit created by actions/checkout.
if [ -d "${{steps.download.outputs.download-path}}" ]; then
if [ -d "${STEPS_DOWNLOAD_OUTPUTS_DOWNLOAD_PATH}" ]; then
cd scripts/health_metrics/generate_code_coverage_report
swift run CoverageReportGenerator --presubmit "firebase/firebase-ios-sdk" --head-commit "${GITHUB_SHA}" --token $(gcloud auth print-identity-token) --xcresult-dir "/Users/runner/test/codecoverage" --log-link "https://github.com/firebase/firebase-ios-sdk/actions/runs/${GITHUB_RUN_ID}" --pull-request-num ${{github.event.pull_request.number}} --base-commit "$base_commit"
fi
Expand Down Expand Up @@ -357,7 +358,9 @@ jobs:
- name: Update New Coverage Data
if: github.event.pull_request.merged && github.event.pull_request.head.repo.full_name == github.repository
run: |
if [ -d "${{steps.download.outputs.download-path}}" ]; then
if [ -d "${STEPS_DOWNLOAD_OUTPUTS_DOWNLOAD_PATH}" ]; then
cd scripts/health_metrics/generate_code_coverage_report
swift run CoverageReportGenerator --merge "firebase/firebase-ios-sdk" --head-commit "${GITHUB_SHA}" --token $(gcloud auth print-identity-token) --xcresult-dir "/Users/runner/test/codecoverage" --log-link "https://github.com/firebase/firebase-ios-sdk/actions/runs/${GITHUB_RUN_ID}" --source-branch "${{ github.base_ref }}"
swift run CoverageReportGenerator --merge "firebase/firebase-ios-sdk" --head-commit "${GITHUB_SHA}" --token $(gcloud auth print-identity-token) --xcresult-dir "/Users/runner/test/codecoverage" --log-link "https://github.com/firebase/firebase-ios-sdk/actions/runs/${GITHUB_RUN_ID}" --source-branch "${GITHUB_BASE_REF}"
fi
env:
STEPS_DOWNLOAD_OUTPUTS_DOWNLOAD_PATH: ${{steps.download.outputs.download-path}}
4 changes: 3 additions & 1 deletion .github/workflows/prerelease_cocoapods.yml
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ jobs:
git config --global user.name "google-oss-bot"
- name: Update SpecsTesting repo
run: |
[[ ${{ matrix.allowwarnings }} == true ]] && ALLOWWARNINGS=true
[[ ${MATRIX_ALLOWWARNINGS} == true ]] && ALLOWWARNINGS=true
cd scripts/create_spec_repo/
swift build
pod repo add --silent "${local_repo}" https://"$botaccess"@github.com/Firebase/SpecsTesting.git
Expand All @@ -166,6 +166,8 @@ jobs:
--pod-sources 'https://${BOT_TOKEN}@github.com/Firebase/SpecsTesting' "https://github.com/firebase/SpecsDev.git" "https://github.com/firebase/SpecsStaging.git" "https://github.com/CocoaPods/Specs.git" \
--include-pods "${targeted_pod}" \
--keep-repo ${ALLOWWARNINGS:+--allow-warnings}
env:
MATRIX_ALLOWWARNINGS: ${{ matrix.allowwarnings }}
- name: Clean Artifacts
if: ${{ always() }}
run: pod repo remove "${local_repo}"
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/release_cocoapods.yml
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ jobs:
git config --global user.name "google-oss-bot"
- name: Update SpecsReleasing repo
run: |
[[ ${{ matrix.allowwarnings }} == true ]] && ALLOWWARNINGS=true
[[ ${MATRIX_ALLOWWARNINGS} == true ]] && ALLOWWARNINGS=true
cd scripts/create_spec_repo/
swift build
pod repo add --silent "${local_repo}" https://"$botaccess"@github.com/Firebase/SpecsReleasing.git
Expand All @@ -149,6 +149,8 @@ jobs:
--pod-sources 'https://github.com/Firebase/SpecsReleasing' "https://github.com/firebase/SpecsStaging.git" "https://github.com/CocoaPods/Specs.git" \
--include-pods "${targeted_pod}" \
--keep-repo ${ALLOWWARNINGS:+--allow-warnings}
env:
MATRIX_ALLOWWARNINGS: ${{ matrix.allowwarnings }}
- name: Clean Artifacts
if: ${{ always() }}
run: pod repo remove "${local_repo}"
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/update-cpp-sdk-on-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,6 @@ jobs:
- name: Trigger firebase-cpp-sdk update
run: |
pip install -r scripts/gha/python_requirements.txt
python scripts/gha/trigger_workflow.py -t ${{ steps.generate-token.outputs.token }} -w update-dependencies.yml -p updateAndroid 0 -p updateiOS 1 -p comment "[Triggered]($GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID) by [firebase-ios-sdk $GITHUB_REF release]($GITHUB_SERVER_URL/$GITHUB_REPOSITORY/releases/tag/$GITHUB_REF)." -s 10 -A
python scripts/gha/trigger_workflow.py -t ${STEPS_GENERATE_TOKEN_OUTPUTS_TOKEN} -w update-dependencies.yml -p updateAndroid 0 -p updateiOS 1 -p comment "[Triggered]($GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID) by [firebase-ios-sdk $GITHUB_REF release]($GITHUB_SERVER_URL/$GITHUB_REPOSITORY/releases/tag/$GITHUB_REF)." -s 10 -A
env:
STEPS_GENERATE_TOKEN_OUTPUTS_TOKEN: ${{ steps.generate-token.outputs.token }}
12 changes: 8 additions & 4 deletions .github/workflows/zip.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,13 @@ jobs:
- name: Check if packaging should be skipped
id: check
run: |
if [[ -n "${{ env.PINNED_RUN_ID }}" || -n "${{ github.event.inputs.zip_run_id }}" ]]; then
if [[ -n "${{ env.PINNED_RUN_ID }}" || -n "${GITHUB_EVENT_INPUTS_ZIP_RUN_ID}" ]]; then
echo "should_package=false" >> $GITHUB_OUTPUT
else
echo "should_package=true" >> $GITHUB_OUTPUT
fi
env:
GITHUB_EVENT_INPUTS_ZIP_RUN_ID: ${{ github.event.inputs.zip_run_id }}

package-release:
needs: should_package
Expand Down Expand Up @@ -161,13 +163,15 @@ jobs:
- name: Get Run ID
id: get_run_id
run: |
if [[ -n "${{ github.event.inputs.zip_run_id }}" ]]; then
echo "run_id=${{ github.event.inputs.zip_run_id }}" >> $GITHUB_OUTPUT
if [[ -n "${GITHUB_EVENT_INPUTS_ZIP_RUN_ID}" ]]; then
echo "run_id=${GITHUB_EVENT_INPUTS_ZIP_RUN_ID}" >> $GITHUB_OUTPUT
elif [[ -n "${{ env.PINNED_RUN_ID }}" ]]; then
echo "run_id=${{ env.PINNED_RUN_ID }}" >> $GITHUB_OUTPUT
else
echo "run_id=${{ github.run_id }}" >> $GITHUB_OUTPUT
fi
env:
GITHUB_EVENT_INPUTS_ZIP_RUN_ID: ${{ github.event.inputs.zip_run_id }}

check_framework_firestore_symbols:
needs: packaging_done
Expand Down Expand Up @@ -739,4 +743,4 @@ jobs:
name: quickstart_artifacts_storage_${{ matrix.artifact }}
path: |
quickstart-ios/
!quickstart-ios/**/GoogleService-Info.plist
!quickstart-ios/**/GoogleService-Info.plist
3 changes: 1 addition & 2 deletions FirebaseAI/Tests/TestApp/Sources/Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,9 @@ public enum FirebaseAppNames {
public enum ModelNames {
public static let gemini2Flash = "gemini-2.0-flash-001"
public static let gemini2FlashLite = "gemini-2.0-flash-lite-001"
public static let gemini2FlashPreviewImageGeneration = "gemini-2.0-flash-preview-image-generation"
public static let gemini2FlashLive = "gemini-2.0-flash-live-001"
public static let gemini2FlashLivePreview = "gemini-2.0-flash-live-preview-04-09"
public static let gemini2_5_FlashImagePreview = "gemini-2.5-flash-image-preview"
public static let gemini2_5_FlashImage = "gemini-2.5-flash-image"
public static let gemini2_5_Flash = "gemini-2.5-flash"
public static let gemini2_5_FlashLite = "gemini-2.5-flash-lite"
public static let gemini2_5_FlashLivePreview = "gemini-live-2.5-flash-preview"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -322,18 +322,11 @@ struct GenerateContentIntegrationTests {
}

@Test(arguments: [
(InstanceConfig.vertexAI_v1beta, ModelNames.gemini2FlashPreviewImageGeneration),
(InstanceConfig.vertexAI_v1beta_global, ModelNames.gemini2FlashPreviewImageGeneration),
(InstanceConfig.vertexAI_v1beta_global, ModelNames.gemini2_5_FlashImagePreview),
(InstanceConfig.googleAI_v1beta, ModelNames.gemini2FlashPreviewImageGeneration),
(InstanceConfig.googleAI_v1beta, ModelNames.gemini2_5_FlashImagePreview),
(InstanceConfig.vertexAI_v1beta, ModelNames.gemini2_5_FlashImage),
(InstanceConfig.vertexAI_v1beta_global, ModelNames.gemini2_5_FlashImage),
(InstanceConfig.googleAI_v1beta, ModelNames.gemini2_5_FlashImage),
// Note: The following configs are commented out for easy one-off manual testing.
// (InstanceConfig.googleAI_v1beta_staging, ModelNames.gemini2FlashPreviewImageGeneration)
// (InstanceConfig.googleAI_v1beta_freeTier, ModelNames.gemini2FlashPreviewImageGeneration),
// (
// InstanceConfig.googleAI_v1beta_freeTier_bypassProxy,
// ModelNames.gemini2FlashPreviewImageGeneration
// ),
// (InstanceConfig.googleAI_v1beta_staging, ModelNames.gemini2_5_FlashImage)
])
func generateImage(_ config: InstanceConfig, modelName: String) async throws {
let generationConfig = GenerationConfig(
Expand All @@ -354,34 +347,21 @@ struct GenerateContentIntegrationTests {
)
let prompt = "Generate an image of a cute cartoon kitten playing with a ball of yarn."

var response: GenerateContentResponse?
try await withKnownIssue(
"Backend may fail with a 503 - Service Unavailable error when overloaded",
isIntermittent: true
) {
response = try await model.generateContent(prompt)
} matching: { issue in
(issue.error as? BackendError).map { $0.httpResponseCode == 503 } ?? false
}
let response = try await model.generateContent(prompt)

guard let response else { return }
let candidate = try #require(response.candidates.first)
let inlineDataPart = try #require(candidate.content.parts
.first { $0 is InlineDataPart } as? InlineDataPart)
let inlineDataPartsViaAccessor = response.inlineDataParts
#expect(inlineDataPartsViaAccessor.count == 1)
let inlineDataPartViaAccessor = try #require(inlineDataPartsViaAccessor.first)
#expect(inlineDataPart == inlineDataPartViaAccessor)
#expect(inlineDataPart.mimeType == "image/png")
#expect(inlineDataPart.mimeType.starts(with: "image/"))
#expect(inlineDataPart.data.count > 0)
#if canImport(UIKit)
let uiImage = try #require(UIImage(data: inlineDataPart.data))
// Gemini 2.0 Flash Experimental returns images sized to fit within a 1024x1024 pixel box but
// dimensions may vary depending on the aspect ratio.
#expect(uiImage.size.width <= 1024)
#expect(uiImage.size.width >= 500)
#expect(uiImage.size.height <= 1024)
#expect(uiImage.size.height >= 500)
#expect(uiImage.size.width > 0)
#expect(uiImage.size.height > 0)
#endif // canImport(UIKit)
}

Expand Down Expand Up @@ -552,18 +532,11 @@ struct GenerateContentIntegrationTests {
}

@Test(arguments: [
(InstanceConfig.vertexAI_v1beta, ModelNames.gemini2FlashPreviewImageGeneration),
(InstanceConfig.vertexAI_v1beta_global, ModelNames.gemini2FlashPreviewImageGeneration),
(InstanceConfig.vertexAI_v1beta_global, ModelNames.gemini2_5_FlashImagePreview),
(InstanceConfig.googleAI_v1beta, ModelNames.gemini2FlashPreviewImageGeneration),
(InstanceConfig.googleAI_v1beta, ModelNames.gemini2_5_FlashImagePreview),
(InstanceConfig.vertexAI_v1beta, ModelNames.gemini2_5_FlashImage),
(InstanceConfig.vertexAI_v1beta_global, ModelNames.gemini2_5_FlashImage),
(InstanceConfig.googleAI_v1beta, ModelNames.gemini2_5_FlashImage),
// Note: The following configs are commented out for easy one-off manual testing.
// (InstanceConfig.googleAI_v1beta_staging, ModelNames.gemini2FlashPreviewImageGeneration)
// (InstanceConfig.googleAI_v1beta_freeTier, ModelNames.gemini2FlashPreviewImageGeneration),
// (
// InstanceConfig.googleAI_v1beta_freeTier_bypassProxy,
// ModelNames.gemini2FlashPreviewImageGeneration
// ),
// (InstanceConfig.googleAI_v1beta_staging, ModelNames.gemini2_5_FlashImage)
])
func generateImageStreaming(_ config: InstanceConfig, modelName: String) async throws {
let generationConfig = GenerationConfig(
Expand All @@ -572,11 +545,6 @@ struct GenerateContentIntegrationTests {
topK: 1,
responseModalities: [.text, .image]
)
let safetySettings = safetySettings.filter {
// HARM_CATEGORY_CIVIC_INTEGRITY is deprecated in Vertex AI but only rejected when using the
// 'gemini-2.0-flash-preview-image-generation' model.
$0.harmCategory != .civicIntegrity
}
let model = FirebaseAI.componentInstance(config).generativeModel(
modelName: modelName,
generationConfig: generationConfig,
Expand Down Expand Up @@ -605,16 +573,12 @@ struct GenerateContentIntegrationTests {

#expect(inlineDataParts.count == 1)
let inlineDataPart = try #require(inlineDataParts.first)
#expect(inlineDataPart.mimeType == "image/png")
#expect(inlineDataPart.mimeType.starts(with: "image/"))
#expect(inlineDataPart.data.count > 0)
#if canImport(UIKit)
let uiImage = try #require(UIImage(data: inlineDataPart.data))
// Gemini 2.0 Flash Experimental returns images sized to fit within a 1024x1024 pixel box but
// dimensions may vary depending on the aspect ratio.
#expect(uiImage.size.width <= 1024)
#expect(uiImage.size.width >= 500)
#expect(uiImage.size.height <= 1024)
#expect(uiImage.size.height >= 500)
#expect(uiImage.size.width > 0)
#expect(uiImage.size.height > 0)
#endif // canImport(UIKit)
}

Expand Down
2 changes: 1 addition & 1 deletion scripts/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ function RunXcodebuild() {
local buildaction="${xcodebuild_args[$# - 1]}" # buildaction is the last arg
local log_filename="xcodebuild-${buildaction}.log"

local xcbeautify_cmd=(xcbeautify --renderer github-actions --disable-logging)
local xcbeautify_cmd=(xcbeautify --renderer github-actions --disable-logging --is-ci --preserve-unbeautified)

local result=0
NSUnbufferedIO=YES xcodebuild "$@" 2>&1 | tee "$log_filename" | \
Expand Down