Skip to content

Commit ca26251

Browse files
committed
feat: Add engine compatibility check for PRs
1 parent d913c56 commit ca26251

2 files changed

Lines changed: 78 additions & 1 deletion

File tree

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
name: Node Packages Engine Compatibility Check
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
node-versions:
7+
description: 'Comma-separated Node.js versions, e.g. 22.20.0, 22, 24.0.0, 24'
8+
required: true
9+
type: string
10+
11+
permissions:
12+
contents: read
13+
pull-requests: write
14+
15+
jobs:
16+
engine-compat:
17+
name: Engine compatibility
18+
runs-on: ubuntu-24.04
19+
steps:
20+
21+
- uses: actions/checkout@v6
22+
23+
- name: Check engines and report
24+
env:
25+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
26+
NODE_VERSIONS: ${{ inputs.node-versions }}
27+
run: |
28+
export NVM_DIR="$HOME/.nvm" && . "$NVM_DIR/nvm.sh"
29+
30+
PR="${{ github.event.pull_request.number }}"
31+
MARKER="<!-- engine-compat -->"
32+
FAILED=false
33+
TABLE="| Node | Result | Incompatible Packages |\n|---|---|---|"
34+
35+
IFS=',' read -ra VERSIONS <<< "$NODE_VERSIONS"
36+
for V in "${VERSIONS[@]}"; do
37+
V=$(echo "$V" | xargs) # trim whitespace
38+
nvm install "$V" --no-progress > /dev/null 2>&1
39+
nvm use "$V" > /dev/null 2>&1
40+
VER=$(node --version)
41+
42+
PKGS=$(npm ci --dry-run 2>&1 \
43+
| awk -F"'" '/EBADENGINE.*package:/{pkg=$2} /EBADENGINE.*node:/{if(pkg){print pkg" (node "$2")"; pkg=""}}' \
44+
| sort -u | tr '\n' ',' | sed 's/,$//' | sed 's/,/, /g')
45+
46+
if [ -n "$PKGS" ]; then
47+
FAILED=true
48+
SAFE=$(echo "$PKGS" | sed 's/|/\\|/g')
49+
TABLE="$TABLE\n| $VER | ❌ Fail | $SAFE |"
50+
else
51+
TABLE="$TABLE\n| $VER | ✅ Pass | — |"
52+
fi
53+
done
54+
55+
if [ "$FAILED" = true ]; then ICON="❌"; else ICON="✅"; fi
56+
printf '%s\n## %s Engine Compatibility\n\n%b\n' "$MARKER" "$ICON" "$TABLE" > /tmp/comment.md
57+
58+
OLD=$(gh api "repos/${{ github.repository }}/issues/${PR}/comments" \
59+
--jq "[.[] | select(.body | contains(\"$MARKER\"))][0].id" 2>/dev/null || true)
60+
if [ -n "$OLD" ] && [ "$OLD" != "null" ]; then
61+
gh api --method PATCH "repos/${{ github.repository }}/issues/comments/$OLD" -F body=@/tmp/comment.md
62+
else
63+
gh pr comment "$PR" --body-file /tmp/comment.md
64+
fi
65+
66+
if [ "$FAILED" = true ]; then
67+
gh label create blocked --color D93F0B 2>/dev/null || true
68+
gh pr edit "$PR" --add-label blocked
69+
else
70+
gh pr edit "$PR" --remove-label blocked 2>/dev/null || true
71+
fi

.github/workflows/github-ci.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,14 @@ jobs:
2424
with:
2525
node-version: 22.20.0
2626

27+
- name: Engine compatibility check
28+
if: github.event_name == 'pull_request'
29+
uses: ./.github/workflows/engine-compat.yml
30+
with:
31+
node-versions: '22.20.0, 22, 24.0.0, 24'
32+
2733
- name: Install dependencies
28-
run: npm ci --engine-strict # --engine-strict is used to fail-fast if deps require node versions unsupported by the repo
34+
run: npm ci
2935

3036
- name: Check package.json "engines" consistency
3137
run: |

0 commit comments

Comments
 (0)