Skip to content

Better git hub runners#1409

Open
AustinBenoit wants to merge 4 commits intomainfrom
Better-git-hub-runners
Open

Better git hub runners#1409
AustinBenoit wants to merge 4 commits intomainfrom
Better-git-hub-runners

Conversation

@AustinBenoit
Copy link
Contributor

Description

Provide details of the change, and generalize the change in the PR title above.


Testing

Describe how you've tested these changes.


Type of Change

Place an x the applicable box:

  • Bug fix. Add the issue # below if applicable.
  • New feature. A non-breaking change which adds functionality.
  • Other, such as a build process or documentation change.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the GitHub Actions workflow by introducing more granular control over test execution and improving failure analysis. It allows for more precise selection of test applications, dynamic generation of test matrices based on APIs, and focused parsing of test results. Furthermore, it integrates automated reporting of failed jobs to an external analysis tool and refines the job retry mechanism, contributing to a more robust and efficient CI/CD pipeline.

Highlights

  • Enhanced Test App Filtering: The desktop_tester.py and test_simulator.py scripts now support more flexible filtering of test applications using an api_filter derived from the testapp_name, allowing for API-specific test execution.
  • Dynamic Test Matrix Generation: The print_matrix_configuration.py script was updated to allow an optional apis argument, enabling the generation of test matrices with API-specific entries for more targeted testing configurations.
  • FTL Test Result Filtering: The read_ftl_test_result.py script gained a new testapp_name flag, allowing it to filter and parse FTL test results only for applications whose paths contain the specified name.
  • Automated Failure Reporting to Jules: A new script, report_to_jules.py, was introduced to automatically report failed GitHub Actions jobs to the Jules API, including log filtering capabilities, to assist with root cause analysis.
  • Improved Job Retry Logic: The retry_test_failures.py script was refined to better identify and retry failed build and test jobs, and now outputs a max_retries_exhausted flag if a job fails after exceeding its retry limit.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • scripts/gha/desktop_tester.py
    • Updated test app discovery logic to use a target_file_name and an api_filter derived from testapp_name.
    • Modified logging to include the api_filter during the search.
  • scripts/gha/print_matrix_configuration.py
    • Modified get_testapp_test_matrix function signature to accept an optional apis parameter.
    • Added an api field to the generated matrix entries when apis are provided.
    • Updated the main function to parse and pass the new apis argument.
    • Added a new command-line argument -apis for specifying APIs.
  • scripts/gha/read_ftl_test_result.py
    • Added a testapp_name flag to filter FTL test results based on the test app's path.
    • Implemented logic to skip parsing results for apps that do not match the testapp_name filter.
  • scripts/gha/report_to_jules.py
    • Added a new script to report failed GitHub Actions jobs to the Jules API.
    • Implemented functions to filter log content by step pattern.
    • Included logic for creating Jules sessions and sending log messages.
    • Defined command-line flags for GitHub token, Jules token, run ID, and filtering options.
  • scripts/gha/retry_test_failures.py
    • Imported the os module.
    • Updated job name matching for build and test jobs to use in instead of startswith.
    • Added logic to check if MAX_RETRIES have been exhausted for failed jobs and set a max_retries_exhausted output.
  • scripts/gha/test_simulator.py
    • Added a testapp_name flag to filter test applications for simulator tests.
    • Modified the test app discovery loop to apply the api_filter (derived from testapp_name) to .app and .apk files.
