Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 57 additions & 29 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,49 +1,81 @@
name: CI
# SECURITY NOTE: This workflow uses pull_request_target which has access to secrets.
# This is needed because tests require access to external services with credentials.
# `pull_request_target` will always run without manual approval, even if "Require approval for all external contributors" is enabled in the repo settings.
# Therefore we implement a "safe to test" label that must be manually added once we have checked that the diff is safe.
# For PRs from forks, secrets are only provided when the "safe to test" label is present.
# This allows maintainers to safely test external contributions while preventing
# malicious actors from accessing secrets.
# SECURITY: Uses environment protection for external PRs instead of unsafe "safe to test" labels.
# Environment protection provides secure manual approval tied to specific commits,
# eliminating race conditions and ensuring maintainer review before secrets access.
on:
push:
branches: [main]
paths-ignore:
- "**.md"
- ".changeset/**"
pull_request_target:
types: [opened, synchronize, reopened, labeled]
types: [opened, synchronize, reopened]
paths-ignore:
- "**.md"
- ".changeset/**"
pull_request:
types: [opened, synchronize, reopened]
paths:
- .github/workflows/ci.yml
paths-ignore:
- "**.md"
- ".changeset/**"

concurrency: ${{ github.workflow }}--${{ github.ref }}
concurrency:
group: ${{ github.workflow }}--${{ github.event_name == 'pull_request_target' && format('pr#{0}', github.event.pull_request.number) || github.ref }}
cancel-in-progress: true

permissions:
pull-requests: write
contents: read
pull-requests: read

jobs:
main:
name: Node.js 20
# Basic validation job - runs for all PRs without secrets
basic-validation:
name: Build and lint
runs-on: ubuntu-latest
# Only run tests with secrets if:
# 1. This is a push to main, OR
# 2. PR is from the same repository (trusted), OR
# 3. PR has the "safe to test" label (maintainer approved)
if: github.event_name == 'pull_request'

steps:
- name: Checkout sources
uses: actions/checkout@v4

- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 20.x
cache: npm
cache-dependency-path: package-lock.json

- name: Install dependencies
run: npm ci --no-fund --no-audit

- name: Build
run: npm run build

- name: Check formatting
run: npm run format:check

- name: Run linters
run: npm run lint

# Integration tests with secrets - requires approval for external PRs
tests:
name: Tests
runs-on: ubuntu-latest
# SECURITY: Use environment protection for external contributors
environment: ${{ github.event.pull_request.head.repo.full_name != github.repository && 'external-testing' || '' }}
# Run tests with secrets for:
# 1. Push to main (trusted), OR
# 2. PR from same repository (trusted)
# For external PRs: environment protection requires manual approval
if: |
github.event_name == 'push' ||
github.event.pull_request.head.repo.full_name == github.repository ||
contains(github.event.pull_request.labels.*.name, 'safe to test')
github.event_name == 'push' ||
(github.event.pull_request.head.repo.full_name == github.repository)

steps:
- name: Checkout sources
uses: actions/checkout@v4
with:
# Environment protection provides security - we can safely checkout PR code
ref: ${{ github.event.pull_request.head.sha || github.sha }}

- name: Decrypt keyfile
Expand All @@ -52,22 +84,18 @@ jobs:
KEYFILE_PASSPHRASE: ${{secrets.KEYFILE_PASSPHRASE}}

- name: Install Node.js
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: 20.19
node-version: 20.x
cache: npm
cache-dependency-path: package-lock.json

- name: Install dependencies
run: npm ci --no-fund --no-audit

- name: Build
run: npm run build

- name: Check formatting
run: npm run format:check

- name: Run linters
run: npm run lint

- name: Run tests
run: npm run test
env:
Expand Down
1 change: 0 additions & 1 deletion bb.test

This file was deleted.