From 8806f86f365b346e6429ff16c3dc2569c0a5d087 Mon Sep 17 00:00:00 2001 From: Brandon Page Date: Thu, 31 Oct 2024 13:00:25 -0700 Subject: [PATCH 01/10] Add Github Actions --- .github/workflows/nightly.yaml | 17 +++++++++ .github/workflows/pr.yaml | 16 +++++++++ .github/workflows/reusable-workflow.yaml | 44 ++++++++++++++++++++++++ .gitignore | 1 - 4 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/nightly.yaml create mode 100644 .github/workflows/pr.yaml create mode 100644 .github/workflows/reusable-workflow.yaml diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml new file mode 100644 index 0000000000..ba843d9f99 --- /dev/null +++ b/.github/workflows/nightly.yaml @@ -0,0 +1,17 @@ +name: Nightly Tests + +on: + schedule: + - cron: "0 5 * * 3,5" # cron is UTC, this translates to 10 PM PST Tues and Thur. + +jobs: + ios-pr: + strategy: + fail-fast: false + matrix: + lib: [SalesforceSDKCommon, SalesforceAnalytics, SalesforceSDKCore, SmartStore, MobileSync] + ios: [^18, ^17] + uses: ./.github/workflows/reusable-workflow.yaml + with: + lib: ${{ matrix.lib }} + ios: ${{ matirx.ios }} \ No newline at end of file diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml new file mode 100644 index 0000000000..38de0d4772 --- /dev/null +++ b/.github/workflows/pr.yaml @@ -0,0 +1,16 @@ +name: Pull Request + +on: + pull_request: + branches: + - dev + +jobs: + ios-pr: + strategy: + fail-fast: false + matrix: + lib: [SalesforceSDKCommon, SalesforceAnalytics, SalesforceSDKCore, SmartStore, MobileSync] + uses: ./.github/workflows/reusable-workflow.yaml + with: + lib: ${{ matrix.lib }} \ No newline at end of file diff --git a/.github/workflows/reusable-workflow.yaml b/.github/workflows/reusable-workflow.yaml new file mode 100644 index 0000000000..e84dfd9db9 --- /dev/null +++ b/.github/workflows/reusable-workflow.yaml @@ -0,0 +1,44 @@ +on: + workflow_call: + inputs: + lib: + required: true + type: string + ios: + default: '^18' + required: false + type: string + xcode: + default: '^16' + required: false + type: string + +jobs: + test-ios: + runs-on: macos-latest + steps: + - uses: actions/checkout@v4.1.0 + - name: Install Dependencies + run: | + npm install shelljs@0.8.5 + ./install.sh + ./build/pre-build + - name: Static Analysis and Danger + if: ${{ github.event_name == 'pull_request' }} + run: | + xcodebuild analyze -workspace SalesforceMobileSDK.xcworkspace -scheme ${{ inputs.lib }} -sdk 'iphonesimulator' \ + CLANG_ANALYZER_OUTPUT=plist-html CLANG_ANALYZER_OUTPUT_DIR=./clangReport RUN_CLANG_STATIC_ANALYZER=YES + - uses: mxcl/xcodebuild@v3 + with: + xcode: ${{ inputs.xcode }} + platform: iOS + platform-version: ${{ inputs.ios }} + workspace: SalesSalesforceMobileSDK.xcworkspace + scheme: ${{ inputs.lib }} + code-coverage: ${{ github.event_name == 'pull_request' }} + upload-logs: always + - uses: kishikawakatsumi/xcresulttool@v1 + with: + path: test.xcresult + if: success() || failure() + \ No newline at end of file diff --git a/.gitignore b/.gitignore index d84a467e08..9223f072bf 100644 --- a/.gitignore +++ b/.gitignore @@ -18,7 +18,6 @@ shared/test/test_credentials.json /libs/MobileSync/build/ /native/SampleApps/RestAPIExplorer/build/ node_modules/ -.github/ .idea/ package-lock.json npm-debug.log From c9ace331a84a2cfc76f26c32cc9eccab5aa42cc9 Mon Sep 17 00:00:00 2001 From: Brandon Page Date: Fri, 1 Nov 2024 19:37:31 -0700 Subject: [PATCH 02/10] Add dynamic testing matrix for PRs, static analysis and test summary reporting. --- .github/DangerStaticAnalysis.rb | 57 ++++++++++++++++ .github/DangerTestResults.rb | 2 + .github/Gemfile | 5 ++ .github/Gemfile.lock | 82 ++++++++++++++++++++++++ .github/workflows/nightly.yaml | 2 +- .github/workflows/pr.yaml | 28 +++++++- .github/workflows/reusable-workflow.yaml | 26 ++++---- 7 files changed, 187 insertions(+), 15 deletions(-) create mode 100644 .github/DangerStaticAnalysis.rb create mode 100644 .github/DangerTestResults.rb create mode 100644 .github/Gemfile create mode 100644 .github/Gemfile.lock diff --git a/.github/DangerStaticAnalysis.rb b/.github/DangerStaticAnalysis.rb new file mode 100644 index 0000000000..26783204fd --- /dev/null +++ b/.github/DangerStaticAnalysis.rb @@ -0,0 +1,57 @@ +require 'plist' + +# Determine which libs were midified by this PR +modifed_libs = Set[] +for file in (git.modified_files + git.added_files); + # Add the library name for each modified file + modifed_libs.add(file.split("libs/").last.split("/").first) +end + +# If we are modifiing any CI files run all tests. +if modifed_libs.inclues?(".github") + modifed_libs = ['SalesforceSDKCommon', 'SalesforceAnalytics', 'SalesforceSDKCore', 'SmartStore', 'MobileSync'] +end + +# Set Github Job output so we know which tests to run +json_libs = modifed_libs.map { |l| "'#{l}'"}.join(", ") +`echo "libs=[#{json_libs}]" >> $GITHUB_OUTPUT` + +# Markdown table character length without any issues +MAKRDOWN_LENGTH = 138 + +# Get all static analysis report files +files = Set[] +for lib in modifed_libs; + files.merge(Dir["../libs/SalesforceAnalytics/clangReport/StaticAnalyzer/#{lib}/#{lib}/normal/**/*.plist"]) +end + +modified_file_names = git.modified_files.map { |file| File.basename(file, File.extname(file)) } +added_file_names = git.added_files.map { |file| File.basename(file, File.extname(file)) } + +# Github PR comment header +message = "### Clang Static Analysis Issues\n\n" +message << "File | Type | Category | Description | Line | Col |\n" +message << " --- | ---- | -------- | ----------- | ---- | --- |\n" + +# Parse Clang Plist files and report issues associated with files modified or added in this PR. +for file in files; + report = Plist.parse_xml(file) + report_file_name = File.basename(file, File.extname(file)) + print "file name: #{report_file_name}\n" + + if modified_file_names.include?(report_file_name) || added_file_names.include?(report_file_name) + print "file match! #{file}" + issues = report['diagnostics'] + for i in 0..issues.count-1 + unless issues[i].nil? + message << "#{file_path.split('/').last} | #{issues[i]['type']} | #{issues[i]['category']} | #{issues[i]['description']} | #{issues[i]['location']['line']} | #{issues[i]['location']['col']}\n" + end + end + end +end + +# Only print Static Analysis table if there are issues +if message.length > MAKRDOWN_LENGTH + warn('Static Analysis found an issue with one or more files you modified. Please fix the issue(s).') + markdown message +end \ No newline at end of file diff --git a/.github/DangerTestResults.rb b/.github/DangerTestResults.rb new file mode 100644 index 0000000000..6e5ecfcc4a --- /dev/null +++ b/.github/DangerTestResults.rb @@ -0,0 +1,2 @@ +xcode_summary.inline_mode = true +xcode_summary.report '../test.xcresult' \ No newline at end of file diff --git a/.github/Gemfile b/.github/Gemfile new file mode 100644 index 0000000000..5ea887c6ef --- /dev/null +++ b/.github/Gemfile @@ -0,0 +1,5 @@ +source("https://rubygems.org") + +gem 'danger' +gem 'plist' +gem 'danger-xcode_summary' \ No newline at end of file diff --git a/.github/Gemfile.lock b/.github/Gemfile.lock new file mode 100644 index 0000000000..297bbfdbbb --- /dev/null +++ b/.github/Gemfile.lock @@ -0,0 +1,82 @@ +GEM + remote: https://rubygems.org/ + specs: + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) + base64 (0.2.0) + claide (1.1.0) + claide-plugins (0.9.2) + cork + nap + open4 (~> 1.3) + colored2 (3.1.2) + cork (0.3.0) + colored2 (~> 3.1) + danger (9.5.1) + base64 (~> 0.2) + claide (~> 1.0) + claide-plugins (>= 0.9.2) + colored2 (~> 3.1) + cork (~> 0.1) + faraday (>= 0.9.0, < 3.0) + faraday-http-cache (~> 2.0) + git (~> 1.13) + kramdown (~> 2.3) + kramdown-parser-gfm (~> 1.0) + octokit (>= 4.0) + pstore (~> 0.1) + terminal-table (>= 1, < 4) + danger-plugin-api (1.0.0) + danger (> 2.0) + danger-xcode_summary (1.3.1) + danger-plugin-api (~> 1.0) + xcresult (~> 0.2.2) + faraday (2.12.0) + faraday-net_http (>= 2.0, < 3.4) + json + logger + faraday-http-cache (2.5.1) + faraday (>= 0.8) + faraday-net_http (3.3.0) + net-http + git (1.19.1) + addressable (~> 2.8) + rchardet (~> 1.8) + json (2.7.5) + kramdown (2.4.0) + rexml + kramdown-parser-gfm (1.1.0) + kramdown (~> 2.0) + logger (1.6.1) + nap (1.1.0) + net-http (0.4.1) + uri + octokit (9.2.0) + faraday (>= 1, < 3) + sawyer (~> 0.9) + open4 (1.3.4) + plist (3.7.1) + pstore (0.1.3) + public_suffix (6.0.1) + rchardet (1.8.0) + rexml (3.3.9) + sawyer (0.9.2) + addressable (>= 2.3.5) + faraday (>= 0.17.3, < 3) + terminal-table (3.0.2) + unicode-display_width (>= 1.1.1, < 3) + unicode-display_width (2.6.0) + uri (0.13.1) + xcresult (0.2.2) + +PLATFORMS + arm64-darwin-23 + ruby + +DEPENDENCIES + danger + danger-xcode_summary + plist + +BUNDLED WITH + 2.5.22 \ No newline at end of file diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index ba843d9f99..d439dc8386 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -14,4 +14,4 @@ jobs: uses: ./.github/workflows/reusable-workflow.yaml with: lib: ${{ matrix.lib }} - ios: ${{ matirx.ios }} \ No newline at end of file + ios: ${{ matrix.ios }} \ No newline at end of file diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 38de0d4772..e84b6fc6b3 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -6,11 +6,37 @@ on: - dev jobs: + static-analysis: + runs-on: macos-latest + outputs: + libs: ${{ steps.danger.outputs.libs }} + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 100 + - name: Install Dependencies + run: | + npm install shelljs@0.8.5 + ./install.sh + - name: Static Analysis and Danger + if: ${{ github.event_name == 'pull_request' }} && (success() || failure()) + id: danger + env: + DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + xcodebuild analyze -workspace SalesforceMobileSDK.xcworkspace -scheme MobileSync -sdk 'iphonesimulator' \ + CLANG_ANALYZER_OUTPUT=plist-html CLANG_ANALYZER_OUTPUT_DIR=./clangReport RUN_CLANG_STATIC_ANALYZER=YES | xcbeautify + cd .github + bundle update && bundle install + bundle exec danger --dangerfile=DangerStaticAnalysis.rb + ios-pr: + needs: [static-analysis] strategy: fail-fast: false matrix: - lib: [SalesforceSDKCommon, SalesforceAnalytics, SalesforceSDKCore, SmartStore, MobileSync] + lib: ${{ fromJson(needs.static-analysis.outputs.libs) }} uses: ./.github/workflows/reusable-workflow.yaml with: lib: ${{ matrix.lib }} \ No newline at end of file diff --git a/.github/workflows/reusable-workflow.yaml b/.github/workflows/reusable-workflow.yaml index e84dfd9db9..640ac4cec0 100644 --- a/.github/workflows/reusable-workflow.yaml +++ b/.github/workflows/reusable-workflow.yaml @@ -17,28 +17,28 @@ jobs: test-ios: runs-on: macos-latest steps: - - uses: actions/checkout@v4.1.0 + - uses: actions/checkout@v4 + with: + fetch-depth: 100 - name: Install Dependencies run: | npm install shelljs@0.8.5 ./install.sh - ./build/pre-build - - name: Static Analysis and Danger - if: ${{ github.event_name == 'pull_request' }} - run: | - xcodebuild analyze -workspace SalesforceMobileSDK.xcworkspace -scheme ${{ inputs.lib }} -sdk 'iphonesimulator' \ - CLANG_ANALYZER_OUTPUT=plist-html CLANG_ANALYZER_OUTPUT_DIR=./clangReport RUN_CLANG_STATIC_ANALYZER=YES + echo ${{ secrets.TEST_CREDENTIALS }} > ./shared/test/test_credentials.json - uses: mxcl/xcodebuild@v3 with: xcode: ${{ inputs.xcode }} platform: iOS platform-version: ${{ inputs.ios }} - workspace: SalesSalesforceMobileSDK.xcworkspace + workspace: SalesforceMobileSDK.xcworkspace scheme: ${{ inputs.lib }} code-coverage: ${{ github.event_name == 'pull_request' }} upload-logs: always - - uses: kishikawakatsumi/xcresulttool@v1 - with: - path: test.xcresult - if: success() || failure() - \ No newline at end of file + - name: Danger Test Results + if: ${{ github.event_name == 'pull_request' }} && (success() || failure()) + env: + DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + cd .github + bundle update && bundle install + bundle exec danger --dangerfile=DangerTestResults.rb --danger_id=${{ inputs.lib }} \ No newline at end of file From 623204d1fe75a3be723837186390586a272f5f9f Mon Sep 17 00:00:00 2001 From: Brandon Page Date: Mon, 4 Nov 2024 10:24:42 -0800 Subject: [PATCH 03/10] Add test-orchestrator so unit tests start before static analysis is finished. Move danger files into their own folder. Add CodeCov. Fix static analysis reporting. --- .circleci/fastlane/Fastfile | 127 ------------------ .github/{ => DangerFiles}/Gemfile | 0 .github/{ => DangerFiles}/Gemfile.lock | 0 .../StaticAnalysis.rb} | 29 +--- .github/DangerFiles/TestOrchestrator.rb | 18 +++ .github/DangerFiles/TestResults.rb | 3 + .github/DangerTestResults.rb | 2 - .github/workflows/pr.yaml | 39 ++++-- .github/workflows/reusable-workflow.yaml | 17 ++- 9 files changed, 69 insertions(+), 166 deletions(-) delete mode 100644 .circleci/fastlane/Fastfile rename .github/{ => DangerFiles}/Gemfile (100%) rename .github/{ => DangerFiles}/Gemfile.lock (100%) rename .github/{DangerStaticAnalysis.rb => DangerFiles/StaticAnalysis.rb} (52%) create mode 100644 .github/DangerFiles/TestOrchestrator.rb create mode 100644 .github/DangerFiles/TestResults.rb delete mode 100644 .github/DangerTestResults.rb diff --git a/.circleci/fastlane/Fastfile b/.circleci/fastlane/Fastfile deleted file mode 100644 index e5bcae5e16..0000000000 --- a/.circleci/fastlane/Fastfile +++ /dev/null @@ -1,127 +0,0 @@ -$git_pr_api = "https://api.github.com/repos/%s/SalesforceMobileSDK-iOS/pulls/%s/files" -$schemes = ['SalesforceSDKCommon', 'SalesforceAnalytics', 'SalesforceSDKCore', 'SmartStore', 'MobileSync'] -ENV['DEVICE'] = 'iPhone-SE-3rd-generation' unless ENV.has_key?('DEVICE') -ENV['IOS_VERSION'] = '17.2' unless ENV.has_key?('IOS_VERSION') - -lane :PR do |options| - lib_to_test = options[:lib] - Dir.chdir('../') - schemes = Set.new - - if (ENV.has_key?('NIGHTLY_TEST') and ENV['NIGHTLY_TEST'] == 'true') - UI.important "Nightly, skipping modified check." - test_scheme(lib_to_test) - else - # Check if this is a PR. - # Rebuilds of PR's don't have the CIRCLE_PULL_REQUEST key, so check the branch instead. - if ENV.has_key?('CIRCLE_BRANCH') && ENV['CIRCLE_BRANCH'].include?('pull/') - # No PR Number indicates that this PR is running in a CircleCI env linked to a fork, so force the url to forcedotcom project. - if ENV.has_key?('CIRCLE_PR_NUMBER') - pr_files_api = $git_pr_api % [ENV['CIRCLE_PROJECT_USERNAME'], ENV['CIRCLE_PR_NUMBER']] - else - pr_files_api = $git_pr_api % ['forcedotcom', ENV['CIRCLE_BRANCH'].split('/').last] - end - pull_files = `#{"curl %s" % [pr_files_api]}` - else - UI.error 'Not a PR on CircleCI, stopping stop execution now.' - `circleci step halt` - next - end - - # Determine which libs have been modified - pr_files = JSON.parse(pull_files) - for pr_file in pr_files - path = pr_file['filename'] - $schemes.each do |scheme| - if path.include? scheme - schemes.merge($schemes[$schemes.index(scheme)..]) - break - end - end - end - UI.important "Schemes to test: " + schemes.to_a().join(',') - - if schemes.include? lib_to_test - test_scheme(lib_to_test) - else - UI.important "Lib #{lib_to_test} not modified by this PR, no need to test." - `circleci step halt` - end - end -end - -lane :LCL do - Dir.chdir('../') - index = 1 - puts 'Select scheme: ' - for scheme in $schemes - puts index.to_s + ': ' + scheme - index = index + 1 - end - - print 'Just enter a number or name: ' - selection = STDIN.gets.strip - - if $schemes.include? selection - test_scheme(selection) - # Not the best error handling, but sufficient for catching typos - elsif selection.to_i > 0 and selection.to_i <= $schemes.count - test_scheme($schemes[selection.to_i - 1]) - else - UI.user_error!('Invalid test selection.') - end -end - -lane :CI do - Dir.chdir('../') - test_scheme('UnitTests') -end - -def test_scheme(scheme) - analyze_scheme(scheme) - - device = ENV['DEVICE'].gsub(' ', '-') - ios_code = ENV['IOS_VERSION'].gsub('.', '-') - system('xcrun simctl delete test_device') or true - sim_id = `xcrun simctl create test_device com.apple.CoreSimulator.SimDeviceType.#{device} com.apple.CoreSimulator.SimRuntime.iOS-#{ios_code}`.delete("\n") - ios_version = `xcrun xctrace list devices | grep test_device | awk -F"[()]" '{print $2}'`.delete("\n") - - if (ios_version.empty?) - UI.user_error!('Invalid Test Device.') - end - - begin - scan( - workspace: 'SalesforceMobileSDK.xcworkspace', - scheme: scheme, - device: "test_device (#{ios_version})", - output_directory: 'test_output', - output_types: 'html,junit', - code_coverage: true, - skip_build: true, - number_of_retries: 1, - xcodebuild_formatter: "xcbeautify" - ) - ensure - system("mv ../test_output/report.html ../test_output/#{scheme}_results.html") - end -end - -def analyze_scheme(scheme) - begin - xcodebuild( - xcargs: 'CLANG_ANALYZER_OUTPUT=plist-html CLANG_ANALYZER_OUTPUT_DIR=./clangReport RUN_CLANG_STATIC_ANALYZER=YES ARCHS=x86_64', - workspace: 'SalesforceMobileSDK.xcworkspace', - scheme: scheme, - sdk: 'iphonesimulator', - ) - ensure - #move clangReports to one folder - system('mkdir -p ../clangReport/StaticAnalyzer') - system('mv ../libs/SalesforceSDKCommon/clangReport/StaticAnalyzer/SalesforceSDKCommon ../clangReport/StaticAnalyzer/') - system('mv ../libs/SalesforceAnalytics/clangReport/StaticAnalyzer/SalesforceAnalytics ../clangReport/StaticAnalyzer/') - system('mv ../libs/SalesforceSDKCore/clangReport/StaticAnalyzer/SalesforceSDKCore ../clangReport/StaticAnalyzer/') - system('mv ../libs/SmartStore/clangReport/StaticAnalyzer/SmartStore ../clangReport/StaticAnalyzer/') - system('mv ../libs/MobileSync/clangReport/StaticAnalyzer/MobileSync ../clangReport/StaticAnalyzer/') - end -end diff --git a/.github/Gemfile b/.github/DangerFiles/Gemfile similarity index 100% rename from .github/Gemfile rename to .github/DangerFiles/Gemfile diff --git a/.github/Gemfile.lock b/.github/DangerFiles/Gemfile.lock similarity index 100% rename from .github/Gemfile.lock rename to .github/DangerFiles/Gemfile.lock diff --git a/.github/DangerStaticAnalysis.rb b/.github/DangerFiles/StaticAnalysis.rb similarity index 52% rename from .github/DangerStaticAnalysis.rb rename to .github/DangerFiles/StaticAnalysis.rb index 26783204fd..522759b543 100644 --- a/.github/DangerStaticAnalysis.rb +++ b/.github/DangerFiles/StaticAnalysis.rb @@ -1,29 +1,14 @@ require 'plist' -# Determine which libs were midified by this PR -modifed_libs = Set[] -for file in (git.modified_files + git.added_files); - # Add the library name for each modified file - modifed_libs.add(file.split("libs/").last.split("/").first) -end - -# If we are modifiing any CI files run all tests. -if modifed_libs.inclues?(".github") - modifed_libs = ['SalesforceSDKCommon', 'SalesforceAnalytics', 'SalesforceSDKCore', 'SmartStore', 'MobileSync'] -end - -# Set Github Job output so we know which tests to run -json_libs = modifed_libs.map { |l| "'#{l}'"}.join(", ") -`echo "libs=[#{json_libs}]" >> $GITHUB_OUTPUT` - # Markdown table character length without any issues MAKRDOWN_LENGTH = 138 +LIBS = ['SalesforceSDKCommon', 'SalesforceAnalytics', 'SalesforceSDKCore', 'SmartStore', 'MobileSync'] -# Get all static analysis report files files = Set[] -for lib in modifed_libs; - files.merge(Dir["../libs/SalesforceAnalytics/clangReport/StaticAnalyzer/#{lib}/#{lib}/normal/**/*.plist"]) +for lib in LIBS; + files.merge(Dir["../../libs/#{lib}/clangReport/StaticAnalyzer/#{lib}/#{lib}/normal/**/*.plist"]) end +print "Found #{files.count} classes with static analysis files.\n" modified_file_names = git.modified_files.map { |file| File.basename(file, File.extname(file)) } added_file_names = git.added_files.map { |file| File.basename(file, File.extname(file)) } @@ -37,14 +22,14 @@ for file in files; report = Plist.parse_xml(file) report_file_name = File.basename(file, File.extname(file)) - print "file name: #{report_file_name}\n" + print "File with clang report: #{report_file_name}\n" if modified_file_names.include?(report_file_name) || added_file_names.include?(report_file_name) - print "file match! #{file}" issues = report['diagnostics'] + print "File modified in PR: #{file}, has #{issue.count} issues.\n" for i in 0..issues.count-1 unless issues[i].nil? - message << "#{file_path.split('/').last} | #{issues[i]['type']} | #{issues[i]['category']} | #{issues[i]['description']} | #{issues[i]['location']['line']} | #{issues[i]['location']['col']}\n" + message << "#{report_file_name} | #{issues[i]['type']} | #{issues[i]['category']} | #{issues[i]['description']} | #{issues[i]['location']['line']} | #{issues[i]['location']['col']}\n" end end end diff --git a/.github/DangerFiles/TestOrchestrator.rb b/.github/DangerFiles/TestOrchestrator.rb new file mode 100644 index 0000000000..86fe22e899 --- /dev/null +++ b/.github/DangerFiles/TestOrchestrator.rb @@ -0,0 +1,18 @@ +# List of supported xcode schemes for testing +SCHEMES = ['SalesforceSDKCommon', 'SalesforceAnalytics', 'SalesforceSDKCore', 'SmartStore', 'MobileSync'] + +modifed_libs = Set[] +for file in (git.modified_files + git.added_files); + scheme = file.split("libs/").last.split("/").first + print "lib: #{scheme}\n" + if scheme == '.github' + # If CI files are modified, run all tests + modifed_libs.merge(SCHEMES) + elsif SCHEMES.include?(scheme) + modifed_libs.add(scheme) + end +end + +# Set Github Job output so we know which tests to run +json_libs = modifed_libs.map { |l| "'#{l}'"}.join(", ") +`echo "libs=[#{json_libs}]" >> $GITHUB_OUTPUT` \ No newline at end of file diff --git a/.github/DangerFiles/TestResults.rb b/.github/DangerFiles/TestResults.rb new file mode 100644 index 0000000000..4224046244 --- /dev/null +++ b/.github/DangerFiles/TestResults.rb @@ -0,0 +1,3 @@ +xcode_summary.ignores_warnings = true +xcode_summary.inline_mode = true +xcode_summary.report '../../test.xcresult' \ No newline at end of file diff --git a/.github/DangerTestResults.rb b/.github/DangerTestResults.rb deleted file mode 100644 index 6e5ecfcc4a..0000000000 --- a/.github/DangerTestResults.rb +++ /dev/null @@ -1,2 +0,0 @@ -xcode_summary.inline_mode = true -xcode_summary.report '../test.xcresult' \ No newline at end of file diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index e84b6fc6b3..f00e22a707 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -8,8 +8,6 @@ on: jobs: static-analysis: runs-on: macos-latest - outputs: - libs: ${{ steps.danger.outputs.libs }} steps: - name: Checkout uses: actions/checkout@v4 @@ -19,24 +17,43 @@ jobs: run: | npm install shelljs@0.8.5 ./install.sh - - name: Static Analysis and Danger - if: ${{ github.event_name == 'pull_request' }} && (success() || failure()) - id: danger + - name: Run Static Analysis + # It would be nice to use xcbeaufity here but all the warnings and errors get annotated onto the PR, including + # files not mofified in the PR which is annoying. + run: xcodebuild analyze -workspace SalesforceMobileSDK.xcworkspace -scheme MobileSync -sdk 'iphonesimulator' \ + CLANG_ANALYZER_OUTPUT=plist-html CLANG_ANALYZER_OUTPUT_DIR=./clangReport RUN_CLANG_STATIC_ANALYZER=YES + - name: Report Static Analysis + env: + DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + cd .github/DangerFiles + bundle update && bundle install + bundle exec danger --dangerfile=StaticAnalysis.rb --danger_id=StaticAnalysis + + test-orchestrator: + runs-on: macos-latest + outputs: + libs: ${{ steps.test-orchestrator.outputs.libs }} + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 100 + - name: Determine Tests to Run + id: test-orchestrator env: DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - xcodebuild analyze -workspace SalesforceMobileSDK.xcworkspace -scheme MobileSync -sdk 'iphonesimulator' \ - CLANG_ANALYZER_OUTPUT=plist-html CLANG_ANALYZER_OUTPUT_DIR=./clangReport RUN_CLANG_STATIC_ANALYZER=YES | xcbeautify - cd .github + cd .github/DangerFiles bundle update && bundle install - bundle exec danger --dangerfile=DangerStaticAnalysis.rb + bundle exec danger --dangerfile=TestOrchestrator.rb ios-pr: - needs: [static-analysis] + needs: [test-orchestrator] strategy: fail-fast: false matrix: - lib: ${{ fromJson(needs.static-analysis.outputs.libs) }} + lib: ${{ fromJson(needs.test-orchestrator.outputs.libs) }} uses: ./.github/workflows/reusable-workflow.yaml with: lib: ${{ matrix.lib }} \ No newline at end of file diff --git a/.github/workflows/reusable-workflow.yaml b/.github/workflows/reusable-workflow.yaml index 640ac4cec0..3b64c33c5d 100644 --- a/.github/workflows/reusable-workflow.yaml +++ b/.github/workflows/reusable-workflow.yaml @@ -1,4 +1,5 @@ on: + workflow_dispatch: workflow_call: inputs: lib: @@ -21,10 +22,12 @@ jobs: with: fetch-depth: 100 - name: Install Dependencies + env: + TEST_CREDENTIALS: ${{ secrets.TEST_CREDENTIALS }} run: | npm install shelljs@0.8.5 ./install.sh - echo ${{ secrets.TEST_CREDENTIALS }} > ./shared/test/test_credentials.json + echo $TEST_CREDENTIALS > ./shared/test/test_credentials.json - uses: mxcl/xcodebuild@v3 with: xcode: ${{ inputs.xcode }} @@ -35,10 +38,16 @@ jobs: code-coverage: ${{ github.event_name == 'pull_request' }} upload-logs: always - name: Danger Test Results - if: ${{ github.event_name == 'pull_request' }} && (success() || failure()) + if: (github.event_name == 'pull_request') && failure() env: DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - cd .github + cd .github/DangerFiles bundle update && bundle install - bundle exec danger --dangerfile=DangerTestResults.rb --danger_id=${{ inputs.lib }} \ No newline at end of file + bundle exec danger --dangerfile=TestResults.rb --danger_id=${{ inputs.lib }} + - uses: codecov/codecov-action@v4 + with: + flags: ${{ inputs.lib }} + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + if: success() || failure() \ No newline at end of file From c8c74e38606c8a154badd5ae8ac7ef923163f750 Mon Sep 17 00:00:00 2001 From: Brandon Page Date: Mon, 4 Nov 2024 17:51:57 -0800 Subject: [PATCH 04/10] Fix secrets inheritance. --- .circleci/fastlane/Fastfile | 0 .github/DangerFiles/TestOrchestrator.rb | 1 - .github/workflows/nightly.yaml | 3 ++- .github/workflows/pr.yaml | 7 ++++++- .github/workflows/reusable-workflow.yaml | 2 ++ 5 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 .circleci/fastlane/Fastfile diff --git a/.circleci/fastlane/Fastfile b/.circleci/fastlane/Fastfile new file mode 100644 index 0000000000..e69de29bb2 diff --git a/.github/DangerFiles/TestOrchestrator.rb b/.github/DangerFiles/TestOrchestrator.rb index 86fe22e899..4ce7fb633d 100644 --- a/.github/DangerFiles/TestOrchestrator.rb +++ b/.github/DangerFiles/TestOrchestrator.rb @@ -4,7 +4,6 @@ modifed_libs = Set[] for file in (git.modified_files + git.added_files); scheme = file.split("libs/").last.split("/").first - print "lib: #{scheme}\n" if scheme == '.github' # If CI files are modified, run all tests modifed_libs.merge(SCHEMES) diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index d439dc8386..6300cad032 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -14,4 +14,5 @@ jobs: uses: ./.github/workflows/reusable-workflow.yaml with: lib: ${{ matrix.lib }} - ios: ${{ matrix.ios }} \ No newline at end of file + ios: ${{ matrix.ios }} + secrets: inherit \ No newline at end of file diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index f00e22a707..2f4fcab8c6 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -11,6 +11,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + # We need a sufficient depth or Danger will occasionally run into issues + # checking which files were modified. with: fetch-depth: 100 - name: Install Dependencies @@ -37,6 +39,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + # We need a sufficient depth or Danger will occasionally run into issues + # checking which files were modified. with: fetch-depth: 100 - name: Determine Tests to Run @@ -56,4 +60,5 @@ jobs: lib: ${{ fromJson(needs.test-orchestrator.outputs.libs) }} uses: ./.github/workflows/reusable-workflow.yaml with: - lib: ${{ matrix.lib }} \ No newline at end of file + lib: ${{ matrix.lib }} + secrets: inherit \ No newline at end of file diff --git a/.github/workflows/reusable-workflow.yaml b/.github/workflows/reusable-workflow.yaml index 3b64c33c5d..16d607444e 100644 --- a/.github/workflows/reusable-workflow.yaml +++ b/.github/workflows/reusable-workflow.yaml @@ -19,6 +19,8 @@ jobs: runs-on: macos-latest steps: - uses: actions/checkout@v4 + # We need a sufficient depth or Danger will occasionally run into issues + # checking which files were modified. with: fetch-depth: 100 - name: Install Dependencies From 1362002155e61c3057b5024c2135815f193a6b25 Mon Sep 17 00:00:00 2001 From: Brandon Page Date: Mon, 4 Nov 2024 17:53:04 -0800 Subject: [PATCH 05/10] no message --- .circleci/fastlane/Fastfile | 128 ++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) diff --git a/.circleci/fastlane/Fastfile b/.circleci/fastlane/Fastfile index e69de29bb2..886c4a133f 100644 --- a/.circleci/fastlane/Fastfile +++ b/.circleci/fastlane/Fastfile @@ -0,0 +1,128 @@ + +$git_pr_api = "https://api.github.com/repos/%s/SalesforceMobileSDK-iOS/pulls/%s/files" +$schemes = ['SalesforceSDKCommon', 'SalesforceAnalytics', 'SalesforceSDKCore', 'SmartStore', 'MobileSync'] +ENV['DEVICE'] = 'iPhone-SE-3rd-generation' unless ENV.has_key?('DEVICE') +ENV['IOS_VERSION'] = '17.2' unless ENV.has_key?('IOS_VERSION') + +lane :PR do |options| + lib_to_test = options[:lib] + Dir.chdir('../') + schemes = Set.new + + if (ENV.has_key?('NIGHTLY_TEST') and ENV['NIGHTLY_TEST'] == 'true') + UI.important "Nightly, skipping modified check." + test_scheme(lib_to_test) + else + # Check if this is a PR. + # Rebuilds of PR's don't have the CIRCLE_PULL_REQUEST key, so check the branch instead. + if ENV.has_key?('CIRCLE_BRANCH') && ENV['CIRCLE_BRANCH'].include?('pull/') + # No PR Number indicates that this PR is running in a CircleCI env linked to a fork, so force the url to forcedotcom project. + if ENV.has_key?('CIRCLE_PR_NUMBER') + pr_files_api = $git_pr_api % [ENV['CIRCLE_PROJECT_USERNAME'], ENV['CIRCLE_PR_NUMBER']] + else + pr_files_api = $git_pr_api % ['forcedotcom', ENV['CIRCLE_BRANCH'].split('/').last] + end + pull_files = `#{"curl %s" % [pr_files_api]}` + else + UI.error 'Not a PR on CircleCI, stopping stop execution now.' + `circleci step halt` + next + end + + # Determine which libs have been modified + pr_files = JSON.parse(pull_files) + for pr_file in pr_files + path = pr_file['filename'] + $schemes.each do |scheme| + if path.include? scheme + schemes.merge($schemes[$schemes.index(scheme)..]) + break + end + end + end + UI.important "Schemes to test: " + schemes.to_a().join(',') + + if schemes.include? lib_to_test + test_scheme(lib_to_test) + else + UI.important "Lib #{lib_to_test} not modified by this PR, no need to test." + `circleci step halt` + end + end +end + +lane :LCL do + Dir.chdir('../') + index = 1 + puts 'Select scheme: ' + for scheme in $schemes + puts index.to_s + ': ' + scheme + index = index + 1 + end + + print 'Just enter a number or name: ' + selection = STDIN.gets.strip + + if $schemes.include? selection + test_scheme(selection) + # Not the best error handling, but sufficient for catching typos + elsif selection.to_i > 0 and selection.to_i <= $schemes.count + test_scheme($schemes[selection.to_i - 1]) + else + UI.user_error!('Invalid test selection.') + end +end + +lane :CI do + Dir.chdir('../') + test_scheme('UnitTests') +end + +def test_scheme(scheme) + analyze_scheme(scheme) + + device = ENV['DEVICE'].gsub(' ', '-') + ios_code = ENV['IOS_VERSION'].gsub('.', '-') + system('xcrun simctl delete test_device') or true + sim_id = `xcrun simctl create test_device com.apple.CoreSimulator.SimDeviceType.#{device} com.apple.CoreSimulator.SimRuntime.iOS-#{ios_code}`.delete("\n") + ios_version = `xcrun xctrace list devices | grep test_device | awk -F"[()]" '{print $2}'`.delete("\n") + + if (ios_version.empty?) + UI.user_error!('Invalid Test Device.') + end + + begin + scan( + workspace: 'SalesforceMobileSDK.xcworkspace', + scheme: scheme, + device: "test_device (#{ios_version})", + output_directory: 'test_output', + output_types: 'html,junit', + code_coverage: true, + skip_build: true, + number_of_retries: 1, + xcodebuild_formatter: "xcbeautify" + ) + ensure + system("mv ../test_output/report.html ../test_output/#{scheme}_results.html") + end +end + +def analyze_scheme(scheme) + begin + xcodebuild( + xcargs: 'CLANG_ANALYZER_OUTPUT=plist-html CLANG_ANALYZER_OUTPUT_DIR=./clangReport RUN_CLANG_STATIC_ANALYZER=YES ARCHS=x86_64', + workspace: 'SalesforceMobileSDK.xcworkspace', + scheme: scheme, + sdk: 'iphonesimulator', + ) + ensure + #move clangReports to one folder + system('mkdir -p ../clangReport/StaticAnalyzer') + system('mv ../libs/SalesforceSDKCommon/clangReport/StaticAnalyzer/SalesforceSDKCommon ../clangReport/StaticAnalyzer/') + system('mv ../libs/SalesforceAnalytics/clangReport/StaticAnalyzer/SalesforceAnalytics ../clangReport/StaticAnalyzer/') + system('mv ../libs/SalesforceSDKCore/clangReport/StaticAnalyzer/SalesforceSDKCore ../clangReport/StaticAnalyzer/') + system('mv ../libs/SmartStore/clangReport/StaticAnalyzer/SmartStore ../clangReport/StaticAnalyzer/') + system('mv ../libs/MobileSync/clangReport/StaticAnalyzer/MobileSync ../clangReport/StaticAnalyzer/') + end +end \ No newline at end of file From f44532455b53c6ee88e467f9838073b51e2ab386 Mon Sep 17 00:00:00 2001 From: Brandon Page Date: Mon, 4 Nov 2024 18:46:32 -0800 Subject: [PATCH 06/10] no message --- .circleci/fastlane/Fastfile | 3 +-- .github/DangerFiles/TestResults.rb | 7 ++++++- .github/workflows/reusable-workflow.yaml | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.circleci/fastlane/Fastfile b/.circleci/fastlane/Fastfile index 886c4a133f..4e5a354947 100644 --- a/.circleci/fastlane/Fastfile +++ b/.circleci/fastlane/Fastfile @@ -1,4 +1,3 @@ - $git_pr_api = "https://api.github.com/repos/%s/SalesforceMobileSDK-iOS/pulls/%s/files" $schemes = ['SalesforceSDKCommon', 'SalesforceAnalytics', 'SalesforceSDKCore', 'SmartStore', 'MobileSync'] ENV['DEVICE'] = 'iPhone-SE-3rd-generation' unless ENV.has_key?('DEVICE') @@ -86,7 +85,7 @@ def test_scheme(scheme) system('xcrun simctl delete test_device') or true sim_id = `xcrun simctl create test_device com.apple.CoreSimulator.SimDeviceType.#{device} com.apple.CoreSimulator.SimRuntime.iOS-#{ios_code}`.delete("\n") ios_version = `xcrun xctrace list devices | grep test_device | awk -F"[()]" '{print $2}'`.delete("\n") - + if (ios_version.empty?) UI.user_error!('Invalid Test Device.') end diff --git a/.github/DangerFiles/TestResults.rb b/.github/DangerFiles/TestResults.rb index 4224046244..5fb45580c8 100644 --- a/.github/DangerFiles/TestResults.rb +++ b/.github/DangerFiles/TestResults.rb @@ -1,3 +1,8 @@ xcode_summary.ignores_warnings = true xcode_summary.inline_mode = true -xcode_summary.report '../../test.xcresult' \ No newline at end of file + +if File.exist?('../../test.xcresult') + xcode_summary.report '../../test.xcresult' +else + fail "No test results found." +end \ No newline at end of file diff --git a/.github/workflows/reusable-workflow.yaml b/.github/workflows/reusable-workflow.yaml index 16d607444e..4ae4e9303a 100644 --- a/.github/workflows/reusable-workflow.yaml +++ b/.github/workflows/reusable-workflow.yaml @@ -37,7 +37,7 @@ jobs: platform-version: ${{ inputs.ios }} workspace: SalesforceMobileSDK.xcworkspace scheme: ${{ inputs.lib }} - code-coverage: ${{ github.event_name == 'pull_request' }} + code-coverage: true upload-logs: always - name: Danger Test Results if: (github.event_name == 'pull_request') && failure() From 6d07289071d27476f7cc14e8d383f82fd3c939bf Mon Sep 17 00:00:00 2001 From: Brandon Page Date: Wed, 6 Nov 2024 14:02:29 -0800 Subject: [PATCH 07/10] Move to pull_request_target event with member check. --- .github/workflows/pr.yaml | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 2f4fcab8c6..a782e9e926 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -1,7 +1,8 @@ name: Pull Request -on: - pull_request: +on: + # Dangerious without Member Check setep! + pull_request_target: branches: - dev @@ -9,12 +10,18 @@ jobs: static-analysis: runs-on: macos-latest steps: + - name: Member Check + if: ${{ github.event.pull_request.author_association != 'MEMBER' }} + run: | + echo "Pull Request not triggered by a MSDK team member. Someone from the team needs to rerun this workflow AFTER it has been deemed safe." + exit 1 - name: Checkout uses: actions/checkout@v4 - # We need a sufficient depth or Danger will occasionally run into issues - # checking which files were modified. with: + # We need a sufficient depth or Danger will occasionally run into issues checking which files were modified. fetch-depth: 100 + # This is dangerous without the member check + ref: ${{ github.event.pull_request.head.sha }} - name: Install Dependencies run: | npm install shelljs@0.8.5 @@ -37,12 +44,18 @@ jobs: outputs: libs: ${{ steps.test-orchestrator.outputs.libs }} steps: + - name: Member Check + if: ${{ github.event.pull_request.author_association != 'MEMBER' }} + run: | + echo "Pull Request not triggered by a MSDK team member. Someone from the team needs to rerun this workflow AFTER it has been deemed safe." + exit 1 - name: Checkout uses: actions/checkout@v4 - # We need a sufficient depth or Danger will occasionally run into issues - # checking which files were modified. with: + # We need a sufficient depth or Danger will occasionally run into issues checking which files were modified. fetch-depth: 100 + # This is dangerous without the member check + ref: ${{ github.event.pull_request.head.sha }} - name: Determine Tests to Run id: test-orchestrator env: From a77d4eae449334d7d7bb9a44aa28b72f064e0b09 Mon Sep 17 00:00:00 2001 From: Brandon Page Date: Wed, 6 Nov 2024 14:06:57 -0800 Subject: [PATCH 08/10] Remove check if CI files are modified. --- .github/DangerFiles/TestOrchestrator.rb | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/DangerFiles/TestOrchestrator.rb b/.github/DangerFiles/TestOrchestrator.rb index 4ce7fb633d..96b28a76ca 100644 --- a/.github/DangerFiles/TestOrchestrator.rb +++ b/.github/DangerFiles/TestOrchestrator.rb @@ -4,10 +4,7 @@ modifed_libs = Set[] for file in (git.modified_files + git.added_files); scheme = file.split("libs/").last.split("/").first - if scheme == '.github' - # If CI files are modified, run all tests - modifed_libs.merge(SCHEMES) - elsif SCHEMES.include?(scheme) + if SCHEMES.include?(scheme) modifed_libs.add(scheme) end end From f7386a4dfb051ed075c832f84f5450bac2ab9b75 Mon Sep 17 00:00:00 2001 From: Brandon Page Date: Thu, 14 Nov 2024 12:44:38 -0800 Subject: [PATCH 09/10] Use xcbeautify for test runs and adjust for new single xcode version per macos image Github policy. --- .github/workflows/nightly.yaml | 7 +++++++ .github/workflows/pr.yaml | 4 ++-- .github/workflows/reusable-workflow.yaml | 9 +++++++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index 6300cad032..15e13a9d15 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -11,8 +11,15 @@ jobs: matrix: lib: [SalesforceSDKCommon, SalesforceAnalytics, SalesforceSDKCore, SmartStore, MobileSync] ios: [^18, ^17] + include: + - ios: ^18 + macos: macos-15 + - ios: ^17 + macos: macos-14 + uses: ./.github/workflows/reusable-workflow.yaml with: lib: ${{ matrix.lib }} ios: ${{ matrix.ios }} + macos: ${{ matrix.macos }} secrets: inherit \ No newline at end of file diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index a782e9e926..9675e37dee 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -8,7 +8,7 @@ on: jobs: static-analysis: - runs-on: macos-latest + runs-on: macos-15 steps: - name: Member Check if: ${{ github.event.pull_request.author_association != 'MEMBER' }} @@ -40,7 +40,7 @@ jobs: bundle exec danger --dangerfile=StaticAnalysis.rb --danger_id=StaticAnalysis test-orchestrator: - runs-on: macos-latest + runs-on: macos-15 outputs: libs: ${{ steps.test-orchestrator.outputs.libs }} steps: diff --git a/.github/workflows/reusable-workflow.yaml b/.github/workflows/reusable-workflow.yaml index 4ae4e9303a..c543cbb85d 100644 --- a/.github/workflows/reusable-workflow.yaml +++ b/.github/workflows/reusable-workflow.yaml @@ -13,10 +13,14 @@ on: default: '^16' required: false type: string - + macos: + default: macos-15 + required: false + type: string + jobs: test-ios: - runs-on: macos-latest + runs-on: ${{ inputs.macos }} steps: - uses: actions/checkout@v4 # We need a sufficient depth or Danger will occasionally run into issues @@ -39,6 +43,7 @@ jobs: scheme: ${{ inputs.lib }} code-coverage: true upload-logs: always + verbosity: xcbeautify - name: Danger Test Results if: (github.event_name == 'pull_request') && failure() env: From c599165bac6711fc40452fd936bbb7ab4397c256 Mon Sep 17 00:00:00 2001 From: Brandon Page Date: Fri, 15 Nov 2024 11:34:05 -0800 Subject: [PATCH 10/10] Add owner to author check to make it easier simpler to test CI from forks before PR. --- .github/workflows/pr.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 9675e37dee..fd096e3fc0 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -11,7 +11,7 @@ jobs: runs-on: macos-15 steps: - name: Member Check - if: ${{ github.event.pull_request.author_association != 'MEMBER' }} + if: ${{ github.event.pull_request.author_association != 'MEMBER' && github.event.pull_request.author_association != 'OWNER' }} run: | echo "Pull Request not triggered by a MSDK team member. Someone from the team needs to rerun this workflow AFTER it has been deemed safe." exit 1