diff --git a/.github/dependabot.yml b/.github/dependabot.yml index bff08b2b5..e48b1a50d 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -14,7 +14,8 @@ version: 2 updates: - - package-ecosystem: "npm" + # Maintain weekly dependency update schedule without an artificial cooldown delay + - package-ecosystem: "npm" # zizmor: ignore[dependabot-cooldown] directory: "/" schedule: interval: "weekly" diff --git a/.github/workflows/dependabot.yml b/.github/workflows/dependabot.yml index b82619a65..f58d568af 100644 --- a/.github/workflows/dependabot.yml +++ b/.github/workflows/dependabot.yml @@ -13,7 +13,9 @@ # limitations under the License. name: Dependabot -on: pull_request_target +# Safe: Workflow only interacts with the GitHub API via `gh` CLI to approve and auto-merge +# verified Dependabot PRs; it does NOT checkout repository code or execute untrusted scripts. +on: pull_request_target # zizmor: ignore[dangerous-triggers] permissions: contents: write @@ -22,7 +24,7 @@ permissions: jobs: dependabot: runs-on: ubuntu-latest - if: ${{ github.actor == 'dependabot[bot]' }} + if: github.event.pull_request.user.login == 'dependabot[bot]' env: PR_URL: ${{ github.event.pull_request.html_url }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/dist-pr.yml b/.github/workflows/dist-pr.yml index 14e2ffff5..77911b211 100644 --- a/.github/workflows/dist-pr.yml +++ b/.github/workflows/dist-pr.yml @@ -31,11 +31,11 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 with: token: ${{ secrets.GH_MERGE_TOKEN }} fetch-depth: 0 - + persist-credentials: false - name: Set Git Identity run: | git config --global user.name 'googlemaps-bot' @@ -82,11 +82,15 @@ jobs: - name: Determine PR URL id: pr + env: + PR_EXISTS: ${{ steps.find_pr.outputs.pr_exists }} + FIND_PR_URL: ${{ steps.find_pr.outputs.pr_url }} + CREATE_PR_URL: ${{ steps.create_pr.outputs.pr_url }} run: | - if [ "${{ steps.find_pr.outputs.pr_exists }}" = "true" ]; then - echo "pr_url=${{ steps.find_pr.outputs.pr_url }}" >> "$GITHUB_OUTPUT" + if [ "$PR_EXISTS" = "true" ]; then + echo "pr_url=$FIND_PR_URL" >> "$GITHUB_OUTPUT" else - echo "pr_url=${{ steps.create_pr.outputs.pr_url }}" >> "$GITHUB_OUTPUT" + echo "pr_url=$CREATE_PR_URL" >> "$GITHUB_OUTPUT" fi - name: Approve PR diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3cee65ba7..6d4ad07f6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -30,8 +30,9 @@ jobs: env: GOOGLE_MAPS_API_KEY: "${{ secrets.JS_MAPS_PROD_KEY }}" steps: - - name: Checkout main - uses: actions/checkout@v4 + # Credentials must persist in local git config so subsequent steps can push to origin temp-build-branch + - name: Checkout main # zizmor: ignore[artipacked] + uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 with: ref: main token: ${{ secrets.GH_MERGE_TOKEN }} @@ -42,14 +43,14 @@ jobs: git config --global user.name 'googlemaps-bot' git config --global user.email 'googlemaps-bot@google.com' - - uses: actions/cache@v3 + - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.os }}-node - - uses: actions/setup-node@v4 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: "24.18.0" @@ -57,7 +58,9 @@ jobs: - name: Get Affected Workspaces id: get_workspaces - run: bash samples/find-changes.sh ${{ github.event.before }} + env: + BEFORE_SHA: ${{ github.event.before }} + run: bash samples/find-changes.sh "$BEFORE_SHA" - name: Build Affected Projects if: steps.get_workspaces.outputs.changed_workspaces != '' @@ -81,13 +84,17 @@ jobs: - name: Get Deleted Workspaces id: get_deleted - run: bash samples/find-deleted-subfolders.sh ${{ github.event.before }} + env: + BEFORE_SHA: ${{ github.event.before }} + run: bash samples/find-deleted-subfolders.sh "$BEFORE_SHA" - name: Remove Output for Deleted Folders if: steps.get_deleted.outputs.deleted_workspaces != '' + env: + DELETED_WORKSPACES: ${{ steps.get_deleted.outputs.deleted_workspaces }} run: | IFS=$'\n' - DELETED_WORKSPACES_ARRAY=({{ steps.get_deleted.outputs.deleted_workspaces }}) + DELETED_WORKSPACES_ARRAY=(${DELETED_WORKSPACES}) echo "Removing deleted project output:" for workspace in "${DELETED_WORKSPACES_ARRAY[@]}"; do echo " - samples/$workspace" @@ -97,12 +104,13 @@ jobs: - name: Generate Index run: bash samples/generate-index.sh - - uses: google-github-actions/auth@v1 + - uses: google-github-actions/auth@c200f3691d83b41bf9bbd8638997a462592937ed # v2 with: credentials_json: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_KEY }} + # Global CLI install needed on the runner for the subsequent firebase deploy step - name: Install Firebase CLI - run: npm install -g firebase-tools + run: npm install -g firebase-tools # zizmor: ignore[adhoc-packages] - name: Deploy to Firebase Hosting run: firebase deploy --only hosting @@ -127,7 +135,7 @@ jobs: - name: Trigger Create Release Workflow if: steps.commit_and_push.outputs.changes_pushed == 'true' - uses: benc-uk/workflow-dispatch@v1 + uses: benc-uk/workflow-dispatch@e2e5e9a103e331dad343f381a29e654aea3cf8fc # v1.2.4 with: workflow: dist-pr.yml ref: "main" diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a4df0f53e..f0b88f962 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -14,6 +14,9 @@ name: Tests +permissions: + contents: read + on: pull_request: types: [opened, synchronize, edited] @@ -44,27 +47,31 @@ concurrency: jobs: pr_and_push_tests: name: Playwright PR/Push Tests - if: | + if: |- (github.event_name == 'pull_request' && github.event.pull_request.merged == false) || (github.event_name == 'push' && !contains(github.event.head_commit.message, 'chore: update dist folder')) runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 with: fetch-depth: 0 + persist-credentials: false lfs: true - - name: Get Changed Workspaces id: get_workspaces # For PRs, compare against the origin's version of the base branch. # For pushes, compare against the commit before the push. + env: + BASE_REF: ${{ github.event_name == 'pull_request' && format('origin/{0}', github.base_ref) || github.event.before }} run: | - bash samples/find-changes.sh ${{ github.event_name == 'pull_request' && format('origin/{0}', github.base_ref) || github.event.before }} + bash samples/find-changes.sh "$BASE_REF" - name: Check for changes id: check_changes + env: + CHANGED_WORKSPACES: ${{ steps.get_workspaces.outputs.changed_workspaces }} run: | - if [ "${{ steps.get_workspaces.outputs.changed_workspaces }}" != "" ]; then + if [ "$CHANGED_WORKSPACES" != "" ]; then echo "HAS_CHANGES=true" >> $GITHUB_ENV else echo "HAS_CHANGES=false" >> $GITHUB_ENV @@ -72,13 +79,13 @@ jobs: - name: Setup Node.js if: env.HAS_CHANGES == 'true' - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: "24.18.0" - name: Cache npm dependencies if: env.HAS_CHANGES == 'true' - uses: actions/cache@v4 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -94,7 +101,7 @@ jobs: - name: Cache Playwright browsers id: playwright-cache if: env.HAS_CHANGES == 'true' - uses: actions/cache@v4 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: path: ~/.cache/ms-playwright # Default Playwright cache path key: ${{ runner.os }}-playwright-${{ steps.playwright-version.outputs.version }}-${{ hashFiles('playwright.config.ts') }} @@ -106,7 +113,9 @@ jobs: - name: Install dependencies if: env.HAS_CHANGES == 'true' - run: npm ci + run: | + npm ci --include=optional + npm rebuild rollup - name: Prettier Check (Changed Files Only) if: env.HAS_CHANGES == 'true' @@ -154,7 +163,7 @@ jobs: - name: Generate Index (Run Once After Builds) run: bash samples/generate-index.sh - if: | + if: |- env.HAS_CHANGES == 'true' || contains(github.event.pull_request.paths.*, 'samples/generate-index.sh') @@ -168,7 +177,7 @@ jobs: GOOGLE_MAPS_API_KEY: "${{ secrets.JS_MAPS_DEV_KEY }}" - name: Upload Test Report Artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 if: failure() with: name: Test Results @@ -181,17 +190,17 @@ jobs: permissions: issues: write steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 with: lfs: true - + persist-credentials: false - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: "24.18.0" - name: Cache npm dependencies - uses: actions/cache@v4 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -205,7 +214,7 @@ jobs: - name: Cache Playwright browsers id: playwright-cache - uses: actions/cache@v4 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: path: ~/.cache/ms-playwright # Default Playwright cache path key: ${{ runner.os }}-playwright-${{ steps.playwright-version.outputs.version }}-${{ hashFiles('playwright.config.ts') }} @@ -214,7 +223,9 @@ jobs: ${{ runner.os }}-playwright- # Broader fallback - name: Install dependencies - run: npm ci + run: | + npm ci --include=optional + npm rebuild rollup - name: Build All Projects run: npm run build-all @@ -236,7 +247,7 @@ jobs: GOOGLE_MAPS_API_KEY: "${{ secrets.JS_MAPS_DEV_KEY }}" - name: Upload Test Report Artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 if: failure() with: name: Test Results