Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
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
8 changes: 8 additions & 0 deletions .github/file-filters.yml
Original file line number Diff line number Diff line change
Expand Up @@ -543,3 +543,11 @@ run_size_analysis_for_prs: &run_size_analysis_for_prs
# Build configuration
- "Makefile"
- "Brewfile*"

run_swift_log_for_prs: &run_swift_log_for_prs
- "3rd-party-integrations/SwiftLog/**"

# GH Actions
- ".github/workflows/integrations-common.yml"
- ".github/workflows/integrations-swift-log.yml"
- ".github/file-filters.yml"
138 changes: 138 additions & 0 deletions .github/workflows/integrations-swift-log.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
name: Test Integrations
on:
push:
branches:
- main
- release/**

pull_request:
types: [opened, synchronize, reopened, labeled]

# Concurrency configuration:
# - We use workflow-specific concurrency groups to allow independent test runs across different workflows
# while preventing multiple runs of the same test suite on the same branch/commit.
# - For pull requests, we cancel in-progress runs when new commits are pushed to save CI resources
# and provide faster feedback on the latest changes.
# - For main branch pushes and scheduled runs, we never cancel in-progress runs to ensure the complete
# test suite always finishes, maintaining the integrity of our main branch quality gates.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
ready-to-merge-gate:
name: Ready-to-merge gate
uses: ./.github/workflows/ready-to-merge-workflow.yml

# This job detects if the PR contains changes that require running unit tests.
# If yes, the job will output a flag that will be used by the next job to run the unit tests.
# If no, the job will output a flag that will be used by the next job to skip running the unit tests.
# At the end of this workflow, we run a check that validates that either all unit tests passed or were
# called unit-tests-required-check.
files-changed:
name: Detect File Changes
runs-on: ubuntu-latest
needs: ready-to-merge-gate
# Map a step output to a job output
outputs:
run_swift_log_for_prs: ${{ steps.changes.outputs.run_swift_log_for_prs }}
steps:
- uses: actions/checkout@v6
- name: Get changed files
id: changes
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
with:
token: ${{ github.token }}
filters: .github/file-filters.yml

# TODO: All tests here are validating against the released SPM package, so we need to build the XCFramework first.
spm-integrations-tests:
name: "SPM Tests for Swift Log"
needs: files-changed
if: github.event_name != 'pull_request' || needs.files-changed.outputs.run_swift_log_for_prs == 'true'
runs-on: macos-15
timeout-minutes: 30
steps:
- uses: actions/checkout@v6
- name: Select Xcode version
env:
XCODE_VERSION: 16.4
run: ./scripts/ci-select-xcode.sh "$XCODE_VERSION"
- name: Prepare Package.swift
working-directory: 3rd-party-integrations/SwiftLog
shell: bash
run: |
../../scripts/prepare-package.sh \
--package-file Package.swift \
--update-path-to-sentry-cocoa true
- name: Run SPM Tests
working-directory: 3rd-party-integrations/SwiftLog
run: swift test

test-integration:
name: Unit Tests for Swift Log
if: github.event_name != 'pull_request' || needs.files-changed.outputs.run_swift_log_for_prs == 'true'
needs: files-changed
uses: ./.github/workflows/unit-test-common.yml
with:
name: SwiftLog
scheme: SentrySwiftLog
working_directory: 3rd-party-integrations/SwiftLog
path_to_scripts_folder: ../../scripts
xcode: ${{ matrix.xcode }}
test-destination-os: ${{ matrix.test-destination-os }}
device: ${{ matrix.device }}
platform: ${{ matrix.platform }}
runs-on: ${{ matrix.macos_version }}
timeout: 10
Copy link

Choose a reason for hiding this comment

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

Bug: Missing secrets inheritance for codecov token access

The test-integration job is missing secrets: inherit when calling the unit-test-common.yml reusable workflow. Other callers like test.yml and fast-pr-checks.yml include this directive. Without it, unit-test-common.yml cannot access secrets.CODECOV_TOKEN, causing the codecov upload steps to fail or behave unexpectedly.

Fix in Cursor Fix in Web

update_path_to_sentry_cocoa: true
test_spm_package: true
strategy:
fail-fast: false
matrix:
include:
- name: iOS 18
xcode: "16.4"
macos_version: macos-15
test-destination-os: "18.4"
platform: "iOS"
device: "iPhone 16 Pro"

- name: iOS 26
macos_version: macos-26
xcode: "26.1.1"
test-destination-os: "26.1"
platform: "iOS"
device: "iPhone 17 Pro"

- name: macOS 15
macos_version: macos-15
xcode: "16.4"
test-destination-os: "latest"
platform: "macOS"

- name: macOS 26
macos_version: macos-26
xcode: "26.1.1"
test-destination-os: "26.1"
platform: "macOS"

unit-tests-required-check:
needs:
[
ready-to-merge-gate,
files-changed,
spm-integrations-tests,
test-integration,
]
name: Swift Log Tests - Required Check
# This is necessary since a failed/skipped dependent job would cause this job to be skipped
if: always()
runs-on: ubuntu-latest
steps:
# If any jobs we depend on fails gets cancelled or times out, this job will fail.
# Skipped jobs are not considered failures.
- name: Check for failures
if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
run: |
echo "One of the unit test jobs has failed." && exit 1
31 changes: 0 additions & 31 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -369,37 +369,6 @@ jobs:
device: "Apple TV"
scheme: "Sentry"

swiftlog-integration-unit-tests:
name: Integrations/Logs/SentrySwiftLog Unit Tests
if: needs.files-changed.outputs.run_unit_tests_for_prs == 'true'
needs: files-changed
runs-on: macos-15
steps:
- uses: actions/checkout@v6

- name: Select Xcode
run: ./scripts/ci-select-xcode.sh 16.4

- name: Setup local sentry-cocoa dependency
working-directory: 3rd-party-integrations/SwiftLog
run: swift package edit sentry-cocoa --path ../..

- name: Run SwiftLog tests
working-directory: 3rd-party-integrations/SwiftLog
run: swift test

- name: Archiving Raw Logs
uses: actions/upload-artifact@v5
if: ${{ failure() || cancelled() }}
with:
name: raw-output-swiftlog-integration
path: |
3rd-party-integrations/SwiftLog/.build/**/*.log

- name: Run CI Diagnostics
if: failure()
run: ./scripts/ci-diagnostics.sh

# This check validates that either all unit tests passed or were skipped, which allows us
# to make unit tests a required check with only running the unit tests when required.
# So, we don't have to run unit tests, for example, for Changelog or ReadMe changes.
Expand Down
62 changes: 51 additions & 11 deletions .github/workflows/unit-test-common.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,29 @@ on:
default: false
type: boolean

working_directory:
Copy link

Choose a reason for hiding this comment

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

Bug: Missing default for working_directory in unit-test-common.yml breaks existing callers and causes workflow failures.
Severity: CRITICAL | Confidence: High

🔍 Detailed Analysis

The unit-test-common.yml workflow's working_directory input is required: false but lacks a default: value. Existing callers, such as test.yml, do not provide this parameter. When working_directory is an empty string, critical steps like ls -la ${{ inputs.working_directory }} will fail with ls: cannot access '': No such file or directory. Additionally, the report_paths for JUnit reports will incorrectly resolve to /build/reports/junit.xml, causing the report action to fail.

💡 Suggested Fix

Add a default: value to the working_directory input in unit-test-common.yml or update all existing callers (e.g., test.yml) to provide this parameter.

🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: .github/workflows/unit-test-common.yml#L72

Potential issue: The `unit-test-common.yml` workflow's `working_directory` input is
`required: false` but lacks a `default:` value. Existing callers, such as `test.yml`, do
not provide this parameter. When `working_directory` is an empty string, critical steps
like `ls -la ${{ inputs.working_directory }}` will fail with `ls: cannot access '': No
such file or directory`. Additionally, the `report_paths` for JUnit reports will
incorrectly resolve to `/build/reports/junit.xml`, causing the report action to fail.

Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 5615901

description: "The working directory to run the tests in"
required: false
type: string

path_to_scripts_folder:
description: "The path to the scripts folder"
default: ./scripts
required: false
type: string

update_path_to_sentry_cocoa:
description: "The path to the scripts folder"
default: false
required: false
type: boolean

test_spm_package:
description: "Whether to test the SPM package"
default: false
required: false
type: boolean

jobs:
unit-tests:
name: Unit ${{inputs.name}}
Expand All @@ -77,7 +100,9 @@ jobs:
if: ${{!inputs.should_skip}}
steps:
- uses: actions/checkout@v6
- run: ./scripts/ci-select-xcode.sh "$XCODE_VERSION"
- name: Select Xcode version
working-directory: ${{ inputs.working_directory }}
run: ${{ inputs.path_to_scripts_folder }}/ci-select-xcode.sh "$XCODE_VERSION"
env:
XCODE_VERSION: ${{inputs.xcode}}

