diff --git a/.github/workflows/build-and-push-bskyweb-aws.yaml b/.github/workflows/build-and-push-bskyweb-aws.yaml index 660498fbd3..2c8d09c776 100644 --- a/.github/workflows/build-and-push-bskyweb-aws.yaml +++ b/.github/workflows/build-and-push-bskyweb-aws.yaml @@ -22,13 +22,13 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Setup Docker buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0 - name: Log into registry ${{ env.REGISTRY }} - uses: docker/login-action@v2 + uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0 with: registry: ${{ env.REGISTRY }} username: ${{ env.USERNAME}} @@ -36,7 +36,7 @@ jobs: - name: Extract Docker metadata id: meta - uses: docker/metadata-action@v4 + uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0 with: images: | ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} @@ -51,7 +51,7 @@ jobs: - name: Build and push Docker image id: build-and-push - uses: docker/build-push-action@v4 + uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0 with: context: . push: ${{ github.event_name != 'pull_request' }} diff --git a/.github/workflows/build-and-push-bskyweb-ghcr.yaml b/.github/workflows/build-and-push-bskyweb-ghcr.yaml index c7cec477e8..693e9a1d3b 100644 --- a/.github/workflows/build-and-push-bskyweb-ghcr.yaml +++ b/.github/workflows/build-and-push-bskyweb-ghcr.yaml @@ -23,13 +23,13 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Setup Docker buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0 - name: Log into registry ${{ env.REGISTRY }} - uses: docker/login-action@v2 + uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0 with: registry: ${{ env.REGISTRY }} username: ${{ env.USERNAME }} @@ -37,7 +37,7 @@ jobs: - name: Extract Docker metadata id: meta - uses: docker/metadata-action@v4 + uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0 with: images: | ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} @@ -46,7 +46,7 @@ jobs: - name: Build and push Docker image id: build-and-push - uses: docker/build-push-action@v4 + uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0 with: context: . push: ${{ github.event_name != 'pull_request' }} diff --git a/.github/workflows/build-and-push-embedr-aws.yaml b/.github/workflows/build-and-push-embedr-aws.yaml index 4eb1c550d9..a4e1bd2c88 100644 --- a/.github/workflows/build-and-push-embedr-aws.yaml +++ b/.github/workflows/build-and-push-embedr-aws.yaml @@ -22,13 +22,13 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Setup Docker buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0 - name: Log into registry ${{ env.REGISTRY }} - uses: docker/login-action@v2 + uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0 with: registry: ${{ env.REGISTRY }} username: ${{ env.USERNAME}} @@ -36,7 +36,7 @@ jobs: - name: Extract Docker metadata id: meta - uses: docker/metadata-action@v4 + uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0 with: images: | ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} @@ -45,7 +45,7 @@ jobs: - name: Build and push Docker image id: build-and-push - uses: docker/build-push-action@v4 + uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0 with: context: . push: ${{ github.event_name != 'pull_request' }} diff --git a/.github/workflows/build-and-push-link-aws.yaml b/.github/workflows/build-and-push-link-aws.yaml index f0825fd0c9..31eaa8357f 100644 --- a/.github/workflows/build-and-push-link-aws.yaml +++ b/.github/workflows/build-and-push-link-aws.yaml @@ -22,13 +22,13 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Setup Docker buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0 - name: Log into registry ${{ env.REGISTRY }} - uses: docker/login-action@v2 + uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0 with: registry: ${{ env.REGISTRY }} username: ${{ env.USERNAME}} @@ -36,7 +36,7 @@ jobs: - name: Extract Docker metadata id: meta - uses: docker/metadata-action@v4 + uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0 with: images: | ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} @@ -45,7 +45,7 @@ jobs: - name: Build and push Docker image id: build-and-push - uses: docker/build-push-action@v4 + uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0 with: context: . push: true diff --git a/.github/workflows/build-and-push-ogcard-aws.yaml b/.github/workflows/build-and-push-ogcard-aws.yaml index 9bd14879c7..3102b05975 100644 --- a/.github/workflows/build-and-push-ogcard-aws.yaml +++ b/.github/workflows/build-and-push-ogcard-aws.yaml @@ -22,13 +22,13 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Setup Docker buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0 - name: Log into registry ${{ env.REGISTRY }} - uses: docker/login-action@v2 + uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0 with: registry: ${{ env.REGISTRY }} username: ${{ env.USERNAME}} @@ -36,7 +36,7 @@ jobs: - name: Extract Docker metadata id: meta - uses: docker/metadata-action@v4 + uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0 with: images: | ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} @@ -45,7 +45,7 @@ jobs: - name: Build and push Docker image id: build-and-push - uses: docker/build-push-action@v4 + uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0 with: context: . push: true diff --git a/.github/workflows/build-submit-android.yml b/.github/workflows/build-submit-android.yml index fe9d5b1c5b..2716942e40 100644 --- a/.github/workflows/build-submit-android.yml +++ b/.github/workflows/build-submit-android.yml @@ -11,6 +11,10 @@ on: - testflight-android - production +# Deploys happen via EAS using EXPO_TOKEN; the GITHUB_TOKEN only checks out code +permissions: + contents: read + jobs: build: if: github.repository == 'bluesky-social/social-app' @@ -28,32 +32,32 @@ jobs: fi - name: ⬇️ Checkout - uses: actions/checkout@v5 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 5 - - uses: pnpm/action-setup@v6 + - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 - name: 🔧 Setup Node - uses: actions/setup-node@v6 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: package.json cache: pnpm - name: 🪛 Setup jq - uses: dcarbone/install-jq-action@v2 + uses: dcarbone/install-jq-action@b7ef57d46ece78760b4019dbc4080a1ba2a40b45 # v3.2.0 - name: ⚙️ Install dependencies run: pnpm install --frozen-lockfile - name: 🔨 Setup Expo CLI - uses: expo/expo-github-action@v9 + uses: expo/expo-github-action@eab7a230208c952974db8c3245cfd78402c7b385 # 9.0.0 with: eas-version: '19.0.5' packager: 'pnpm --allow-build=dtrace-provider' token: ${{ secrets.EXPO_TOKEN }} - - uses: actions/setup-java@v5 + - uses: actions/setup-java@ad2b38190b15e4d6bdf0c97fb4fca8412226d287 # v5.3.0 with: distribution: "temurin" java-version: "17" @@ -98,14 +102,12 @@ jobs: - name: ⏰ Get a timestamp id: timestamp - uses: nanzm/get-time-action@master - with: - format: "MM-DD-HH-mm-ss" + run: echo "time=$(date -u +'%m-%d-%H-%M-%S')" >> "$GITHUB_OUTPUT" - name: 🚀 Upload Production Artifact id: upload-artifact-production if: ${{ inputs.profile == 'production' }} - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: retention-days: 30 compression-level: 6 @@ -115,7 +117,7 @@ jobs: - name: 🚀 Upload Testflight Artifact id: upload-artifact-testflight if: ${{ inputs.profile != 'production' }} - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: retention-days: 30 compression-level: 6 @@ -128,7 +130,7 @@ jobs: - name: 🔔 Notify Slack of Production Build if: ${{ inputs.profile == 'production' }} - uses: slackapi/slack-github-action@v3.0.3 + uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 with: webhook: ${{ secrets.SLACK_CLIENT_ALERT_WEBHOOK }} webhook-type: incoming-webhook @@ -138,7 +140,7 @@ jobs: - name: 🔔 Notify Slack of Testflight Build if: ${{ inputs.profile != 'production' }} - uses: slackapi/slack-github-action@v3.0.3 + uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 with: webhook: ${{ secrets.SLACK_CLIENT_ALERT_WEBHOOK }} webhook-type: incoming-webhook @@ -165,7 +167,7 @@ jobs: - name: 🚀 Upload Production APK Artifact id: upload-artifact-production-apk if: ${{ inputs.profile == 'production' }} - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: retention-days: 30 compression-level: 6 @@ -174,7 +176,7 @@ jobs: - name: 🔔 Notify Slack of Production APK Build if: ${{ inputs.profile == 'production' }} - uses: slackapi/slack-github-action@v3.0.3 + uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 with: webhook: ${{ secrets.SLACK_CLIENT_ALERT_WEBHOOK }} webhook-type: incoming-webhook @@ -184,7 +186,7 @@ jobs: - name: ⬇️ Restore Cache id: get-base-commit - uses: actions/cache@v5 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 if: ${{ inputs.profile == 'testflight-android' }} with: path: most-recent-testflight-commit.txt diff --git a/.github/workflows/build-submit-ios.yml b/.github/workflows/build-submit-ios.yml index d2cc7a7abb..4b13c5b03b 100644 --- a/.github/workflows/build-submit-ios.yml +++ b/.github/workflows/build-submit-ios.yml @@ -11,6 +11,10 @@ on: - testflight - production +# Deploys happen via EAS using EXPO_TOKEN; the GITHUB_TOKEN only checks out code +permissions: + contents: read + jobs: build: if: github.repository == 'bluesky-social/social-app' @@ -28,42 +32,42 @@ jobs: fi - name: ⬇️ Checkout - uses: actions/checkout@v5 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 5 - - uses: pnpm/action-setup@v6 + - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 - name: 🔧 Setup Node - uses: actions/setup-node@v6 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: package.json cache: pnpm - name: 🪛 Setup jq - uses: dcarbone/install-jq-action@v2 + uses: dcarbone/install-jq-action@b7ef57d46ece78760b4019dbc4080a1ba2a40b45 # v3.2.0 - name: ⚙️ Install dependencies run: pnpm install --frozen-lockfile - name: 🔨 Setup Expo CLI - uses: expo/expo-github-action@v9 + uses: expo/expo-github-action@eab7a230208c952974db8c3245cfd78402c7b385 # 9.0.0 with: eas-version: '19.0.5' packager: 'pnpm --allow-build=dtrace-provider' token: ${{ secrets.EXPO_TOKEN }} - - uses: maxim-lobanov/setup-xcode@v1 + - uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1.7.0 with: xcode-version: "26.4" - name: ☕️ Setup Cocoapods - uses: maxim-lobanov/setup-cocoapods@v1 + uses: maxim-lobanov/setup-cocoapods@8e97e1e98e6ccf42564fdf5622c8feec74199377 # v1.4.0 with: version: 1.16.2 - name: 💾 Cache Pods - uses: actions/cache@v5 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 id: pods-cache with: path: ./ios/Pods @@ -155,7 +159,7 @@ jobs: - name: 🔔 Notify Slack of Production Build if: ${{ inputs.profile == 'production' }} - uses: slackapi/slack-github-action@v3.0.3 + uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 with: webhook: ${{ secrets.SLACK_CLIENT_ALERT_WEBHOOK }} webhook-type: incoming-webhook @@ -165,7 +169,7 @@ jobs: - name: ⬇️ Restore Cache id: get-base-commit - uses: actions/cache@v5 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 if: ${{ inputs.profile == 'testflight' }} with: path: most-recent-testflight-commit.txt diff --git a/.github/workflows/bundle-deploy-eas-update.yml b/.github/workflows/bundle-deploy-eas-update.yml index 5f1f0a4e28..5185da34c0 100644 --- a/.github/workflows/bundle-deploy-eas-update.yml +++ b/.github/workflows/bundle-deploy-eas-update.yml @@ -18,6 +18,10 @@ on: description: Runtime version (in x.x.x format) that this update is for required: true +# Deploys happen via EAS using EXPO_TOKEN; the GITHUB_TOKEN only checks out code +permissions: + contents: read + jobs: bundleDeploy: if: github.repository == 'bluesky-social/social-app' @@ -48,7 +52,7 @@ jobs: fi - name: ⬇️ Checkout - uses: actions/checkout@v5 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 0 @@ -56,17 +60,17 @@ jobs: if: ${{ github.ref != 'refs/heads/main' }} run: git fetch origin main:main --depth 100 - - uses: pnpm/action-setup@v6 + - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 - name: 🔧 Setup Node - uses: actions/setup-node@v6 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: package.json cache: pnpm - name: 📷 Check fingerprint and install dependencies id: fingerprint - uses: bluesky-social/github-actions/fingerprint-native@main + uses: bluesky-social/github-actions/fingerprint-native@ebc6aa6d7466dc1e78b1e832041b7b81f6f95030 # v0.1.0 with: profile: ${{ inputs.channel || 'testflight' }} previous-commit-tag: ${{ inputs.runtimeVersion }} @@ -87,7 +91,7 @@ jobs: run: pnpm typecheck - name: 🔨 Setup EAS - uses: expo/expo-github-action@v9 + uses: expo/expo-github-action@eab7a230208c952974db8c3245cfd78402c7b385 # 9.0.0 if: ${{ !steps.fingerprint.outputs.includes-changes }} with: eas-version: '19.0.5' @@ -96,7 +100,7 @@ jobs: - name: 🪛 Setup jq if: ${{ !steps.fingerprint.outputs.includes-changes }} - uses: dcarbone/install-jq-action@v2 + uses: dcarbone/install-jq-action@b7ef57d46ece78760b4019dbc4080a1ba2a40b45 # v3.2.0 # eas.json not used here, set EXPO_PUBLIC_ENV - name: Env @@ -137,7 +141,7 @@ jobs: - name: ⬇️ Restore Cache id: get-base-commit - uses: actions/cache@v5 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 if: ${{ !steps.fingerprint.outputs.includes-changes }} with: path: most-recent-testflight-commit.txt @@ -167,20 +171,20 @@ jobs: fi - name: ⬇️ Checkout - uses: actions/checkout@v5 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 5 - - uses: pnpm/action-setup@v6 + - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 - name: 🔧 Setup Node - uses: actions/setup-node@v6 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: package.json cache: pnpm - name: 🔨 Setup EAS - uses: expo/expo-github-action@v9 + uses: expo/expo-github-action@eab7a230208c952974db8c3245cfd78402c7b385 # 9.0.0 with: eas-version: '19.0.5' packager: 'pnpm --allow-build=dtrace-provider' @@ -189,17 +193,17 @@ jobs: - name: ⚙️ Install dependencies run: pnpm install --frozen-lockfile - - uses: maxim-lobanov/setup-xcode@v1 + - uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1.7.0 with: xcode-version: "26.4" - name: ☕️ Setup Cocoapods - uses: maxim-lobanov/setup-cocoapods@v1 + uses: maxim-lobanov/setup-cocoapods@8e97e1e98e6ccf42564fdf5622c8feec74199377 # v1.4.0 with: version: 1.16.2 - name: 💾 Cache Pods - uses: actions/cache@v5 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 id: pods-cache with: path: ./ios/Pods @@ -282,7 +286,7 @@ jobs: - name: ⬇️ Restore Cache id: get-base-commit - uses: actions/cache@v5 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 if: ${{ inputs.channel == 'testflight' }} with: path: most-recent-testflight-commit.txt @@ -314,26 +318,26 @@ jobs: fi - name: ⬇️ Checkout - uses: actions/checkout@v5 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 5 - - uses: pnpm/action-setup@v6 + - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 - name: 🔧 Setup Node - uses: actions/setup-node@v6 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: package.json cache: pnpm - name: 🔨 Setup EAS - uses: expo/expo-github-action@v9 + uses: expo/expo-github-action@eab7a230208c952974db8c3245cfd78402c7b385 # 9.0.0 with: eas-version: '19.0.5' packager: 'pnpm --allow-build=dtrace-provider' token: ${{ secrets.EXPO_TOKEN }} - - uses: actions/setup-java@v5 + - uses: actions/setup-java@ad2b38190b15e4d6bdf0c97fb4fca8412226d287 # v5.3.0 with: distribution: "temurin" java-version: "17" @@ -372,13 +376,11 @@ jobs: - name: ⏰ Get a timestamp id: timestamp - uses: nanzm/get-time-action@master - with: - format: "MM-DD-HH-mm-ss" + run: echo "time=$(date -u +'%m-%d-%H-%M-%S')" >> "$GITHUB_OUTPUT" - name: 🚀 Upload Artifact id: upload-artifact - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: retention-days: 30 compression-level: 0 @@ -386,7 +388,7 @@ jobs: path: build.apk - name: 🔔 Notify Slack - uses: slackapi/slack-github-action@v3.0.3 + uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 with: webhook: ${{ secrets.SLACK_CLIENT_ALERT_WEBHOOK }} webhook-type: incoming-webhook @@ -396,7 +398,7 @@ jobs: - name: ⬇️ Restore Cache id: get-base-commit - uses: actions/cache@v5 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 if: ${{ inputs.channel != 'testflight' && inputs.channel != 'production' }} with: path: most-recent-testflight-commit.txt diff --git a/.github/workflows/claude-mention.yml b/.github/workflows/claude-mention.yml index 355a05adfb..5a7a7accff 100644 --- a/.github/workflows/claude-mention.yml +++ b/.github/workflows/claude-mention.yml @@ -54,18 +54,18 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 1 - name: Configure AWS credentials (OIDC) - uses: aws-actions/configure-aws-credentials@v6 + uses: aws-actions/configure-aws-credentials@e7f100cf4c008499ea8adda475de1042d6975c7b # v6.2.0 with: role-to-assume: ${{ secrets.AWS_BEDROCK_REVIEW_ROLE_ARN }} aws-region: us-east-2 - name: Claude - uses: anthropics/claude-code-action@v1 + uses: anthropics/claude-code-action@4d7e1f0cd85743fdc93b1c8040ab54395da024e2 # v1.0.149 with: use_bedrock: 'true' additional_permissions: | diff --git a/.github/workflows/claude-review.yml b/.github/workflows/claude-review.yml index 9b7cdaa57d..3f6078219c 100644 --- a/.github/workflows/claude-review.yml +++ b/.github/workflows/claude-review.yml @@ -40,18 +40,18 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 1 - name: Configure AWS credentials (OIDC) - uses: aws-actions/configure-aws-credentials@v6 + uses: aws-actions/configure-aws-credentials@e7f100cf4c008499ea8adda475de1042d6975c7b # v6.2.0 with: role-to-assume: ${{ secrets.AWS_BEDROCK_REVIEW_ROLE_ARN }} aws-region: us-east-2 - name: Claude review - uses: anthropics/claude-code-action@v1 + uses: anthropics/claude-code-action@4d7e1f0cd85743fdc93b1c8040ab54395da024e2 # v1.0.149 with: use_bedrock: 'true' additional_permissions: | diff --git a/.github/workflows/golang-test-lint.yml b/.github/workflows/golang-test-lint.yml index 2e7388bbd5..d61f0c153d 100644 --- a/.github/workflows/golang-test-lint.yml +++ b/.github/workflows/golang-test-lint.yml @@ -10,14 +10,17 @@ concurrency: group: "${{ github.workflow }}-${{ github.head_ref || github.ref }}" cancel-in-progress: true +permissions: + contents: read + jobs: build-and-test: runs-on: ubuntu-latest steps: - name: Git Checkout - uses: actions/checkout@v5 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Set up Go tooling - uses: actions/setup-go@v6 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: go-version-file: bskyweb/go.mod cache-dependency-path: bskyweb/go.sum @@ -33,9 +36,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Git Checkout - uses: actions/checkout@v5 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Set up Go tooling - uses: actions/setup-go@v6 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: go-version-file: bskyweb/go.mod cache-dependency-path: bskyweb/go.sum diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 2fb464a92a..5b40ad541d 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -24,7 +24,7 @@ jobs: job: [lint, prettier, typecheck] steps: - name: Check out Git repository - uses: actions/checkout@v5 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Verify Node version pins match package.json run: | set -euo pipefail @@ -50,9 +50,9 @@ jobs: v=$(grep -oE '"node":[[:space:]]*"[0-9]+\.[0-9]+\.[0-9]+"' eas.json | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | sort -u) check "eas.json" "$v" exit $rc - - uses: pnpm/action-setup@v6 + - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 - name: Install node - uses: actions/setup-node@v6 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: package.json cache: pnpm @@ -87,10 +87,10 @@ jobs: shard: [1, 2, 3, 4] steps: - name: Check out Git repository - uses: actions/checkout@v5 - - uses: pnpm/action-setup@v6 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 - name: Install node - uses: actions/setup-node@v6 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: package.json cache: pnpm diff --git a/.github/workflows/nightly-update-source-languages.yaml b/.github/workflows/nightly-update-source-languages.yaml index 2a6ec26ac4..e6094476a6 100644 --- a/.github/workflows/nightly-update-source-languages.yaml +++ b/.github/workflows/nightly-update-source-languages.yaml @@ -16,12 +16,12 @@ jobs: steps: - name: Check out Git repository - uses: actions/checkout@v5 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ssh-key: ${{secrets.GH_ACTION_DEPLOY_KEY}} - - uses: pnpm/action-setup@v6 + - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 - name: Install node - uses: actions/setup-node@v6 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: package.json cache: pnpm @@ -30,12 +30,12 @@ jobs: - name: Extract language strings run: pnpm intl:extract - name: Create commit - uses: stefanzweifel/git-auto-commit-action@v5 + uses: stefanzweifel/git-auto-commit-action@04702edda442b2e678b25b537cec683a1493fcb9 # v7.1.0 with: commit_message: Nightly source-language update file_pattern: ./src/locale/locales/en/messages.po - name: Push source lang to Crowdin - uses: crowdin/github-action@v2 + uses: crowdin/github-action@52aa776766211d83d975df51f3b9c53c2f8ba35f # v2.16.3 with: upload_sources: true upload_sources_args: "-b main" diff --git a/.github/workflows/pull-request-comment.yml b/.github/workflows/pull-request-comment.yml index 8ede462392..4f152f96f1 100644 --- a/.github/workflows/pull-request-comment.yml +++ b/.github/workflows/pull-request-comment.yml @@ -5,16 +5,15 @@ on: issue_comment: types: [created] -# Permissiosn to make comments in the pull request -permissions: - pull-requests: write - actions: write - contents: read +# Permissions are granted per-job below; anything unlisted defaults to none +permissions: {} jobs: handle-comment: if: github.event.issue.pull_request runs-on: ubuntu-latest + permissions: + contents: read outputs: should-deploy: ${{ steps.check-org.outputs.result }} @@ -45,10 +44,10 @@ jobs: echo "mentioned=false" >> $GITHUB_OUTPUT fi - - name: Check organization membership + - name: Check commenter has write access if: steps.check-mention.outputs.mentioned == 'true' id: check-org - uses: actions/github-script@v7 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | try { @@ -72,13 +71,16 @@ jobs: runs-on: ubuntu-latest needs: [handle-comment] if: needs.handle-comment.outputs.should-deploy == 'true' + permissions: + contents: read + pull-requests: write steps: - name: Get PR HEAD SHA env: ISSUE_NUMBER: ${{ github.event.issue.number }} id: pr-info - uses: actions/github-script@v7 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | const pr = await github.rest.pulls.get({ @@ -87,6 +89,16 @@ jobs: pull_number: process.env.ISSUE_NUMBER, }); + // This workflow runs with repo secrets in scope, so never build + // code from a fork: the commenter authorizes the deploy, but a + // fork controls what code would run during it + const expected = `${context.repo.owner}/${context.repo.repo}`; + const head = pr.data.head.repo?.full_name; + if (head !== expected) { + core.setFailed(`OTA deploys are only allowed for branches in ${expected}, not forks (got ${head})`); + return; + } + console.log(`PR HEAD SHA: ${pr.data.head.sha}`); console.log(`PR HEAD REF: ${pr.data.head.ref}`); @@ -94,7 +106,7 @@ jobs: core.setOutput('head-ref', pr.data.head.ref); - name: 💬 Drop a comment - uses: marocchino/sticky-pull-request-comment@v3 + uses: marocchino/sticky-pull-request-comment@0ea0beb66eb9baf113663a64ec522f60e49231c0 # v3.0.4 with: header: pull-request-eas-build-${{ steps.pr-info.outputs.head-sha }} number: ${{ github.event.issue.number }} @@ -113,14 +125,14 @@ jobs: fi - name: ⬇️ Checkout - uses: actions/checkout@v5 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ steps.pr-info.outputs.head-sha }} - - uses: pnpm/action-setup@v6 + - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 - name: 🔧 Setup Node - uses: actions/setup-node@v6 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: package.json cache: pnpm @@ -141,14 +153,14 @@ jobs: run: pnpm typecheck - name: 🔨 Setup EAS - uses: expo/expo-github-action@v9 + uses: expo/expo-github-action@eab7a230208c952974db8c3245cfd78402c7b385 # 9.0.0 with: eas-version: '19.0.5' packager: 'pnpm --allow-build=dtrace-provider' token: ${{ secrets.EXPO_TOKEN }} - name: 🪛 Setup jq - uses: dcarbone/install-jq-action@v2 + uses: dcarbone/install-jq-action@b7ef57d46ece78760b4019dbc4080a1ba2a40b45 # v3.2.0 - name: Env id: env @@ -181,7 +193,7 @@ jobs: RUNTIME_VERSION: - name: 💬 Drop a comment - uses: marocchino/sticky-pull-request-comment@v3 + uses: marocchino/sticky-pull-request-comment@0ea0beb66eb9baf113663a64ec522f60e49231c0 # v3.0.4 env: ISSUE_NUMBER: ${{ github.event.issue.number }} with: @@ -198,7 +210,7 @@ jobs: *Generated by [PR labeler](https://github.com/expo/expo/actions/workflows/pr-labeler.yml) 🤖* - name: 💬 Drop a comment - uses: marocchino/sticky-pull-request-comment@v3 + uses: marocchino/sticky-pull-request-comment@0ea0beb66eb9baf113663a64ec522f60e49231c0 # v3.0.4 if: failure() with: header: pull-request-eas-build-${{ steps.pr-info.outputs.head-sha }} diff --git a/.github/workflows/pull-request-commit.yml b/.github/workflows/pull-request-commit.yml index 976fa35662..df8a69c188 100644 --- a/.github/workflows/pull-request-commit.yml +++ b/.github/workflows/pull-request-commit.yml @@ -13,25 +13,28 @@ concurrency: group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }} cancel-in-progress: true -permissions: - pull-requests: write - actions: write - contents: read +# Permissions are granted per-job below; anything unlisted defaults to none. +# pull-requests: write is needed by sticky-pull-request-comment to post the +# bundle-size and fingerprint diffs +permissions: {} jobs: webpack-analyzer: runs-on: ubuntu-22.04 if: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.event_name == 'pull_request'}} + permissions: + contents: read + pull-requests: write steps: - name: ⬇️ Checkout - uses: actions/checkout@v5 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 0 - - uses: pnpm/action-setup@v6 + - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 - name: 🔧 Setup Node - uses: actions/setup-node@v6 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: package.json cache: pnpm @@ -68,7 +71,7 @@ jobs: - name: ⬇️ Get base stats from cache id: get-base-stats - uses: actions/cache@v5 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: path: stats-base.json key: stats-base-${{ steps.base-commit.outputs.base-commit }} @@ -89,14 +92,14 @@ jobs: - name: % Get diff id: get-diff - uses: NejcZdovc/bundle-size-diff@v1 + uses: NejcZdovc/bundle-size-diff@5321de41d2d62a7b0f4d6e60f59d1280a0034160 # v1.1.0 with: base_path: "stats-base.json" pr_path: "../stats-new.json" excluded_assets: "(.+).chunk.js|(.+).js.map|(.+).json|(.+).png|(.+).svg|(.+).webp|(.+).jpg|(.+).ico" - name: 💬 Drop a comment - uses: marocchino/sticky-pull-request-comment@v3 + uses: marocchino/sticky-pull-request-comment@0ea0beb66eb9baf113663a64ec522f60e49231c0 # v3.0.4 with: header: bundle-diff message: | @@ -108,9 +111,12 @@ jobs: fingerprint-native: runs-on: ubuntu-22.04 if: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.event_name == 'pull_request'}} + permissions: + contents: read + pull-requests: write steps: - name: ⬇️ Checkout - uses: actions/checkout@v5 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 100 @@ -118,22 +124,22 @@ jobs: run: git fetch origin main:main --depth 100 if: github.event_name == 'pull_request' - - uses: pnpm/action-setup@v6 + - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 - name: 🔧 Setup Node - uses: actions/setup-node@v6 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: package.json cache: pnpm - name: 📷 Check fingerprint and install dependencies id: fingerprint - uses: bluesky-social/github-actions/fingerprint-native@main + uses: bluesky-social/github-actions/fingerprint-native@ebc6aa6d7466dc1e78b1e832041b7b81f6f95030 # v0.1.0 with: profile: pull-request - name: 💬 Drop a comment - uses: marocchino/sticky-pull-request-comment@v3 + uses: marocchino/sticky-pull-request-comment@0ea0beb66eb9baf113663a64ec522f60e49231c0 # v3.0.4 if: ${{ steps.fingerprint.outputs.includes-changes }} with: header: fingerprint-diff @@ -151,7 +157,7 @@ jobs: *Generated by [PR labeler](https://github.com/expo/expo/actions/workflows/pr-labeler.yml) 🤖* - name: 💬 Delete comment - uses: marocchino/sticky-pull-request-comment@v3 + uses: marocchino/sticky-pull-request-comment@0ea0beb66eb9baf113663a64ec522f60e49231c0 # v3.0.4 if: ${{ !steps.fingerprint.outputs.includes-changes }} with: header: fingerprint-diff diff --git a/.github/workflows/sync-internal.yaml b/.github/workflows/sync-internal.yaml index 03120eaebc..3b07ae2b90 100644 --- a/.github/workflows/sync-internal.yaml +++ b/.github/workflows/sync-internal.yaml @@ -4,22 +4,29 @@ on: push: branches: [main] +# The push to the internal repo uses the app token below, not the GITHUB_TOKEN +permissions: + contents: read + jobs: sync: runs-on: ubuntu-latest if: github.repository == 'bluesky-social/social-app' steps: - name: Checkout public repo - uses: actions/checkout@v5 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 0 - name: Generate GitHub App Token id: app-token - uses: actions/create-github-app-token@v3 + uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 with: app-id: ${{ vars.SYNC_INTERNAL_APP_ID }} private-key: ${{ secrets.SYNC_INTERNAL_PK }} repositories: social-app-internal + # Scope the token down from the app's full installation permissions; + # pushing is the only thing this token is used for + permission-contents: write - name: Push to internal repo env: TOKEN: ${{ steps.app-token.outputs.token }} diff --git a/.github/workflows/verify-pnpm-lock.yml b/.github/workflows/verify-pnpm-lock.yml index f1b61e95e7..cb68e2b4e7 100644 --- a/.github/workflows/verify-pnpm-lock.yml +++ b/.github/workflows/verify-pnpm-lock.yml @@ -6,13 +6,16 @@ concurrency: group: "${{ github.workflow }}-${{ github.head_ref || github.ref }}" cancel-in-progress: true +permissions: + contents: read + jobs: verify-pnpm-lock: name: No manual pnpm-lock.yaml edits runs-on: ubuntu-latest steps: - name: Check out PR HEAD - uses: actions/checkout@v5 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 0 @@ -21,10 +24,10 @@ jobs: BASE_REF: ${{ github.base_ref }} run: git fetch origin $BASE_REF --depth=1 - - uses: pnpm/action-setup@v6 + - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 - name: Install node - uses: actions/setup-node@v6 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: package.json diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml new file mode 100644 index 0000000000..56d06bbd85 --- /dev/null +++ b/.github/workflows/zizmor.yml @@ -0,0 +1,37 @@ +name: Workflow security + +on: + push: + branches: [main] + paths: [".github/**"] + pull_request: + paths: [".github/**"] + +concurrency: + group: "${{ github.workflow }}-${{ github.head_ref || github.ref }}" + cancel-in-progress: true + +# The github.token is only used by zizmor's online audits (read-only API calls) +permissions: + contents: read + +jobs: + zizmor: + name: Audit workflows with zizmor + runs-on: ubuntu-latest + steps: + - name: Check out Git repository + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false + + - name: Run zizmor + uses: zizmorcore/zizmor-action@5f14fd08f7cf1cb1609c1e344975f152c7ee938d # v0.5.6 + with: + # Annotate the PR directly instead of uploading SARIF to the + # security tab, and fail the check on any finding + advanced-security: false + annotations: true + # Low-confidence findings (e.g. artipacked on workflows that never + # push) are too noisy to gate CI on + min-confidence: medium diff --git a/package.json b/package.json index 7d61fb5264..a543300494 100644 --- a/package.json +++ b/package.json @@ -90,7 +90,8 @@ "generate-webpack-stats-file": "EXPO_PUBLIC_GENERATE_STATS=1 pnpm build-web", "open-analyzer": "EXPO_PUBLIC_OPEN_ANALYZER=1 pnpm build-web", "icons:optimize": "svgo -f ./assets/icons", - "prettier": "prettier --check ." + "prettier": "prettier --check .", + "update-actions": "pnpm dlx actions-up --min-age 7" }, "dependencies": { "@atproto/api": "0.20.15",