Skip to content
Closed
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
1 change: 1 addition & 0 deletions .bun-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1.3.14
22 changes: 10 additions & 12 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ on:
- 'eslint.config.mjs'
- 'tsconfig.json'
- 'package.json'
- 'package-lock.json'
- '.nvmrc'
- 'bun.lock'
- '.bun-version'
- '.npmrc'
- '.github/workflows/lint.yml'

Expand All @@ -22,20 +22,18 @@ jobs:
# 6.0.3
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10

# v6.1.0
- name: Setup Node
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f
# v2.2.0
- name: Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6
with:
node-version-file: .nvmrc
cache: npm
cache-dependency-path: package-lock.json
bun-version-file: .bun-version

- name: Install npm packages
run: npm ci
- name: Install packages
run: bun install --frozen-lockfile

- name: Lint
run: npm run lint
run: bun run lint

- name: Tell people how to run the failing check
if: failure()
run: echo "::error::The lint check failed! To run it locally, run \`npm ci && npm run lint\` from the GitHub-Actions repo root."
run: echo "::error::The lint check failed! To run it locally, run \`bun install && bun run lint\` from the GitHub-Actions repo root."
22 changes: 10 additions & 12 deletions .github/workflows/oxfmt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ on:
- '**.yaml'
- '.oxfmtrc.json'
- 'package.json'
- 'package-lock.json'
- '.nvmrc'
- 'bun.lock'
- '.bun-version'
- '.npmrc'
- '.github/workflows/oxfmt.yml'

Expand All @@ -25,20 +25,18 @@ jobs:
# v7
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0

- name: Setup Node
# v6.4.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e
# v2.2.0
- name: Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6
with:
node-version-file: .nvmrc
cache: npm
cache-dependency-path: package-lock.json
bun-version-file: .bun-version

- name: Install npm packages
run: npm ci
- name: Install packages
run: bun install --frozen-lockfile

- name: Check formatting with Oxfmt
run: npx oxfmt --check .
run: bunx oxfmt --check .

- name: Tell people how to run the failing check
if: failure()
run: echo "::error::The Oxfmt check failed! Run \`npm run fmt\` from the GitHub-Actions repo root and commit the changes."
run: echo "::error::The Oxfmt check failed! Run \`bun run fmt\` from the GitHub-Actions repo root and commit the changes."
64 changes: 64 additions & 0 deletions .github/workflows/releaseVerifyPeerReview.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Release peer review verifier

on:
push:
branches: [main]
paths:
- 'scripts/verifyPeerReview.ts'
- 'scripts/libs/**'
- 'package.json'
- 'bun.lock'
- '.bun-version'
- '.github/workflows/releaseVerifyPeerReview.yml'
permissions:
attestations: write
contents: write
id-token: write

concurrency:
group: release-peer-review-verifier

jobs:
release:
runs-on: blacksmith-2vcpu-ubuntu-2404
steps:
# v7.0.0
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0

# v2.2.0
- name: Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6
with:
bun-version-file: .bun-version

- name: Install packages
run: bun install --frozen-lockfile

- name: Compile native executable
run: bun run build:verify-peer-review

# v4.2.2
- name: Attest native executable
uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8
with:
subject-path: dist/verify-peer-review-linux-x64

- name: Publish GitHub Release
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
VERSION="$(bun -p "require('./package.json').version")"
readonly VERSION
TAG="verify-peer-review-v${VERSION}"
readonly TAG
if gh release view "$TAG" >/dev/null 2>&1; then
echo "::error::Release $TAG already exists. Bump package.json version before publishing a changed executable."
exit 1
fi
gh release create "$TAG" \
dist/verify-peer-review-linux-x64 \
--target "$GITHUB_SHA" \
--title "Peer review verifier v${VERSION}" \
--notes "Standalone Linux x64 executable for the peer review ruleset check."
34 changes: 22 additions & 12 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ on:
- '**/*.?[tj]s'
- 'tsconfig.json'
- 'package.json'
- 'package-lock.json'
- '.nvmrc'
- 'bun.lock'
- '.bun-version'
- '.npmrc'
- '.github/workflows/test.yml'

Expand All @@ -21,20 +21,30 @@ jobs:
# 6.0.3
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10

# v6.1.0
- name: Setup Node
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f
# v2.2.0
- name: Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6
with:
node-version-file: .nvmrc
cache: npm
cache-dependency-path: package-lock.json
bun-version-file: .bun-version

- name: Install npm packages
run: npm ci
- name: Install packages
run: bun install --frozen-lockfile

- name: Run unit tests
run: npm test
run: bun test

- name: Compile native executable
run: bun run build:verify-peer-review

- name: Smoke test native executable
run: |
set +e
OUTPUT="$(./dist/verify-peer-review-linux-x64 2>&1)"
STATUS=$?
set -e
test "$STATUS" -eq 1
grep --fixed-strings 'Missing required named argument --owner' <<< "$OUTPUT"

- name: Tell people how to run the failing check
if: failure()
run: echo "::error::The test check failed! To run it locally, run \`npm ci && npm test\` from the GitHub-Actions repo root."
run: echo "::error::The test check failed! To run it locally, run \`bun install && bun test\` from the GitHub-Actions repo root."
22 changes: 10 additions & 12 deletions .github/workflows/typecheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ on:
- '**/*.?[tj]s'
- 'tsconfig.json'
- 'package.json'
- 'package-lock.json'
- '.nvmrc'
- 'bun.lock'
- '.bun-version'
- '.npmrc'
- '.github/workflows/typecheck.yml'