Expand All @@ -86,42 +111,55 @@ jobs:

# Install platform runtimes that are not included by default
- name: Install required platforms
working-directory: ${{ inputs.working_directory }}
if: ${{ inputs.install_platforms }}
env:
PLATFORMS: ${{ inputs.platform }}
OS_VERSION: ${{ inputs.test-destination-os }}
run: ./scripts/ci-install-platforms.sh --platforms "$PLATFORMS" --os-version "$OS_VERSION"
run: ${{ inputs.path_to_scripts_folder }}/ci-install-platforms.sh --platforms "$PLATFORMS" --os-version "$OS_VERSION"

- name: Ensure required runtime is loaded
# Ideally we will not need this, but CI sometimes is failing to load some runtimes, this will ensure they are loaded
if: ${{ inputs.platform == 'iOS' }}
timeout-minutes: 5 # 5 minutes timeout
working-directory: ${{ inputs.working_directory }}
env:
OS_VERSION: ${{ inputs.test-destination-os }}
run: ./scripts/ci-ensure-runtime-loaded.sh --os-version "$OS_VERSION"
run: ${{ inputs.path_to_scripts_folder }}/ci-ensure-runtime-loaded.sh --os-version "$OS_VERSION"

# Create simulator devices for non-preinstalled simulators
# Required for iOS 16.4, iOS 17.5 (on Xcode 15.4), and iOS/tvOS 26.1
- name: Create simulator device
if: ${{ inputs.create_device }}
working-directory: ${{ inputs.working_directory }}
env:
PLATFORM: ${{ inputs.platform }}
OS_VERSION: ${{ inputs.test-destination-os }}
DEVICE_NAME: ${{inputs.device}}
run: ./scripts/ci-create-simulator.sh --platform "$PLATFORM" --os-version "$OS_VERSION" --device-name "$DEVICE_NAME"
run: ${{ inputs.path_to_scripts_folder }}/ci-create-simulator.sh --platform "$PLATFORM" --os-version "$OS_VERSION" --device-name "$DEVICE_NAME"

# Boot created simulators to ensure they're ready before tests run
# Based on CircleCI forum comment, booting is especially important for Xcode 26: https://discuss.circleci.com/t/xcode-26-rc/54066/18
- name: Boot simulator
if: ${{ inputs.create_device && inputs.platform == 'iOS' }}
working-directory: ${{ inputs.working_directory }}
env:
XCODE_VERSION: ${{ inputs.xcode }}
DEVICE_NAME: ${{ inputs.device }}
OS_VERSION: ${{ inputs.test-destination-os }}
run: ./scripts/ci-boot-simulator.sh --xcode "$XCODE_VERSION" --device "$DEVICE_NAME" --os-version "$OS_VERSION"
run: ${{ inputs.path_to_scripts_folder }}/ci-boot-simulator.sh --xcode "$XCODE_VERSION" --device "$DEVICE_NAME" --os-version "$OS_VERSION"

- name: Prepare Package.swift
working-directory: ${{ inputs.working_directory }}
shell: bash
run: |
${{ inputs.path_to_scripts_folder }}/prepare-package.sh \
--package-file Package.swift \
--update-path-to-sentry-cocoa true

# We split building and running tests in two steps so we know how long running the tests takes.
- name: Build Tests
working-directory: ${{ inputs.working_directory }}
id: build_tests
env:
PLATFORM: ${{ inputs.platform }}
Expand All @@ -130,14 +168,14 @@ jobs:
DEVICE_NAME: ${{ inputs.device }}
SCHEME: ${{ inputs.scheme }}
run: |
./scripts/sentry-xcodebuild.sh \
${{ inputs.path_to_scripts_folder }}/sentry-xcodebuild.sh \
--platform "$PLATFORM" \
--os "$OS_VERSION" \
--ref "$REF_NAME" \
--command build-for-testing \
--device "$DEVICE_NAME" \
--configuration TestCI \
--scheme "$SCHEME"
--scheme "$SCHEME" ${{ inputs.test_spm_package && '--spm-project' || '' }}

