fix(ci): harden some workflows in cocoon (#5106)

fixes flutter/flutter#189097

```
➜  /app /opt/zizmor --gh-token=$(gh auth token) .github/workflows
 INFO zizmor: 🌈 zizmor v1.25.2
 INFO audit: zizmor: 🌈 completed .github/workflows/app_dart_tests.yaml
 INFO audit: zizmor: 🌈 completed .github/workflows/common_validation.yaml
 INFO audit: zizmor: 🌈 completed .github/workflows/dashboard_tests.yaml
 INFO audit: zizmor: 🌈 completed .github/workflows/packages_checks.yaml
No findings to report. Good job! (13 suppressed)
➜  /app /opt/zizmor --gh-token=$(gh auth token) packages/wait_for_tests
 INFO zizmor: 🌈 zizmor v1.25.2
 INFO audit: zizmor: 🌈 completed packages/wait_for_tests/action.yml
No findings to report. Good job! (1 suppressed)
```
diff --git a/.github/workflows/app_dart_tests.yaml b/.github/workflows/app_dart_tests.yaml
index 0db9e2b..ccfc1f9 100644
--- a/.github/workflows/app_dart_tests.yaml
+++ b/.github/workflows/app_dart_tests.yaml
@@ -1,5 +1,8 @@
 name: Test app_dart
 
+permissions:
+  contents: read
+
 on:
   pull_request:
     branches: [main]
@@ -25,7 +28,9 @@
           architecture: x64 # only needed for running locally (mac)
 
       - name: Checkout code
-        uses: actions/checkout@v7
+        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
+        with:
+          persist-credentials: false
 
       - name: Get packages
         run: |
diff --git a/.github/workflows/common_validation.yaml b/.github/workflows/common_validation.yaml
index a16ecc4..a3260bf 100644
--- a/.github/workflows/common_validation.yaml
+++ b/.github/workflows/common_validation.yaml
@@ -1,5 +1,8 @@
 name: Common workflows
 
+permissions:
+  contents: read
+
 on:
   pull_request:
     branches: [main]
@@ -17,7 +20,9 @@
           architecture: x64 # only needed for running locally (mac)
 
       - name: Checkout code
-        uses: actions/checkout@v7
+        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
+        with:
+          persist-credentials: false
 
       - name: Run analyze.dart
         working-directory: analyze
diff --git a/.github/workflows/dashboard_tests.yaml b/.github/workflows/dashboard_tests.yaml
index c0c6618..f066c56 100644
--- a/.github/workflows/dashboard_tests.yaml
+++ b/.github/workflows/dashboard_tests.yaml
@@ -1,5 +1,8 @@
 name: Test dashboard
 
+permissions:
+  contents: read
+
 on:
   workflow_dispatch:
     inputs:
@@ -34,7 +37,9 @@
           architecture: x64 # only needed for running locally (mac)
 
       - name: Checkout code
-        uses: actions/checkout@v7
+        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
+        with:
+          persist-credentials: false
 
       - name: Get packages
         run: |
@@ -48,18 +53,6 @@
         run: |
           dart format --set-exit-if-changed .
 
-      # Failures on github will upload the artifacts as annotations.
-      # Review them and if you accept them, either download them or run:
-      # gh act -b --env UPDATE_GOLDENS=true --container-architecture linux/amd64 --container-options="--tty" --workflows ".github/workflows/dashboard_tests.yaml"
-      # The `--update-goldens` flag will not work on GitHub because we do not
-      # have write access to the repository.
-      - name: Upload Golden Failures
-        if: failure()
-        uses: actions/upload-artifact@v7
-        with:
-          name: golden-failures
-          path: 'dashboard/**/failures/*.png'
-
       - name: Flutter Test
         run: |
           EXTRA_ARGS=""
@@ -68,3 +61,14 @@
           fi
           flutter test --test-randomize-ordering-seed=random --reporter expanded $EXTRA_ARGS
 
+      # Failures on github will upload the artifacts as annotations.
+      # Review them and if you accept them, either download them or run:
+      # gh act -b --env UPDATE_GOLDENS=true --container-architecture linux/amd64 --container-options="--tty" --workflows ".github/workflows/dashboard_tests.yaml"
+      # The `--update-goldens` flag will not work on GitHub because we do not
+      # have write access to the repository.
+      - name: Upload Golden Failures
+        if: failure()
+        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
+        with:
+          name: golden-failures
+          path: 'dashboard/**/failures/*.png'
diff --git a/.github/workflows/packages_checks.yaml b/.github/workflows/packages_checks.yaml
index 390a588..ab37f4c 100644
--- a/.github/workflows/packages_checks.yaml
+++ b/.github/workflows/packages_checks.yaml
@@ -1,5 +1,8 @@
 name: Package Checks
 
+permissions:
+  contents: read
+
 on:
   pull_request:
     branches: [main]
@@ -15,7 +18,9 @@
     outputs:
       tests: ${{ steps.tests.outputs.tests }}
     steps:
-      - uses: actions/checkout@v7
+      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
+        with:
+          persist-credentials: false
       - id: tests
         run: |
           echo "tests=$(find packages dev cipd_packages auto_submit licenses -type f -name 'pubspec.yaml' -print0 | xargs -0 dirname | jq --raw-input --slurp --compact-output 'split("\n")[:-1]')" >> ${GITHUB_OUTPUT}
@@ -31,7 +36,9 @@
         working-directory: ${{ matrix.dir }}
     steps:
       - name: Checkout code
-        uses: actions/checkout@v7
+        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
+        with:
+          persist-credentials: false
 
       - name: Set up Flutter
         uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2
diff --git a/packages/wait_for_tests/action.yml b/packages/wait_for_tests/action.yml
index 8d8c482..251dc1d 100644
--- a/packages/wait_for_tests/action.yml
+++ b/packages/wait_for_tests/action.yml
@@ -19,9 +19,10 @@
   using: 'composite'
   steps:
     - name: Set up Dart SDK
-      uses: dart-lang/setup-dart@v1.7.2
+      uses: dart-lang/setup-dart@65eb853c7ba17dde3be364c3d2858773e7144260 # v1.7.2
 
     - name: Get dependencies
+      id: get-deps
       shell: bash
       run: |
         # 1. Resolve the action path.
@@ -32,7 +33,7 @@
         if [ -z "$ACTION_PATH" ] || [ "$ACTION_PATH" = "." ] || [ "$ACTION_PATH" = "$(pwd)" ]; then
           ACTION_PATH="packages/wait_for_tests"
         fi
-        echo "RESOLVED_ACTION_PATH=$ACTION_PATH" >> "$GITHUB_ENV"
+        echo "resolved-action-path=$ACTION_PATH" >> "$GITHUB_OUTPUT"
         echo "Using action path: $ACTION_PATH"
 
         # 2. Bypass workspace resolution.
@@ -64,5 +65,6 @@
         INPUT_REPO: ${{ inputs.repo }}
         INPUT_REQUIRED_TESTS: ${{ inputs.required-tests }}
         INPUT_WAIT_INTERVAL: ${{ inputs.wait-interval }}
+        RESOLVED_ACTION_PATH: ${{ steps.get-deps.outputs.resolved-action-path }}
       run: dart "$RESOLVED_ACTION_PATH/bin/wait_for_tests.dart"