diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index 6744b0bc8..f1931e1a5 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -22,12 +22,12 @@ runs: echo "version=$version" >> "$GITHUB_OUTPUT" - name: Setup Bun - uses: oven-sh/setup-bun@v2 + uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 with: bun-version: ${{ steps.bun-version.outputs.version }} - name: Cache dependencies - uses: actions/cache@v4 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: path: ~/.bun/install/cache key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }} diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..b7ff8b381 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,23 @@ +version: 2 + +updates: + # Keep the SHA-pinned actions fresh across the CI workflows and every local + # composite action. Dependabot rewrites both the commit SHA and the trailing + # `# vX.Y.Z` comment, grouped into a single weekly PR. + # + # `directories` (plural) is required for the glob: `directory: /` only scans + # .github/workflows, and the singular key supports no wildcards. The `*` + # matches each local action's directory (.github/actions//action.yml); + # `**` is avoided on purpose — it has a duplicate-PR bug for github-actions. + - package-ecosystem: github-actions + directories: + - '/' # .github/workflows + - '/.github/actions/*' # every local composite action's action.yml + schedule: + interval: weekly + groups: + github-actions: + patterns: + - '*' + commit-message: + prefix: '[ci]' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index be74a2444..649dd5e23 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ jobs: runs-on: blacksmith-4vcpu-ubuntu-2404 steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - name: Set up Bun and install dependencies uses: ./.github/actions/setup @@ -27,7 +27,7 @@ jobs: run: NEXT_PUBLIC_SITE=diffshub bun ws docs build - name: Upload build artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: build-output path: | @@ -42,13 +42,13 @@ jobs: needs: build steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - name: Set up Bun and install dependencies uses: ./.github/actions/setup - name: Download build artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 with: name: build-output @@ -61,7 +61,7 @@ jobs: needs: build steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - name: Set up Bun and install dependencies uses: ./.github/actions/setup @@ -75,7 +75,7 @@ jobs: needs: build steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - name: Set up Bun and install dependencies uses: ./.github/actions/setup @@ -89,13 +89,13 @@ jobs: needs: build steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - name: Set up Bun and install dependencies uses: ./.github/actions/setup - name: Download build artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 with: name: build-output @@ -103,7 +103,7 @@ jobs: run: bun ws "packages/*" test --sequential - name: Mount Playwright browsers - uses: useblacksmith/stickydisk@v1 + uses: useblacksmith/stickydisk@13af8883542ca949a717e70fef89d15edbb29d88 # v1.2.0 with: key: ${{ github.repository }}-playwright-browsers-${{ runner.os }} path: ~/.cache/ms-playwright @@ -119,15 +119,42 @@ jobs: needs: build steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - name: Set up Bun and install dependencies uses: ./.github/actions/setup - name: Download build artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 with: name: build-output - name: Type check all workspaces run: bun run ws "*" tsc + + actions-pinned: + name: Actions pinned to SHA + runs-on: blacksmith-4vcpu-ubuntu-2404 + steps: + - name: Checkout code + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + + - name: Verify external actions are pinned to a full commit SHA + run: | + # Supply-chain guard: every external action must be pinned to a + # 40-character commit SHA, never a movable tag/branch. Local actions + # (uses: ./...) ship with the repo and are exempt. Scans the workflows + # and the shared composite action manifest alike. + set -euo pipefail + unpinned=$( + grep -rEn '^[[:space:]]*-?[[:space:]]*uses:[[:space:]]*[^.[:space:]]' .github \ + | grep -vE 'uses:[[:space:]]*[^[:space:]]+@[0-9a-fA-F]{40}([[:space:]]|#|"|'"'"'|$)' \ + || true + ) + if [ -n "$unpinned" ]; then + echo "::error::These actions are not pinned to a full commit SHA:" + echo "$unpinned" + echo "Pin each to a 40-character commit SHA, e.g. owner/repo@ # vX.Y.Z" + exit 1 + fi + echo "All external actions are pinned to a full commit SHA."