# Run Flaky Tests TestPlan which has a retry mechanism on failure.
# We intentionally run these before the other test plan to fail early.
Expand All @@ -146,14 +184,15 @@ jobs:
- name: Run Flaky Tests
# Only the Sentry Scheme has the Flaky TestPlan.
if: ${{ inputs.scheme == 'Sentry' }}
working-directory: ${{ inputs.working_directory }}
env:
PLATFORM: ${{ inputs.platform }}
OS_VERSION: ${{ inputs.test-destination-os }}
REF_NAME: ${{ github.ref_name }}
DEVICE_NAME: ${{ inputs.device }}
SCHEME: ${{ inputs.scheme }}
run: |
./scripts/sentry-xcodebuild.sh \
${{ inputs.path_to_scripts_folder }}/sentry-xcodebuild.sh \
--platform "$PLATFORM" \
--os "$OS_VERSION" \
--ref "$REF_NAME" \
Expand All @@ -169,28 +208,29 @@ jobs:
# passed to xcodebuild doesn't end up in the job name,
# because GitHub Actions don't provide an easy way of
# manipulating string in expressions.
working-directory: ${{ inputs.working_directory }}
env:
PLATFORM: ${{ inputs.platform }}
OS_VERSION: ${{ inputs.test-destination-os }}
REF_NAME: ${{ github.ref_name }}
DEVICE_NAME: ${{ inputs.device }}
SCHEME: ${{ inputs.scheme }}
run: |
./scripts/sentry-xcodebuild.sh \
${{ inputs.path_to_scripts_folder }}/sentry-xcodebuild.sh \
--platform "$PLATFORM" \
--os "$OS_VERSION" \
--ref "$REF_NAME" \
--command test-without-building \
--device "$DEVICE_NAME" \
--configuration TestCI \
--scheme "$SCHEME" \
--scheme "$SCHEME" ${{ inputs.test_spm_package && '--spm-project' || '' }} \
--result-bundle results.xcresult

- name: Publish Test Report
uses: mikepenz/action-junit-report@e08919a3b1fb83a78393dfb775a9c37f17d8eea6 # v6.0.1
if: always()
with:
report_paths: "build/reports/junit.xml"
report_paths: "${{ inputs.working_directory }}/build/reports/junit.xml"
Copy link

Choose a reason for hiding this comment

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

Bug: Empty working_directory creates invalid absolute path prefix

The report_paths value "${{ inputs.working_directory }}/build/reports/junit.xml" will produce /build/reports/junit.xml when working_directory is not provided (defaults to empty string). This changes a relative path to an absolute path starting with /, breaking existing callers of unit-test-common.yml that don't specify working_directory (like fast-pr-checks.yml and test.yml). The previous value was simply "build/reports/junit.xml" without the prefix.

Fix in Cursor Fix in Web

fail_on_failure: true
fail_on_parse_error: true
detailed_summary: true
Expand Down
12 changes: 12 additions & 0 deletions scripts/prepare-package.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ Options:
--change-path true|false Whether to swap SPM binary URLs for local paths (default: false)
--remove-binary-targets true|false
Whether to keep only SentryDistribution product/target (default: false)
--update-path-to-sentry-cocoa true|false
Whether to update the path to the sentry-cocoa directory (default: false)
-h, --help Show this help message
USAGE
}
Expand All @@ -30,6 +32,7 @@ IS_PR="false"
REMOVE_DUPLICATE="false"
CHANGE_PATH="false"
REMOVE_BINARY_TARGETS="false"
UPDATE_PATH_TO_SENTRY_COCOA="false"

while [[ $# -gt 0 ]]; do
case "$1" in
Expand Down Expand Up @@ -58,6 +61,11 @@ while [[ $# -gt 0 ]]; do
REMOVE_BINARY_TARGETS="$2"
shift 2
;;
--update-path-to-sentry-cocoa)
[[ $# -lt 2 ]] && { echo "Missing value for $1" >&2; exit 1; }
UPDATE_PATH_TO_SENTRY_COCOA="$2"
shift 2
;;
-h|--help)
usage
exit 0
Expand Down Expand Up @@ -131,6 +139,10 @@ var targets: [Target] = [\
sed -i '' '/^let env = getenv("EXPERIMENTAL_SPM_BUILDS")/,/^}/d' "$PACKAGE_FILE"
fi

if is_enabled "$UPDATE_PATH_TO_SENTRY_COCOA"; then
sed -i '' 's|\.package(url: "https://github\.com/getsentry/sentry-cocoa", from: "[^"]*")|.package(path: "'../../'")|g' "$PACKAGE_FILE"
fi

echo
echo "===== $PACKAGE_FILE (after prepare-package.sh) ====="
cat "$PACKAGE_FILE"
Expand Down
Loading
Loading