diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index 1b26464..03970a1 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -2,10 +2,13 @@ name: Nightly Tests on: schedule: - - cron: "0 5 * * 4" # cron is UTC, this translates to 10 PM PST Wednesday. + - cron: "30 5 * * 3,5" # cron is UTC; 9:30 PM PT Tue/Thu. # This lets us trigger the workflow from a browser. workflow_dispatch: +permissions: + contents: read + jobs: ios-nightly: strategy: @@ -23,7 +26,12 @@ jobs: lib: ${{ matrix.lib }} ios: ${{ matrix.ios }} xcode: ${{ matrix.xcode }} - secrets: inherit + permissions: + contents: read + pull-requests: write + secrets: + TEST_CREDENTIALS: ${{ secrets.TEST_CREDENTIALS }} + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} hybrid-samples-nightly: strategy: @@ -41,4 +49,5 @@ jobs: app: ${{ matrix.app }} ios: ${{ matrix.ios }} xcode: ${{ matrix.xcode }} - secrets: inherit \ No newline at end of file + permissions: + contents: read \ No newline at end of file diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 534d3f7..c019fde 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -1,17 +1,25 @@ name: Pull Request on: - pull_request_target: + # pull_request_target is required for fork PRs to receive secrets. + # Mitigated by per-job Member Check (see "Check Write Permission" / "Validate Write Permission"). + pull_request_target: # zizmor: ignore[dangerous-triggers] branches: [dev, master] +permissions: + contents: read + jobs: static-analysis: runs-on: macos-latest + permissions: + contents: read + pull-requests: write env: BUNDLE_GEMFILE: ${{ github.workspace }}/.github/DangerFiles/Gemfile steps: - name: Check Write Permission - uses: octokit/request-action@v2.x + uses: octokit/request-action@dad4362715b7fb2ddedf9772c8670824af564f0d # v2.4.0 id: check_permissions with: route: GET /repos/${{ github.repository }}/collaborators/${{ github.triggering_actor }}/permission @@ -29,8 +37,9 @@ jobs: exit 1 fi - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 with: + persist-credentials: false # 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 @@ -43,7 +52,7 @@ jobs: run: xcodebuild analyze -workspace SalesforceMobileSDK-Hybrid.xcworkspace -scheme MobileSync -sdk 'iphonesimulator' \ CLANG_ANALYZER_OUTPUT=plist-html CLANG_ANALYZER_OUTPUT_DIR=./clangReport RUN_CLANG_STATIC_ANALYZER=YES - - uses: ruby/setup-ruby@v1 + - uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0 with: ruby-version: '3.3' bundler-cache: true @@ -64,7 +73,12 @@ jobs: lib: ${{ matrix.lib }} ios: ${{ matrix.ios }} is_pr: true - secrets: inherit + permissions: + contents: read + pull-requests: write + secrets: + TEST_CREDENTIALS: ${{ secrets.TEST_CREDENTIALS }} + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} hybrid-samples-pr: needs: [static-analysis] @@ -76,4 +90,5 @@ jobs: with: app: ${{ matrix.app }} is_pr: true - secrets: inherit \ No newline at end of file + permissions: + contents: read \ No newline at end of file diff --git a/.github/workflows/reusable-build-workflow.yaml b/.github/workflows/reusable-build-workflow.yaml index 5510907..f6bb382 100644 --- a/.github/workflows/reusable-build-workflow.yaml +++ b/.github/workflows/reusable-build-workflow.yaml @@ -20,24 +20,30 @@ on: type: boolean default: false +permissions: + contents: read + jobs: build-ios: runs-on: ${{ inputs.macos }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 if: ${{ inputs.is_pr }} with: + persist-credentials: false ref: ${{ github.event.pull_request.head.sha }} - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 if: ${{ ! inputs.is_pr }} with: + persist-credentials: false ref: ${{ github.head_ref }} - name: Install Dependencies run: ./install.sh - name: Install iOS 17 runtime if needed if: ${{ inputs.ios == '^17' }} run: xcodes runtimes install "iOS 17.5" - - uses: mxcl/xcodebuild@v3 + - uses: mxcl/xcodebuild@d3ee9b419c1be9a988086c58fe0988f32d99cfc5 # v3.6.0 + id: build with: xcode: ${{ inputs.xcode }} platform: iOS @@ -46,3 +52,13 @@ jobs: scheme: ${{ inputs.app }} action: build verbosity: xcbeautify + - name: Archive build logs on failure + if: failure() && steps.build.outcome == 'failure' + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: xcode-build-logs-${{ inputs.app }}-ios${{ inputs.ios }} + path: | + ~/Library/Developer/Xcode/DerivedData/**/Logs/Build/*.xcactivitylog + ~/Library/Logs/DiagnosticReports/** + if-no-files-found: ignore + retention-days: 14 diff --git a/.github/workflows/reusable-test-workflow.yaml b/.github/workflows/reusable-test-workflow.yaml index 933f070..cc05e70 100644 --- a/.github/workflows/reusable-test-workflow.yaml +++ b/.github/workflows/reusable-test-workflow.yaml @@ -19,18 +19,29 @@ on: is_pr: type: boolean default: false + secrets: + TEST_CREDENTIALS: + required: true + CODECOV_TOKEN: + required: true + +permissions: + contents: read + pull-requests: write jobs: test-ios: runs-on: ${{ inputs.macos }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 if: ${{ inputs.is_pr }} with: + persist-credentials: false ref: ${{ github.event.pull_request.head.sha }} - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 if: ${{ ! inputs.is_pr }} with: + persist-credentials: false ref: ${{ github.head_ref }} - name: Install Dependencies env: @@ -38,7 +49,7 @@ jobs: run: | ./install.sh echo $TEST_CREDENTIALS > ./shared/test/test_credentials.json - - uses: mxcl/xcodebuild@v3 + - uses: mxcl/xcodebuild@d3ee9b419c1be9a988086c58fe0988f32d99cfc5 # v3.6.0 id: xcodebuild with: xcode: ${{ inputs.xcode }} @@ -49,13 +60,25 @@ jobs: action: test code-coverage: true verbosity: xcbeautify + - name: Archive xcodebuild logs on build failure + if: failure() && steps.xcodebuild.outcome == 'failure' + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: xcodebuild-logs-${{ inputs.lib }}-ios${{ inputs.ios }} + path: | + ~/Library/Developer/Xcode/DerivedData/**/Logs/Build/*.xcactivitylog + if-no-files-found: ignore + retention-days: 14 - name: Parse test results if: success() || failure() + env: + LIB: ${{ inputs.lib }} + IOS: ${{ inputs.ios }} run: | brew install xcresultparser - xcresultparser -o junit test.xcresult > test-results-${{ inputs.lib }}-ios${{ inputs.ios }}.xml + xcresultparser -o junit test.xcresult > "test-results-${LIB}-ios${IOS}.xml" - name: Test Report - uses: mikepenz/action-junit-report@v6 + uses: mikepenz/action-junit-report@3a81627bfac62268172037048872e8ebd4207e6d # v6.4.1 if: success() || failure() with: check_name: ${{ inputs.lib }} iOS ${{ inputs.ios }} Test Results @@ -67,7 +90,7 @@ jobs: comment: true job_summary: ${{ steps.xcodebuild.outcome == 'failure' }} report_paths: 'test-results-${{ inputs.lib }}-ios${{ inputs.ios }}.xml' - - uses: codecov/codecov-action@v4 + - uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4.6.0 if: success() || failure() with: flags: ${{ inputs.lib }} @@ -75,7 +98,7 @@ jobs: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - name: Upload test results artifact if: success() || failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: test-results-${{ inputs.lib }}-ios${{ inputs.ios }} path: test-results-${{ inputs.lib }}-ios${{ inputs.ios }}.xml