Skip to content

Sync End-to-End tests #285

Sync End-to-End tests

Sync End-to-End tests #285

name: Sync End-to-End tests
on:
workflow_dispatch:
schedule:
- cron: '0 5 * * *' # run at 5 AM UTC
jobs:
create-notarized-app:
name: Build Notarized Review app
uses: ./.github/workflows/build_notarized.yml
with:
release-type: review
create-dmg: false
branch: ${{ github.sha }}
secrets:
APPLE_API_KEY_BASE64: ${{ secrets.APPLE_API_KEY_BASE64 }}
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
APPLE_API_KEY_ISSUER: ${{ secrets.APPLE_API_KEY_ISSUER }}
ASANA_ACCESS_TOKEN: ${{ secrets.ASANA_ACCESS_TOKEN }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_ACCESS_KEY_ID_RELEASE_S3: ${{ secrets.AWS_ACCESS_KEY_ID_RELEASE_S3 }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_SECRET_ACCESS_KEY_RELEASE_S3: ${{ secrets.AWS_SECRET_ACCESS_KEY_RELEASE_S3 }}
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
MM_HANDLES_BASE64: ${{ secrets.MM_HANDLES_BASE64 }}
MM_WEBHOOK_URL: ${{ secrets.MM_WEBHOOK_URL }}
SSH_PRIVATE_KEY_FASTLANE_MATCH: ${{ secrets.SSH_PRIVATE_KEY_FASTLANE_MATCH }}
sync-end-to-end-tests:
name: Sync End-to-End Tests
needs: create-notarized-app
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
runner: [macos-13-xlarge, macos-14-xlarge]
include:
- xcode-version: "15.2"
runner: macos-13-xlarge
- xcode-version: "15.4"
runner: macos-14-xlarge
timeout-minutes: 60
steps:
- name: Register SSH key for certificates repository access
uses: webfactory/[email protected]
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY_FASTLANE_MATCH }}
- name: Check out the code
uses: actions/checkout@v4
with:
submodules: recursive
- name: Set up fastlane
run: bundle install
- name: Sync code signing assets
env:
APPLE_API_KEY_BASE64: ${{ secrets.APPLE_API_KEY_BASE64 }}
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
APPLE_API_KEY_ISSUER: ${{ secrets.APPLE_API_KEY_ISSUER }}
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
SSH_PRIVATE_KEY_FASTLANE_MATCH: ${{ secrets.SSH_PRIVATE_KEY_FASTLANE_MATCH }}
run: |
bundle exec fastlane sync_signing_ci
- name: Download and unzip artifact
uses: actions/download-artifact@v4
- name: Set cache key hash
run: |
has_only_tags=$(jq '[ .pins[].state | has("version") ] | all' DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved)
if [[ "$has_only_tags" == "true" ]]; then
echo "cache_key_hash=${{ hashFiles('DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved') }}" >> $GITHUB_ENV
else
echo "Package.resolved contains dependencies specified by branch or commit, skipping cache."
fi
- name: Cache SPM
if: env.cache_key_hash
uses: actions/cache@v4
with:
path: DerivedData/SourcePackages
key: ${{ runner.os }}-spm-${{ env.cache_key_hash }}
restore-keys: |
${{ runner.os }}-spm-
- name: Select Xcode
run: |
# Override .xcode_version because 15.4 is not available on macos 13
echo "${{ matrix.xcode-version }}" > .xcode-version
sudo xcode-select -s /Applications/Xcode_$(<.xcode-version).app/Contents/Developer
- name: Create test account for Sync and return the recovery code
uses: duckduckgo/sync_crypto/action@main
id: sync-recovery-code
with:
debug: true
- name: Build Sync e2e tests
run: |
set -o pipefail && xcodebuild build-for-testing \
-scheme "Sync End-to-End UI Tests CI" \
-derivedDataPath DerivedData \
-skipPackagePluginValidation \
-skipMacroValidation \
| tee xcodebuild.log \
| xcbeautify
- name: Unzip and Copy app to /DerivedData
run: |
cd DuckDuckGo-review-*.app && unzip DuckDuckGo-*.zip
mv -f "DuckDuckGo Review.app" "../DerivedData/Build/Products/Review/DuckDuckGo Review.app"
- name: Run UI Tests
env:
CODE: ${{ steps.sync-recovery-code.outputs.recovery-code }}
run: |
# Set CODE environment variable in the scheme definition, since Xcode 15.4 doesn't
# seem to recognize global environment variables otherwise.
# We use xmlstarlet to edit the scheme XML file.
brew install xmlstarlet
xmlstarlet ed -i '/Scheme/LaunchAction/EnvironmentVariables/EnvironmentVariable[1]' -t elem -n "EnvironmentVariable" \
-i '/Scheme/LaunchAction/EnvironmentVariables/EnvironmentVariable[1]' -t attr -n "key" -v "CODE" \
-i '/Scheme/LaunchAction/EnvironmentVariables/EnvironmentVariable[1]' -t attr -n "value" -v "$CODE" \
-i '/Scheme/LaunchAction/EnvironmentVariables/EnvironmentVariable[1]' -t attr -n "isEnabled" -v "YES" \
"DuckDuckGo.xcodeproj/xcshareddata/xcschemes/Sync End-to-End UI Tests CI.xcscheme" > updated.xcscheme
mv -f updated.xcscheme "DuckDuckGo.xcodeproj/xcshareddata/xcschemes/Sync End-to-End UI Tests CI.xcscheme"
defaults write com.duckduckgo.macos.browser.review sync.environment Development
defaults write com.duckduckgo.macos.browser.review moveToApplicationsFolderAlertSuppress 1
set -o pipefail && xcodebuild test-without-building \
-scheme "Sync End-to-End UI Tests CI" \
-derivedDataPath DerivedData \
-skipPackagePluginValidation \
-skipMacroValidation \
-test-iterations 2 \
-retry-tests-on-failure \
| tee -a xcodebuild.log \
| tee ui-tests.log
- name: Prepare test report
if: always()
run: |
xcbeautify --report junit --report-path . --junit-report-filename ui-tests.xml < ui-tests.log
- name: Publish tests report
uses: mikepenz/action-junit-report@v4
if: always() # always run even if the previous step fails
with:
check_name: "Test Report ${{ matrix.runner }}"
report_paths: ui-tests.xml
- name: Upload logs when workflow failed
uses: actions/upload-artifact@v4
if: failure() || cancelled()
with:
name: "BuildLogs ${{ matrix.runner }}"
path: |
xcodebuild.log
DerivedData/Logs/Test/*.xcresult
~/Library/Logs/DiagnosticReports/*
retention-days: 7
notify-failure:
name: Notify on failure
if: ${{ always() && github.event_name == 'schedule' && (needs.sync-end-to-end-tests.result == 'failure' || needs.sync-end-to-end-tests.result == 'cancelled') }}
needs: [sync-end-to-end-tests]
runs-on: ubuntu-latest
steps:
- name: Create Asana task when workflow failed
uses: duckduckgo/[email protected]
with:
action: create-asana-task
asana-pat: ${{ secrets.ASANA_ACCESS_TOKEN }}
asana-project: ${{ vars.MACOS_APP_DEVELOPMENT_ASANA_PROJECT_ID }}
asana-task-name: GH Workflow Failure - Sync End-to-End Tests
asana-task-description: The Sync end-to-end workflow has failed. See https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}