Skip to content
Open
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
15 changes: 2 additions & 13 deletions .github/workflows/firebaseai.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,8 @@ jobs:
with:
path: .build
key: ${{ needs.spm.outputs.cache_key }}
- name: Install Secret GoogleService-Info.plist
run: scripts/decrypt_gha_secret.sh scripts/gha-encrypted/FirebaseAI/TestApp-GoogleService-Info.plist.gpg \
FirebaseAI/Tests/TestApp/Resources/GoogleService-Info.plist "$secrets_passphrase"
- name: Install Secret GoogleService-Info-Spark.plist
run: scripts/decrypt_gha_secret.sh scripts/gha-encrypted/FirebaseAI/TestApp-GoogleService-Info-Spark.plist.gpg \
FirebaseAI/Tests/TestApp/Resources/GoogleService-Info-Spark.plist "$secrets_passphrase"
- name: Install Secret Credentials.swift
run: scripts/decrypt_gha_secret.sh scripts/gha-encrypted/FirebaseAI/TestApp-Credentials.swift.gpg \
FirebaseAI/Tests/TestApp/Tests/Integration/Credentials.swift "$secrets_passphrase"
- name: Xcode
run: sudo xcode-select -s /Applications/${{ matrix.xcode }}.app/Contents/Developer
- name: Run IntegrationTests
run: scripts/build.sh FirebaseAIIntegration ${{ matrix.target }}
- name: Run integration tests
run: scripts/tests/ai/run.sh ${{ matrix.xcode }} ${{ matrix.target }}
- name: Upload xcodebuild logs
if: failure()
uses: actions/upload-artifact@v4
Expand Down
49 changes: 49 additions & 0 deletions scripts/tests/ai/decrypt_secrets.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/usr/bin/env bash

# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# USAGE: ./decrypt_secrets.sh
#
# Decrypts the secret files used for integration tests with the
# FirebaseAI sample app.
#
# Expects the environment variable "secrets_passphrase" to be set.
# This should be set to gpg password for encrypting/decrypting the files.

if [[ ! "${secrets_passphrase}" ]]; then
echo "Missing environment variable (secrets_passphrase) to decrypt the files with."
exit 1
fi

decrypt () {
local source=$1
local dest=$2

scripts/decrypt_gha_secret.sh "$1" "$2" "${secrets_passphrase}"
echo "${source} => ${dest}"
}

echo "Decrypting files"

decrypt scripts/gha-encrypted/FirebaseAI/TestApp-GoogleService-Info.plist.gpg \
FirebaseAI/Tests/TestApp/Resources/GoogleService-Info.plist

decrypt scripts/gha-encrypted/FirebaseAI/TestApp-GoogleService-Info-Spark.plist.gpg \
FirebaseAI/Tests/TestApp/Resources/GoogleService-Info-Spark.plist

decrypt scripts/gha-encrypted/FirebaseAI/TestApp-Credentials.swift.gpg \
FirebaseAI/Tests/TestApp/Tests/Integration/Credentials.swift

echo "Files decrypted"
133 changes: 133 additions & 0 deletions scripts/tests/ai/run.sh
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I would personally find the decrypt_secrets.sh script most useful locally since it automates most of the project setup. I'm not certain that I would personally use run.sh since I typically need to edit, run, edit, etc., in Xcode when working on the integration tests locally.

My only concern with checking in the script is that it could easily get out of date unless it's part of our CI job for running the integration tests.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I would personally find the decrypt_secrets.sh script most useful locally since it automates most of the project setup. I'm not certain that I would personally use run.sh since I typically need to edit, run, edit, etc., in Xcode when working on the integration tests locally.

I agree. run.sh is more-so useful if you just wanna test run integrations tests locally before waiting on CI to provision a mac (or creating a PR in general). If you're iterating on the integration tests themselves, then opening the project in XCode would be more straightforward.

My only concern with checking in the script is that it could easily get out of date unless it's part of our CI job for running the integration tests.

I've updated the PR to have the CI job use it as well, I just wasn't sure if that's what we wanted to do. But that sound s like a good idea to ensure it stays up-to-date.

Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
#!/usr/bin/env bash

# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# USAGE: ./run.sh [Xcode] [target]
#
# EXAMPLE: ./run.sh Xcode_16.4 iOS
#
# Runs the integration tests for the FirebaseAI sample app.
#
# ARGUMENTS:
# - [Xcode]: The version of Xcode to use. Defaults to searching for Xcode under `/Applications`.
# - [target]: The platform target to test for (eg; iOS or macOS). Defaults to "iOS".
#
# ENVIRONMENT VARIABLES:
# - <TEST_RUNNER_FIRAAppCheckDebugToken>: The app check debug token to use. This is required.
# - <secrets_passphrase>: The gpg secret that the secret files were encrypted with.
# This is semi-required. If this is not present, then the decrypted secret files
# must already be present (ie; you manually added them).
#
# ADDITIONAL NOTES:
# If you provide a value for "secrets_passphrase", then the secret files will be decrypted
# on the fly, and will be deleted after the tests run. Even if the tests fail, the
# secret files will be deleted before the error propogates up. If you do NOT pass
# a value for "secrets_passphrase", and instead manually added the decrypted secret
# files, then the decrypted files will NOT be deleted after the script runs.
#
# If you don't specify an Xcode version, the script will attempt to search for an install
# under `/Applications`. If no installs or found, an error will be thrown. If multiple
# installs are found, they will be listed, and the script will prompt you to rerun it,
# while manually specifying the Xcode version to use.

# TODO: (b/450976183) Implement a generic alternative for all SDKs

shopt -s nullglob
set -eo pipefail

xcode=$1

# Look for Xcode installations if a version wasn't provided explicitly
if [[ ! "${xcode}" ]]; then
apps=(/Applications/Xcode*.app)
names=()
for p in "${apps[@]}"; do
names+=("$(basename "${p%.app}")")
done

case ${#names[@]} in
0)
echo "No Xcode installs found in /Applications" >&2
exit 1
;;
1)
xcode="${names[0]}"
echo "Using Xcode version: ${xcode}"
;;
*)
echo "Multiple Xcode installs found:"
printf ' %s\n' "${names[@]}"
echo "Manually specify an Xcode version instead"
echo "USAGE: $0 [Xcode] [target]"
exit 1
;;
esac
fi

target="iOS"
if [[ $# -gt 1 ]]; then
target="$2"
fi

if [[ ! "${TEST_RUNNER_FIRAAppCheckDebugToken}" ]]; then
echo "Missing required environment variable for app check debug token (TEST_RUNNER_FIRAAppCheckDebugToken)"
exit 1
fi

# Files used in integration tests. These are usually encrypted under /scripts/gha-encrypted/FirebaseAI
secret_files=(
"FirebaseAI/Tests/TestApp/Resources/GoogleService-Info.plist"
"FirebaseAI/Tests/TestApp/Resources/GoogleService-Info-Spark.plist"
"FirebaseAI/Tests/TestApp/Tests/Integration/Credentials.swift"
)

# Checks if any of the secret files are absent, throwing an error if so.
check_for_secret_files () {
for file in "${secret_files[@]}"; do
if [[ ! -f "${file}" ]]; then
echo "Missing required decrypted secret file: ${file}"
exit 1
fi
done
}

cleanup () {
# We only delete the decrypted secret files if we were the ones to decrypt them.
if [[ "${delete_secrets}" ]]; then
echo "Removing secret files"
for file in "${secret_files[@]}"; do
rm -f "${file}"
done
echo "Secret files removed"
fi
}

# always run cleanup last, even on errors
trap 'exit_code=$?; cleanup; exit "$exit_code"' ERR
trap 'cleanup' EXIT

if [[ ! "${secrets_passphrase}" ]]; then
echo "Environment variable 'secrets_passphrase' wasn't set. Checking if files are already present"
check_for_secret_files
echo "Files are present, moving forward"
delete_secrets=true
else
scripts/tests/ai/decrypt_secrets.sh
fi

echo "Selecting Xcode version: ${xcode}"
sudo xcode-select -s /Applications/"${xcode}".app/Contents/Developer
echo "Running integration tests for target: ${target}"
scripts/build.sh FirebaseAIIntegration "${target}"
Loading