Ignored Files
  • Ignored by pattern: .github/workflows/** (3)
    • .github/workflows/build_and_test_platform.yml
    • .github/workflows/integration_tests.yml
    • .github/workflows/retry-test-failures.yml
Activity
  • The pull request was created by AustinBenoit with a title indicating improvements to GitHub runners.
  • The description contains placeholder sections for 'Description' and 'Testing', suggesting that detailed information about the changes and testing efforts has not yet been provided by the author.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Comment on lines +31 to +166
name: build-${{ inputs.platform }}-${{ inputs.unity_version }}
runs-on: ${{ inputs.build_os }}
env:
xcodeVersion: "16.2"
steps:
- uses: lukka/get-cmake@latest
with:
cmakeVersion: "~3.31.0"
- id: matrix_info
shell: bash
run: |
echo "info=${MATRIX_UNITY_VERSION}-${MATRIX_OS}-${MATRIX_PLATFORM}-${MATRIX_IOS_SDK}" >> $GITHUB_OUTPUT
echo "artifact_suffix=${MATRIX_UNITY_VERSION}-${MATRIX_OS}-${MATRIX_IOS_SDK}" >> $GITHUB_OUTPUT
env:
MATRIX_UNITY_VERSION: ${{ inputs.unity_version }}
MATRIX_OS: ${{ inputs.build_os }}
MATRIX_PLATFORM: ${{ inputs.platform }}
# Pass NA for ios_sdk during the single build step, or dynamic if needed later
MATRIX_IOS_SDK: "NA"
- uses: actions/checkout@v4
- name: Setup python
uses: actions/setup-python@v5
with:
python-version: '3.9'
- name: Install python deps
timeout-minutes: 10
shell: bash
run: pip install -r scripts/gha/requirements.txt
- name: setup Xcode version
if: runner.os == 'macOS'
run: sudo xcode-select -s /Applications/Xcode_${{ env.xcodeVersion }}.app/Contents/Developer
- id: unity_setup
uses: ./gha/unity
timeout-minutes: 30
with:
version: ${{ inputs.unity_version }}
platforms: ${{ inputs.platform }}
username: ${{ secrets.UNITY_USERNAME }}
password: ${{ secrets.UNITY_PASSWORD }}
serial_ids: ${{ secrets.SERIAL_ID }}
- name: Workaround tvOS XCode 15 issue
if: ${{ contains(inputs.platform, 'tvOS') && contains(inputs.unity_version, '2020') }}
shell: bash
run: |
find /Applications/Unity/Hub/Editor -type f -name 'UnityViewControllerBase.h' -exec sed -i '' 's/#import <GameController\/GCController.h>/#import <GameController\/GCEventViewController.h>/g' {} \;
- name: Prepare for integration tests
timeout-minutes: 10
shell: bash
run: |
python scripts/gha/restore_secrets.py --passphrase "${{ secrets.TEST_SECRET }}"
- name: Setup Android keystore
if: ${{ contains(inputs.platform, 'Android') }}
shell: bash
run: |
mkdir -p ~/.android
gpg --quiet --batch --yes --decrypt --passphrase="${{ secrets.TEST_SECRET }}" \
--output ~/.android/debug.keystore "scripts/gha-encrypted/debug_keystore.gpg"
- name: Fetch prebuilt packaged SDK from previous run
if: ${{ inputs.packaged_sdk_run_id != '' }}
uses: actions/download-artifact@v4
with:
name: 'firebase_unity_sdk.zip'
github-token: ${{ github.token }}
run-id: ${{ inputs.packaged_sdk_run_id }}

- name: Build integration tests
timeout-minutes: 240
shell: bash
run: |
if [[ -n "${PACKAGED_SDK_RUN_ID}" ]]; then
unzip -q firebase_unity_sdk.zip -d ~/Downloads/
else
curl -L "https://firebase.google.com/download/unity" -o ~/Downloads/firebase_unity_sdk.zip
unzip -q ~/Downloads/firebase_unity_sdk.zip -d ~/Downloads/
fi
CLEAN_APIS=$(echo ${APIS} | tr -d "'" | tr -d "\"")
python scripts/gha/build_testapps.py \
--t ${CLEAN_APIS} \
--u ${UNITY_VERSION} \
--p "${PLATFORM}" \
--ios_sdk "NA" \
--plugin_dir ~/Downloads/firebase_unity_sdk \
--output_directory "${{ github.workspace }}" \
--artifact_name "${STEPS_MATRIX_INFO_OUTPUTS_INFO}" \
--notimestamp \
--force_latest_runtime \
--ci
env:
PACKAGED_SDK_RUN_ID: ${{ inputs.packaged_sdk_run_id }}
APIS: ${{ inputs.apis }}
PLATFORM: ${{ inputs.platform }}
UNITY_VERSION: ${{ inputs.unity_version }}
STEPS_MATRIX_INFO_OUTPUTS_INFO: ${{ steps.matrix_info.outputs.info }}

- name: Return Unity license
if: always()
uses: ./gha/unity
with:
version: ${{ inputs.unity_version }}
release_license: "true"

- name: Prepare results summary artifact
if: ${{ !cancelled() }}
shell: bash
run: |
if [ ! -f build-results-${STEPS_MATRIX_INFO_OUTPUTS_INFO}.log.json ]; then
echo "__SUMMARY_MISSING__" > build-results-${STEPS_MATRIX_INFO_OUTPUTS_INFO}.log.json
fi
env:
STEPS_MATRIX_INFO_OUTPUTS_INFO: ${{ steps.matrix_info.outputs.info }}

- name: Upload build results artifact
uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: build_and_test_results-build-${{ steps.matrix_info.outputs.info }}
path: build-results-${{ steps.matrix_info.outputs.info }}*
retention-days: 2

- name: Upload Mobile integration tests artifact
uses: actions/upload-artifact@v4
if: ${{ contains('Android,iOS,tvOS', inputs.platform) && !cancelled() }}
with:
name: testapps-${{ inputs.platform }}-${{ steps.matrix_info.outputs.artifact_suffix }}
path: testapps-${{ steps.matrix_info.outputs.info }}
retention-days: 2

- name: Upload Desktop integration tests artifact
uses: actions/upload-artifact@v4
if: ${{ !contains('Android,iOS,tvOS', inputs.platform) && !cancelled() }}
with:
name: testapps-${{ inputs.platform }}-${{ steps.matrix_info.outputs.artifact_suffix }}
path: testapps-${{ steps.matrix_info.outputs.info }}/${{ inputs.platform }}
retention-days: 2

prepare_tests:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
Comment on lines +167 to +184
needs: build_testapp
runs-on: ubuntu-latest
outputs:
test_matrix: ${{ steps.set-matrix.outputs.test_matrix }}
steps:
- uses: actions/checkout@v4
- name: Generate Test Matrix
id: set-matrix
run: |
matrix=$(python scripts/gha/print_matrix_configuration.py -test_matrix \
-platforms ${{ inputs.platform }} \
-os ${{ inputs.build_os }} \
-unity_versions ${{ inputs.unity_version }} \
-mobile_test_on ${{ inputs.mobile_device_types }} \
-apis "${{ inputs.apis }}")
echo "test_matrix=$matrix" >> $GITHUB_OUTPUT

integration_test:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
Comment on lines +185 to +346
needs: [build_testapp, prepare_tests]
name: test-${{ matrix.platform }}-${{ matrix.test_device }}-${{ matrix.api }}
runs-on: ${{ matrix.test_os }}
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.prepare_tests.outputs.test_matrix) }}
env:
xcodeVersion: "16.2"
steps:
- id: matrix_info
shell: bash
run: |
echo "info=${MATRIX_UNITY_VERSION}-${MATRIX_BUILD_OS}-${MATRIX_PLATFORM}-${MATRIX_TEST_DEVICE}-${MATRIX_TEST_OS}-${MATRIX_API}" >> $GITHUB_OUTPUT
echo "artifact_path=testapps-${MATRIX_PLATFORM}-${MATRIX_UNITY_VERSION}-${MATRIX_BUILD_OS}-NA" >> $GITHUB_OUTPUT
env:
MATRIX_UNITY_VERSION: ${{ matrix.unity_version }}
MATRIX_BUILD_OS: ${{ matrix.build_os }}
MATRIX_PLATFORM: ${{ matrix.platform }}
MATRIX_TEST_DEVICE: ${{ matrix.test_device }}
MATRIX_TEST_OS: ${{ matrix.test_os }}
MATRIX_API: ${{ matrix.api }}
- uses: actions/checkout@v4
- name: Setup python
uses: actions/setup-python@v5
with:
python-version: '3.9'
- name: Install python deps
timeout-minutes: 10
shell: bash
run: pip install -r scripts/gha/requirements.txt
- name: setup Xcode version
if: runner.os == 'macOS'
run: sudo xcode-select -s /Applications/Xcode_${{ env.xcodeVersion }}.app/Contents/Developer
- name: Download Testapp artifacts
uses: actions/download-artifact@v4
with:
path: testapps
name: ${{ steps.matrix_info.outputs.artifact_path }}
- name: Set up Node (22)
if: ${{ matrix.test_device == 'github_runner' }}
uses: actions/setup-node@v5
with:
node-version: 22
- name: Setup java for Firestore emulator
if: ${{ matrix.test_device == 'github_runner' }}
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '21'
- name: Setup Firestore Emulator
if: ${{ matrix.test_device == 'github_runner' }}
uses: nick-invision/retry@v2
with:
shell: bash
timeout_minutes: 5
max_attempts: 3
command: npm install -g firebase-tools

- name: Run Desktop integration tests
if: ${{ matrix.test_device == 'github_runner' }}
timeout-minutes: 30
shell: bash
run: |
firebase emulators:start --only firestore &
python scripts/gha/desktop_tester.py --testapp_dir testapps \
--testapp_name ${{ matrix.api }} \
--logfile_name "${STEPS_MATRIX_INFO_OUTPUTS_INFO}"
env:
STEPS_MATRIX_INFO_OUTPUTS_INFO: ${{ steps.matrix_info.outputs.info }}

- name: Run Mobile integration tests on real device via FTL
id: ftl_test
if: ${{ matrix.device_type == 'real' }}
uses: FirebaseExtended/github-actions/firebase-test-lab@v1.4
with:
credentials_json: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_CREDENTIALS }}
testapp_dir: testapps
test_type: "game-loop"
timeout: 1200
test_devices: ${{ matrix.device_detail }}
test_device_selection: random
max_attempts: 3
validator: ${GITHUB_WORKSPACE}/scripts/gha/read_ftl_test_result.py

- name: Read FTL Test Result
if: ${{ matrix.device_type == 'real' && !cancelled() }}
timeout-minutes: 60
shell: bash
run: |
python scripts/gha/read_ftl_test_result.py --test_result "${STEPS_FTL_TEST_OUTPUTS_TEST_SUMMARY}" \
--testapp_name ${{ matrix.api }} \
--output_path testapps/test-results-"${STEPS_MATRIX_INFO_OUTPUTS_INFO}".log
env:
STEPS_FTL_TEST_OUTPUTS_TEST_SUMMARY: ${{ steps.ftl_test.outputs.test_summary }}
STEPS_MATRIX_INFO_OUTPUTS_INFO: ${{ steps.matrix_info.outputs.info }}

- name: Print available devices
if: ${{ matrix.device_type == 'virtual' && !cancelled() }}
run: |
xcrun xctrace list devices
- name: Create keychain (macOS Simulator)
if: ${{ contains('iOS,tvOS', matrix.platform) && matrix.device_type == 'virtual'}}
shell: bash
run: |
echo "Creating temporary keychain"
security delete-keychain tmp-keychain 2> /dev/null || true
security -i <<EOF
create-keychain -p ${{ secrets.TEST_SECRET }} tmp-keychain
set-keychain-settings tmp-keychain
unlock-keychain -p ${{ secrets.TEST_SECRET }} tmp-keychain
EOF
security list-keychains -d user -s tmp-keychain
security default-keychain -s tmp-keychain

- name: Run Mobile integration tests on virtual device locally
timeout-minutes: 120
if: ${{ matrix.device_type == 'virtual' && !cancelled() }}
run: |
python scripts/gha/test_simulator.py --testapp_dir testapps \
--tvos_device "${{ matrix.test_device }}" \
--ios_device "${{ matrix.test_device }}" \
--android_device "${{ matrix.test_device }}" \
--testapp_name ${{ matrix.api }} \
--logfile_name "${{ steps.matrix_info.outputs.info }}" \
--ci

- name: Delete keychain (macOS Simulator)
if: ${{ always() && contains('iOS,tvOS', matrix.platform) && matrix.device_type == 'virtual' }}
shell: bash
run: |
security list-keychains -d user -s login.keychain
security delete-keychain tmp-keychain || true

- name: Prepare results summary artifact
if: ${{ !cancelled() }}
shell: bash
run: |
if [ -d "testapps/testapps-${STEPS_MATRIX_INFO_OUTPUTS_INFO}" && ! -f testapps/test-results-${STEPS_MATRIX_INFO_OUTPUTS_INFO}.log.json ]; then
mkdir -p testapps && echo "__SUMMARY_MISSING__" > testapps/test-results-${STEPS_MATRIX_INFO_OUTPUTS_INFO}.log.json
fi
env:
STEPS_MATRIX_INFO_OUTPUTS_INFO: ${{ steps.matrix_info.outputs.info }}

- name: Upload test results artifact
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: build_and_test_results-test-${{ steps.matrix_info.outputs.info }}
path: testapps/test-results-${{ steps.matrix_info.outputs.info }}*
retention-days: 2

- name: Summarize test results
if: ${{ !cancelled() }}
shell: bash
run: |
cat testapps/test-results-${STEPS_MATRIX_INFO_OUTPUTS_INFO}.log
if [[ "${JOB_STATUS}" != "success" ]]; then
exit 1
fi
env:
STEPS_MATRIX_INFO_OUTPUTS_INFO: ${{ steps.matrix_info.outputs.info }}
JOB_STATUS: ${{ job.status }}

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

The pull request introduces a new API filtering mechanism across several testing scripts (desktop_tester.py, print_matrix_configuration.py, test_simulator.py, read_ftl_test_result.py), enhancing the ability to target specific test applications. It also adds a new utility script, report_to_jules.py, for automated root cause analysis of failed GitHub Actions jobs, and improves retry_test_failures.py with more flexible job name matching and retry reporting. However, the new report_to_jules.py script contains potential security vulnerabilities related to Regular Expression Denial of Service (ReDoS) and Prompt Injection, which should be addressed to ensure the reliability and integrity of the automated reporting system.

match = group_start_re.match(line)
if match:
step_name = match.group(1).strip()
if re.search(pattern, step_name):
Copy link
Contributor

Choose a reason for hiding this comment

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

security-medium medium

The script uses user-provided regex patterns (include_step_pattern and include_job_pattern) in re.search against untrusted input (step names and job names). A malicious regex can cause catastrophic backtracking, leading to a Regular Expression Denial of Service (ReDoS) of the CI job. Consider sanitizing the user-provided regex patterns or using a regex engine that is not vulnerable to backtracking, such as google/re2.


message = f"Logs for Test: {job['name']}\n{'-'*40}\n{truncated_log}\n"

send_message(FLAGS.jules_token, session_id, message)
Copy link
Contributor

Choose a reason for hiding this comment

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

security-medium medium

Untrusted log content is directly concatenated into the prompt sent to the Jules LLM. An attacker who can control the logs (e.g., by causing a test failure with a specific error message) can inject instructions to manipulate the LLM's behavior and output, potentially leading to misleading root cause analysis reports. This is a classic Prompt Injection vulnerability. To mitigate this, use clear delimiters (e.g., XML-like tags) to separate the untrusted log content from the system instructions and explicitly instruct the LLM to ignore any instructions contained within the log content.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant