CI: scope heavy jobs, build once, and remove duplicate validation work (#11570)
* CI: scope jobs and reuse build artifacts * CI: fix scope fallback and remove unused artifact job * CI: remove setup-node pnpm cache inputs * CI: add pnpm store cache and dist artifact smoke * CI: extract pnpm cache action and consume dist artifact
This commit is contained in:
committed by
GitHub
parent
b75d618080
commit
cef9bfce22
41
.github/actions/setup-pnpm-store-cache/action.yml
vendored
Normal file
41
.github/actions/setup-pnpm-store-cache/action.yml
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
name: Setup pnpm + store cache
|
||||||
|
description: Prepare pnpm via corepack and restore pnpm store cache.
|
||||||
|
inputs:
|
||||||
|
pnpm-version:
|
||||||
|
description: pnpm version to activate via corepack.
|
||||||
|
required: false
|
||||||
|
default: "10.23.0"
|
||||||
|
cache-key-suffix:
|
||||||
|
description: Suffix appended to the cache key.
|
||||||
|
required: false
|
||||||
|
default: "node22"
|
||||||
|
runs:
|
||||||
|
using: composite
|
||||||
|
steps:
|
||||||
|
- name: Setup pnpm (corepack retry)
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
corepack enable
|
||||||
|
for attempt in 1 2 3; do
|
||||||
|
if corepack prepare "pnpm@${{ inputs.pnpm-version }}" --activate; then
|
||||||
|
pnpm -v
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
echo "corepack prepare failed (attempt $attempt/3). Retrying..."
|
||||||
|
sleep $((attempt * 10))
|
||||||
|
done
|
||||||
|
exit 1
|
||||||
|
|
||||||
|
- name: Resolve pnpm store path
|
||||||
|
id: pnpm-store
|
||||||
|
shell: bash
|
||||||
|
run: echo "path=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
- name: Restore pnpm store cache
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ${{ steps.pnpm-store.outputs.path }}
|
||||||
|
key: ${{ runner.os }}-pnpm-store-${{ inputs.cache-key-suffix }}-${{ hashFiles('pnpm-lock.yaml') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-pnpm-store-${{ inputs.cache-key-suffix }}-
|
||||||
272
.github/workflows/ci.yml
vendored
272
.github/workflows/ci.yml
vendored
@@ -27,9 +27,101 @@ jobs:
|
|||||||
id: check
|
id: check
|
||||||
uses: ./.github/actions/detect-docs-only
|
uses: ./.github/actions/detect-docs-only
|
||||||
|
|
||||||
install-check:
|
# Detect which heavy areas are touched so PRs can skip unrelated expensive jobs.
|
||||||
|
# Push to main keeps broad coverage.
|
||||||
|
changed-scope:
|
||||||
needs: [docs-scope]
|
needs: [docs-scope]
|
||||||
if: needs.docs-scope.outputs.docs_only != 'true'
|
if: needs.docs-scope.outputs.docs_only != 'true'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
run_node: ${{ steps.scope.outputs.run_node }}
|
||||||
|
run_macos: ${{ steps.scope.outputs.run_macos }}
|
||||||
|
run_android: ${{ steps.scope.outputs.run_android }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
submodules: false
|
||||||
|
|
||||||
|
- name: Detect changed scopes
|
||||||
|
id: scope
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if [ "${{ github.event_name }}" = "push" ]; then
|
||||||
|
BASE="${{ github.event.before }}"
|
||||||
|
else
|
||||||
|
BASE="${{ github.event.pull_request.base.sha }}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
CHANGED="$(git diff --name-only "$BASE" HEAD 2>/dev/null || echo "UNKNOWN")"
|
||||||
|
if [ "$CHANGED" = "UNKNOWN" ] || [ -z "$CHANGED" ]; then
|
||||||
|
# Fail-safe: run broad checks if detection fails.
|
||||||
|
echo "run_node=true" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "run_macos=true" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "run_android=true" >> "$GITHUB_OUTPUT"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
run_node=false
|
||||||
|
run_macos=false
|
||||||
|
run_android=false
|
||||||
|
has_non_docs=false
|
||||||
|
has_non_native_non_docs=false
|
||||||
|
|
||||||
|
while IFS= read -r path; do
|
||||||
|
[ -z "$path" ] && continue
|
||||||
|
case "$path" in
|
||||||
|
docs/*|*.md|*.mdx)
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
has_non_docs=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "$path" in
|
||||||
|
apps/macos/*|apps/ios/*|apps/shared/*|Swabble/*)
|
||||||
|
run_macos=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "$path" in
|
||||||
|
apps/android/*|apps/shared/*)
|
||||||
|
run_android=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "$path" in
|
||||||
|
src/*|test/*|extensions/*|packages/*|scripts/*|ui/*|.github/*|openclaw.mjs|package.json|pnpm-lock.yaml|pnpm-workspace.yaml|tsconfig*.json|vitest*.ts|tsdown.config.ts|.oxlintrc.json|.oxfmtrc.jsonc)
|
||||||
|
run_node=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "$path" in
|
||||||
|
apps/android/*|apps/ios/*|apps/macos/*|apps/shared/*|Swabble/*|appcast.xml)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
has_non_native_non_docs=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done <<< "$CHANGED"
|
||||||
|
|
||||||
|
# If there are non-doc files outside native app trees, keep Node checks enabled.
|
||||||
|
if [ "$run_node" = false ] && [ "$has_non_docs" = true ] && [ "$has_non_native_non_docs" = true ]; then
|
||||||
|
run_node=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "run_node=${run_node}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "run_macos=${run_macos}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "run_android=${run_android}" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
# Build dist once for Node-relevant changes and share it with downstream jobs.
|
||||||
|
build-artifacts:
|
||||||
|
needs: [docs-scope, changed-scope]
|
||||||
|
if: needs.docs-scope.outputs.docs_only != 'true' && (github.event_name == 'push' || needs.changed-scope.outputs.run_node == 'true')
|
||||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
@@ -56,20 +148,76 @@ jobs:
|
|||||||
node-version: 22.x
|
node-version: 22.x
|
||||||
check-latest: true
|
check-latest: true
|
||||||
|
|
||||||
- name: Setup pnpm (corepack retry)
|
- name: Setup pnpm + cache store
|
||||||
|
uses: ./.github/actions/setup-pnpm-store-cache
|
||||||
|
with:
|
||||||
|
pnpm-version: "10.23.0"
|
||||||
|
cache-key-suffix: "node22"
|
||||||
|
|
||||||
|
- name: Runtime versions
|
||||||
|
run: |
|
||||||
|
node -v
|
||||||
|
npm -v
|
||||||
|
pnpm -v
|
||||||
|
|
||||||
|
- name: Capture node path
|
||||||
|
run: echo "NODE_BIN=$(dirname \"$(node -p \"process.execPath\")\")" >> "$GITHUB_ENV"
|
||||||
|
|
||||||
|
- name: Install dependencies (frozen)
|
||||||
|
env:
|
||||||
|
CI: true
|
||||||
|
run: |
|
||||||
|
export PATH="$NODE_BIN:$PATH"
|
||||||
|
which node
|
||||||
|
node -v
|
||||||
|
pnpm -v
|
||||||
|
pnpm install --frozen-lockfile --ignore-scripts=false --config.engine-strict=false --config.enable-pre-post-scripts=true
|
||||||
|
|
||||||
|
- name: Build dist
|
||||||
|
run: pnpm build
|
||||||
|
|
||||||
|
- name: Upload dist artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: dist-build
|
||||||
|
path: dist/
|
||||||
|
retention-days: 1
|
||||||
|
|
||||||
|
install-check:
|
||||||
|
needs: [docs-scope, changed-scope]
|
||||||
|
if: needs.docs-scope.outputs.docs_only != 'true' && (github.event_name == 'push' || needs.changed-scope.outputs.run_node == 'true')
|
||||||
|
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: false
|
||||||
|
|
||||||
|
- name: Checkout submodules (retry)
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
corepack enable
|
git submodule sync --recursive
|
||||||
for attempt in 1 2 3; do
|
for attempt in 1 2 3 4 5; do
|
||||||
if corepack prepare pnpm@10.23.0 --activate; then
|
if git -c protocol.version=2 submodule update --init --force --depth=1 --recursive; then
|
||||||
pnpm -v
|
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
echo "corepack prepare failed (attempt $attempt/3). Retrying..."
|
echo "Submodule update failed (attempt $attempt/5). Retrying…"
|
||||||
sleep $((attempt * 10))
|
sleep $((attempt * 10))
|
||||||
done
|
done
|
||||||
exit 1
|
exit 1
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 22.x
|
||||||
|
check-latest: true
|
||||||
|
|
||||||
|
- name: Setup pnpm + cache store
|
||||||
|
uses: ./.github/actions/setup-pnpm-store-cache
|
||||||
|
with:
|
||||||
|
pnpm-version: "10.23.0"
|
||||||
|
cache-key-suffix: "node22"
|
||||||
|
|
||||||
- name: Runtime versions
|
- name: Runtime versions
|
||||||
run: |
|
run: |
|
||||||
node -v
|
node -v
|
||||||
@@ -90,8 +238,8 @@ jobs:
|
|||||||
pnpm install --frozen-lockfile --ignore-scripts=false --config.engine-strict=false --config.enable-pre-post-scripts=true
|
pnpm install --frozen-lockfile --ignore-scripts=false --config.engine-strict=false --config.enable-pre-post-scripts=true
|
||||||
|
|
||||||
checks:
|
checks:
|
||||||
needs: [docs-scope]
|
needs: [docs-scope, changed-scope]
|
||||||
if: needs.docs-scope.outputs.docs_only != 'true'
|
if: needs.docs-scope.outputs.docs_only != 'true' && (github.event_name == 'push' || needs.changed-scope.outputs.run_node == 'true')
|
||||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
@@ -108,7 +256,7 @@ jobs:
|
|||||||
command: pnpm protocol:check
|
command: pnpm protocol:check
|
||||||
- runtime: bun
|
- runtime: bun
|
||||||
task: test
|
task: test
|
||||||
command: pnpm canvas:a2ui:bundle && bunx vitest run
|
command: pnpm canvas:a2ui:bundle && bunx vitest run --config vitest.unit.config.ts
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -134,19 +282,11 @@ jobs:
|
|||||||
node-version: 22.x
|
node-version: 22.x
|
||||||
check-latest: true
|
check-latest: true
|
||||||
|
|
||||||
- name: Setup pnpm (corepack retry)
|
- name: Setup pnpm + cache store
|
||||||
run: |
|
uses: ./.github/actions/setup-pnpm-store-cache
|
||||||
set -euo pipefail
|
with:
|
||||||
corepack enable
|
pnpm-version: "10.23.0"
|
||||||
for attempt in 1 2 3; do
|
cache-key-suffix: "node22"
|
||||||
if corepack prepare pnpm@10.23.0 --activate; then
|
|
||||||
pnpm -v
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
echo "corepack prepare failed (attempt $attempt/3). Retrying..."
|
|
||||||
sleep $((attempt * 10))
|
|
||||||
done
|
|
||||||
exit 1
|
|
||||||
|
|
||||||
- name: Setup Bun
|
- name: Setup Bun
|
||||||
uses: oven-sh/setup-bun@v2
|
uses: oven-sh/setup-bun@v2
|
||||||
@@ -184,7 +324,7 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- task: lint
|
- task: lint
|
||||||
command: pnpm build && pnpm lint
|
command: pnpm lint
|
||||||
- task: format
|
- task: format
|
||||||
command: pnpm format
|
command: pnpm format
|
||||||
steps:
|
steps:
|
||||||
@@ -212,19 +352,11 @@ jobs:
|
|||||||
node-version: 22.x
|
node-version: 22.x
|
||||||
check-latest: true
|
check-latest: true
|
||||||
|
|
||||||
- name: Setup pnpm (corepack retry)
|
- name: Setup pnpm + cache store
|
||||||
run: |
|
uses: ./.github/actions/setup-pnpm-store-cache
|
||||||
set -euo pipefail
|
with:
|
||||||
corepack enable
|
pnpm-version: "10.23.0"
|
||||||
for attempt in 1 2 3; do
|
cache-key-suffix: "node22"
|
||||||
if corepack prepare pnpm@10.23.0 --activate; then
|
|
||||||
pnpm -v
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
echo "corepack prepare failed (attempt $attempt/3). Retrying..."
|
|
||||||
sleep $((attempt * 10))
|
|
||||||
done
|
|
||||||
exit 1
|
|
||||||
|
|
||||||
- name: Setup Bun
|
- name: Setup Bun
|
||||||
uses: oven-sh/setup-bun@v2
|
uses: oven-sh/setup-bun@v2
|
||||||
@@ -280,8 +412,8 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
checks-windows:
|
checks-windows:
|
||||||
needs: [docs-scope]
|
needs: [docs-scope, changed-scope, build-artifacts]
|
||||||
if: needs.docs-scope.outputs.docs_only != 'true'
|
if: needs.docs-scope.outputs.docs_only != 'true' && (github.event_name == 'push' || needs.changed-scope.outputs.run_node == 'true')
|
||||||
runs-on: blacksmith-4vcpu-windows-2025
|
runs-on: blacksmith-4vcpu-windows-2025
|
||||||
env:
|
env:
|
||||||
NODE_OPTIONS: --max-old-space-size=4096
|
NODE_OPTIONS: --max-old-space-size=4096
|
||||||
@@ -296,8 +428,8 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- runtime: node
|
- runtime: node
|
||||||
task: build & lint
|
task: lint
|
||||||
command: pnpm build && pnpm lint
|
command: pnpm lint
|
||||||
- runtime: node
|
- runtime: node
|
||||||
task: test
|
task: test
|
||||||
command: pnpm canvas:a2ui:bundle && pnpm test
|
command: pnpm canvas:a2ui:bundle && pnpm test
|
||||||
@@ -342,25 +474,31 @@ jobs:
|
|||||||
done
|
done
|
||||||
exit 1
|
exit 1
|
||||||
|
|
||||||
|
- name: Download dist artifact (lint lane)
|
||||||
|
if: matrix.task == 'lint'
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: dist-build
|
||||||
|
path: dist/
|
||||||
|
|
||||||
|
- name: Verify dist artifact (lint lane)
|
||||||
|
if: matrix.task == 'lint'
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
test -s dist/index.js
|
||||||
|
test -s dist/plugin-sdk/index.js
|
||||||
|
|
||||||
- name: Setup Node.js
|
- name: Setup Node.js
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 22.x
|
node-version: 22.x
|
||||||
check-latest: true
|
check-latest: true
|
||||||
|
|
||||||
- name: Setup pnpm (corepack retry)
|
- name: Setup pnpm + cache store
|
||||||
run: |
|
uses: ./.github/actions/setup-pnpm-store-cache
|
||||||
set -euo pipefail
|
with:
|
||||||
corepack enable
|
pnpm-version: "10.23.0"
|
||||||
for attempt in 1 2 3; do
|
cache-key-suffix: "node22"
|
||||||
if corepack prepare pnpm@10.23.0 --activate; then
|
|
||||||
pnpm -v
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
echo "corepack prepare failed (attempt $attempt/3). Retrying..."
|
|
||||||
sleep $((attempt * 10))
|
|
||||||
done
|
|
||||||
exit 1
|
|
||||||
|
|
||||||
- name: Setup Bun
|
- name: Setup Bun
|
||||||
uses: oven-sh/setup-bun@v2
|
uses: oven-sh/setup-bun@v2
|
||||||
@@ -395,8 +533,8 @@ jobs:
|
|||||||
# running 4 separate jobs per PR (as before) starved the queue. One job
|
# running 4 separate jobs per PR (as before) starved the queue. One job
|
||||||
# per PR allows 5 PRs to run macOS checks simultaneously.
|
# per PR allows 5 PRs to run macOS checks simultaneously.
|
||||||
macos:
|
macos:
|
||||||
needs: [docs-scope]
|
needs: [docs-scope, changed-scope]
|
||||||
if: github.event_name == 'pull_request' && needs.docs-scope.outputs.docs_only != 'true'
|
if: github.event_name == 'pull_request' && needs.docs-scope.outputs.docs_only != 'true' && needs.changed-scope.outputs.run_macos == 'true'
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
@@ -424,19 +562,11 @@ jobs:
|
|||||||
node-version: 22.x
|
node-version: 22.x
|
||||||
check-latest: true
|
check-latest: true
|
||||||
|
|
||||||
- name: Setup pnpm (corepack retry)
|
- name: Setup pnpm + cache store
|
||||||
run: |
|
uses: ./.github/actions/setup-pnpm-store-cache
|
||||||
set -euo pipefail
|
with:
|
||||||
corepack enable
|
pnpm-version: "10.23.0"
|
||||||
for attempt in 1 2 3; do
|
cache-key-suffix: "node22"
|
||||||
if corepack prepare pnpm@10.23.0 --activate; then
|
|
||||||
pnpm -v
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
echo "corepack prepare failed (attempt $attempt/3). Retrying..."
|
|
||||||
sleep $((attempt * 10))
|
|
||||||
done
|
|
||||||
exit 1
|
|
||||||
|
|
||||||
- name: Runtime versions
|
- name: Runtime versions
|
||||||
run: |
|
run: |
|
||||||
@@ -681,8 +811,8 @@ jobs:
|
|||||||
PY
|
PY
|
||||||
|
|
||||||
android:
|
android:
|
||||||
needs: [docs-scope]
|
needs: [docs-scope, changed-scope]
|
||||||
if: needs.docs-scope.outputs.docs_only != 'true'
|
if: needs.docs-scope.outputs.docs_only != 'true' && (github.event_name == 'push' || needs.changed-scope.outputs.run_android == 'true')
|
||||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|||||||
Reference in New Issue
Block a user