Expand All @@ -21,20 +21,18 @@ jobs:
# 6.0.3
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10

# v6.1.0
- name: Setup Node
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f
# v2.2.0
- name: Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6
with:
node-version-file: .nvmrc
cache: npm
cache-dependency-path: package-lock.json
bun-version-file: .bun-version

- name: Install npm packages
run: npm ci
- name: Install packages
run: bun install --frozen-lockfile

- name: Typecheck
run: npm run typecheck
run: bun run typecheck

- name: Tell people how to run the failing check
if: failure()
run: echo "::error::The typecheck check failed! To run it locally, run \`npm ci && npm run typecheck\` from the GitHub-Actions repo root."
run: echo "::error::The typecheck check failed! To run it locally, run \`bun install && bun run typecheck\` from the GitHub-Actions repo root."
40 changes: 18 additions & 22 deletions .github/workflows/verifyPeerReview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
#
# Security model:
# - pull_request_target runs this workflow file from the base branch, not the PR head.
# - Only GitHub-Actions@main is checked out for scripts.
# - Never checkout the repo where the PR lives.
# - Only the peer-review executable compiled from GitHub-Actions@main is downloaded.
# - No repository is checked out.
#
# Thus, all code we run for the check is itself peer-reviewed, and the check can't be hacked, bypassed, or used to leak secrets.
#
Expand All @@ -16,6 +16,7 @@ on:
pull_request_target:

permissions:
attestations: read
contents: read
pull-requests: read

Expand All @@ -41,33 +42,28 @@ jobs:
permission-metadata: read
permission-pull-requests: read

# v7.0.0
- name: Checkout GitHub-Actions
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
with:
repository: Expensify/GitHub-Actions
path: GitHub-Actions

# v6.4.0
- name: Setup Node
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e
with:
node-version-file: GitHub-Actions/.nvmrc
cache: npm
cache-dependency-path: GitHub-Actions/package-lock.json

- name: Install npm packages
run: npm ci
working-directory: GitHub-Actions
- name: Download peer review verifier
run: |
set -euo pipefail
readonly RELEASE_URL="https://github.com/Expensify/GitHub-Actions/releases/download/verify-peer-review-v1.0.0"
curl --fail --location --retry 60 --retry-all-errors --retry-delay 5 \
"$RELEASE_URL/verify-peer-review-linux-x64" \
--output verify-peer-review-linux-x64
gh attestation verify verify-peer-review-linux-x64 \
--repo Expensify/GitHub-Actions \
--signer-workflow Expensify/GitHub-Actions/.github/workflows/releaseVerifyPeerReview.yml \
--source-ref refs/heads/main
chmod +x verify-peer-review-linux-x64
env:
GH_TOKEN: ${{ github.token }}

- name: Verify peer review
run: >-
npm run verify-peer-review --
./verify-peer-review-linux-x64
--owner '${{ github.event.pull_request.base.repo.owner.login }}'
--repo '${{ github.event.pull_request.base.repo.name }}'
--pull-request-number '${{ github.event.pull_request.number }}'
--target-branch '${{ github.event.pull_request.base.ref }}'
--actor-type '${{ github.event.sender.type }}'
working-directory: GitHub-Actions
env:
GITHUB_TOKEN: ${{ steps.generateAppToken.outputs.token }}
5 changes: 1 addition & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,8 @@
.vscode/
jsconfig.json

# node.js
# JavaScript
node_modules/
npm-debug.log
yarn-debug.log
yarn-error.log
dist/

# Ignore actionlint binary and any leftover directories related to installing it
Expand Down
2 changes: 1 addition & 1 deletion .oxfmtrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"sortImports": {
"ignoreCase": true
},
"ignorePatterns": ["package.json", "package-lock.json", "*.md", "*.markdown", "dist/**"],
"ignorePatterns": ["package.json", "bun.lock", "*.md", "*.markdown", "dist/**"],
"overrides": [
{
"files": ["*.yml", "*.yaml"],
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ Org-level ruleset workflow that verifies pull requests have an independent emplo

Configure it to run via an org [ruleset](#rulesets) that requires this workflow on `pull_request_target` events. See the Rulesets section below for caveats.

The check only reads GitHub pull request metadata via the API; it does not checkout or execute code from the pull request branch. It uses `pull_request_target` so the workflow YAML and scripts always run from `main`, and only `GitHub-Actions@main` is checked out.
The check only reads GitHub pull request metadata via the API; it does not checkout or execute code from the pull request branch. It uses `pull_request_target` so the workflow YAML always comes from `main`, then downloads the versioned standalone executable built from `GitHub-Actions@main`. The runner does not install Node, Bun, or npm packages.

The executable is compiled for Linux x64, attested, and published to GitHub Releases by `releaseVerifyPeerReview.yml`. The consumer verifies its build provenance against that workflow and the `main` branch. Changes to its source or dependencies must bump the package version and update the release URL in `verifyPeerReview.yml`; releases are immutable.

This workflow requires a GitHub App token with read access for repository metadata, pull requests, organization members, and branch administration. It uses the Peer Review Checker app ID `3877737` and the org secret `PEER_REVIEW_CHECKER_PRIVATE_KEY` to generate that token.

Expand Down
Loading
Loading