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
8 changes: 4 additions & 4 deletions .github/workflows/extract.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ name: Extract Snippets
on:
push:
branches: [main]
# No paths filter on pull_request — required status checks need this workflow to
# always trigger and report `validate`. The validate job is cheap (~20s) and
# idempotent: it just re-runs aggregate + extract + drift-check, which is a
# no-op for PRs that don't touch samples/scripts.
pull_request:
paths:
- "samples/**"
- "scripts/**"
- "placeholder-map.yaml"
workflow_dispatch:

permissions:
Expand Down
64 changes: 51 additions & 13 deletions .github/workflows/test-android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,20 @@ name: Test Android Builds
on:
push:
branches: [main]
paths:
- "samples/react-native/**"
- "samples/android/**"
- ".github/workflows/test-android.yml"
# No paths filter on pull_request — required status checks need this workflow to
# always trigger so the aggregator can report. find-projects below narrows the
# matrix to only projects whose subtree changed, so docs-only / other-framework
# PRs produce an empty matrix → build job skipped → aggregator passes via
# `result == 'skipped'`.
pull_request:
paths:
- "samples/react-native/**"
- "samples/android/**"
- ".github/workflows/test-android.yml"
schedule:
- cron: "0 9 * * 1"
workflow_dispatch:

permissions:
contents: read
# Needed by find-projects' `gh api .../pulls/N/files` call.
pull-requests: read

jobs:
find-projects:
Expand All @@ -26,13 +25,52 @@ jobs:
matrix: ${{ steps.find.outputs.matrix }}
steps:
- uses: actions/checkout@v6
# Default shallow checkout — we only need the working tree for `find`
# below, not git history. The PR's changed files come from gh api.
- id: find
# Discover any sample with an Android Gradle wrapper. Today: react-native
# samples; future: native android samples will surface automatically.
env:
EVENT_NAME: ${{ github.event_name }}
PR_NUMBER: ${{ github.event.pull_request.number }}
WORKFLOW_FILE: .github/workflows/test-android.yml
GH_TOKEN: ${{ github.token }}
run: |
DIRS=$(find samples -name "gradlew" -not -path "*/node_modules/*" -not -path "*/build/*" -exec dirname {} \; 2>/dev/null \
| sort | jq -R -s -c 'split("\n") | map(select(. != ""))')
echo "matrix=$DIRS" >> "$GITHUB_OUTPUT"
set -euo pipefail
# Discover any sample with an Android Gradle wrapper. Today: react-native
# samples and native android samples.
ALL=$(find samples -name "gradlew" -not -path "*/node_modules/*" -not -path "*/build/*" -exec dirname {} \; 2>/dev/null | sort)

if [ "$EVENT_NAME" = "pull_request" ]; then
CHANGED=$(gh api --paginate "/repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER/files" --jq '.[].filename' 2>/dev/null || echo "")
if printf '%s\n' "$CHANGED" | grep -qFx "$WORKFLOW_FILE"; then
FILTERED="$ALL"
else
# For each gradlew dir, walk up to find a package.json. If found (an
# RN sample — gradlew sits under <rn-root>/android/), watch the RN
# root: JS dep changes upstairs affect Android autolinking. If not
# found (a native Android sample), watch the gradlew dir itself.
# Mirrors the "Install JS dependencies (RN samples)" step's walk-up.
FILTERED=$(while IFS= read -r proj; do
[ -z "$proj" ] && continue
watch_root="$proj"
d="$proj"
while [ "$d" != "." ] && [ "$d" != "/" ]; do
if [ -f "$d/package.json" ]; then
watch_root="$d"
break
fi
d=$(dirname "$d")
done
if printf '%s\n' "$CHANGED" | grep -q "^${watch_root}/"; then
echo "$proj"
fi
done <<< "$ALL")
fi
else
FILTERED="$ALL"
fi

MATRIX=$(printf '%s\n' "$FILTERED" | jq -R -s -c 'split("\n") | map(select(. != ""))')
echo "matrix=$MATRIX" >> "$GITHUB_OUTPUT"

build:
needs: find-projects
Expand Down
43 changes: 35 additions & 8 deletions .github/workflows/test-dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,20 @@ name: Test .NET Frameworks
on:
push:
branches: [main]
paths:
- "samples/dotnet/**"
- ".github/workflows/test-dotnet.yml"
# No paths filter on pull_request — required status checks need this workflow to
# always trigger so the aggregator can report. find-projects below narrows the
# matrix to only projects whose subtree changed, so docs-only / other-framework
# PRs produce an empty matrix → test job skipped → aggregator passes via
# `result == 'skipped'`.
pull_request:
paths:
- "samples/dotnet/**"
- ".github/workflows/test-dotnet.yml"
schedule:
- cron: "0 8 * * 1"
workflow_dispatch:

permissions:
contents: read
# Needed by find-projects' `gh api .../pulls/N/files` call.
pull-requests: read

jobs:
find-projects:
Expand All @@ -24,10 +25,36 @@ jobs:
matrix: ${{ steps.find.outputs.matrix }}
steps:
- uses: actions/checkout@v6
# Default shallow checkout — we only need the working tree for `find`
# below, not git history. The PR's changed files come from gh api.
- id: find
env:
EVENT_NAME: ${{ github.event_name }}
PR_NUMBER: ${{ github.event.pull_request.number }}
WORKFLOW_FILE: .github/workflows/test-dotnet.yml
GH_TOKEN: ${{ github.token }}
run: |
DIRS=$(find samples -name "*.sln" -not -path "*/node_modules/*" -exec dirname {} \; 2>/dev/null | sort | jq -R -s -c 'split("\n") | map(select(. != ""))')
echo "matrix=$DIRS" >> "$GITHUB_OUTPUT"
set -euo pipefail
ALL=$(find samples -name "*.sln" -not -path "*/node_modules/*" -exec dirname {} \; 2>/dev/null | sort)

if [ "$EVENT_NAME" = "pull_request" ]; then
CHANGED=$(gh api --paginate "/repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER/files" --jq '.[].filename' 2>/dev/null || echo "")
if printf '%s\n' "$CHANGED" | grep -qFx "$WORKFLOW_FILE"; then
FILTERED="$ALL"
else
FILTERED=$(while IFS= read -r proj; do
[ -z "$proj" ] && continue
if printf '%s\n' "$CHANGED" | grep -q "^${proj}/"; then
echo "$proj"
fi
done <<< "$ALL")
fi
else
FILTERED="$ALL"
fi

MATRIX=$(printf '%s\n' "$FILTERED" | jq -R -s -c 'split("\n") | map(select(. != ""))')
echo "matrix=$MATRIX" >> "$GITHUB_OUTPUT"

test:
needs: find-projects
Expand Down
48 changes: 37 additions & 11 deletions .github/workflows/test-ios.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,20 @@ name: Test iOS Builds
on:
push:
branches: [main]
paths:
- "samples/ios/**"
- ".github/workflows/test-ios.yml"
# No paths filter on pull_request — required status checks need this workflow to
# always trigger so the aggregator can report. find-projects below narrows the
# matrix to only projects whose subtree changed, so docs-only / other-framework
# PRs produce an empty matrix → test job skipped → aggregator passes via
# `result == 'skipped'` (no macOS minutes burned).
pull_request:
paths:
- "samples/ios/**"
- ".github/workflows/test-ios.yml"
schedule:
- cron: "0 10 * * 1"
workflow_dispatch:

permissions:
contents: read
# Needed by find-projects' `gh api .../pulls/N/files` call.
pull-requests: read

jobs:
find-projects:
Expand All @@ -24,13 +25,38 @@ jobs:
matrix: ${{ steps.find.outputs.matrix }}
steps:
- uses: actions/checkout@v6
# Default shallow checkout — we only need the working tree for `find`
# below, not git history. The PR's changed files come from gh api.
- id: find
# Each iOS sample is identified by its project.yml (xcodegen input). We use
# that as the marker rather than the generated .xcodeproj because the
# project.yml is the authoritative source — generated files come and go.
env:
EVENT_NAME: ${{ github.event_name }}
PR_NUMBER: ${{ github.event.pull_request.number }}
WORKFLOW_FILE: .github/workflows/test-ios.yml
GH_TOKEN: ${{ github.token }}
run: |
DIRS=$(find samples/ios -mindepth 2 -maxdepth 2 -name "project.yml" -exec dirname {} \; 2>/dev/null | sort | jq -R -s -c 'split("\n") | map(select(. != ""))')
echo "matrix=$DIRS" >> "$GITHUB_OUTPUT"
set -euo pipefail
# Each iOS sample is identified by its project.yml (xcodegen input) —
# that's the authoritative source; the generated .xcodeproj comes and goes.
ALL=$(find samples/ios -mindepth 2 -maxdepth 2 -name "project.yml" -exec dirname {} \; 2>/dev/null | sort)

if [ "$EVENT_NAME" = "pull_request" ]; then
CHANGED=$(gh api --paginate "/repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER/files" --jq '.[].filename' 2>/dev/null || echo "")
if printf '%s\n' "$CHANGED" | grep -qFx "$WORKFLOW_FILE"; then
FILTERED="$ALL"
else
FILTERED=$(while IFS= read -r proj; do
[ -z "$proj" ] && continue
if printf '%s\n' "$CHANGED" | grep -q "^${proj}/"; then
echo "$proj"
fi
done <<< "$ALL")
fi
else
FILTERED="$ALL"
fi

MATRIX=$(printf '%s\n' "$FILTERED" | jq -R -s -c 'split("\n") | map(select(. != ""))')
echo "matrix=$MATRIX" >> "$GITHUB_OUTPUT"

test:
needs: find-projects
Expand Down
43 changes: 35 additions & 8 deletions .github/workflows/test-java.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,20 @@ name: Test Java Frameworks
on:
push:
branches: [main]
paths:
- "samples/java/**"
- ".github/workflows/test-java.yml"
# No paths filter on pull_request — required status checks need this workflow to
# always trigger so the aggregator can report. find-projects below narrows the
# matrix to only projects whose subtree changed, so docs-only / other-framework
# PRs produce an empty matrix → test job skipped → aggregator passes via
# `result == 'skipped'`.
pull_request:
paths:
- "samples/java/**"
- ".github/workflows/test-java.yml"
schedule:
- cron: "0 8 * * 1"
workflow_dispatch:

permissions:
contents: read
# Needed by find-projects' `gh api .../pulls/N/files` call.
pull-requests: read

jobs:
find-projects:
Expand All @@ -24,10 +25,36 @@ jobs:
matrix: ${{ steps.find.outputs.matrix }}
steps:
- uses: actions/checkout@v6
# Default shallow checkout — we only need the working tree for `find`
# below, not git history. The PR's changed files come from gh api.
- id: find
env:
EVENT_NAME: ${{ github.event_name }}
PR_NUMBER: ${{ github.event.pull_request.number }}
WORKFLOW_FILE: .github/workflows/test-java.yml
GH_TOKEN: ${{ github.token }}
run: |
DIRS=$(find samples -name "pom.xml" -not -path "*/target/*" -not -path "*/node_modules/*" -exec dirname {} \; 2>/dev/null | sort | jq -R -s -c 'split("\n") | map(select(. != ""))')
echo "matrix=$DIRS" >> "$GITHUB_OUTPUT"
set -euo pipefail
ALL=$(find samples -name "pom.xml" -not -path "*/target/*" -not -path "*/node_modules/*" -exec dirname {} \; 2>/dev/null | sort)

if [ "$EVENT_NAME" = "pull_request" ]; then
CHANGED=$(gh api --paginate "/repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER/files" --jq '.[].filename' 2>/dev/null || echo "")
if printf '%s\n' "$CHANGED" | grep -qFx "$WORKFLOW_FILE"; then
FILTERED="$ALL"
else
FILTERED=$(while IFS= read -r proj; do
[ -z "$proj" ] && continue
if printf '%s\n' "$CHANGED" | grep -q "^${proj}/"; then
echo "$proj"
fi
done <<< "$ALL")
fi
else
FILTERED="$ALL"
fi

MATRIX=$(printf '%s\n' "$FILTERED" | jq -R -s -c 'split("\n") | map(select(. != ""))')
echo "matrix=$MATRIX" >> "$GITHUB_OUTPUT"

test:
needs: find-projects
Expand Down
57 changes: 41 additions & 16 deletions .github/workflows/test-js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,20 @@ name: Test JS Frameworks
on:
push:
branches: [main]
paths:
- "samples/react/**"
- "samples/angular/**"
- "samples/vue/**"
- "samples/node/**"
- "samples/react-native/**"
- ".github/workflows/test-js.yml"
# No paths filter on pull_request — required status checks need this workflow to
# always trigger so the aggregator can report. find-projects below narrows the
# matrix to only projects whose subtree changed, so docs-only / other-framework
# PRs produce an empty matrix → test job skipped → aggregator passes via
# `result == 'skipped'`.
pull_request:
paths:
- "samples/react/**"
- "samples/angular/**"
- "samples/vue/**"
- "samples/node/**"
- "samples/react-native/**"
- ".github/workflows/test-js.yml"
schedule:
- cron: "0 8 * * 1"
workflow_dispatch:

permissions:
contents: read
# Needed by find-projects' `gh api .../pulls/N/files` call.
pull-requests: read

jobs:
find-projects:
Expand All @@ -32,10 +25,42 @@ jobs:
matrix: ${{ steps.find.outputs.matrix }}
steps:
- uses: actions/checkout@v6
# Default shallow checkout — we only need the working tree for `find`
# below, not git history. The PR's changed files come from gh api.
- id: find
env:
EVENT_NAME: ${{ github.event_name }}
PR_NUMBER: ${{ github.event.pull_request.number }}
WORKFLOW_FILE: .github/workflows/test-js.yml
GH_TOKEN: ${{ github.token }}
run: |
DIRS=$(find samples -name "package.json" -not -path "*/node_modules/*" -exec dirname {} \; 2>/dev/null | sort | jq -R -s -c 'split("\n") | map(select(. != ""))')
echo "matrix=$DIRS" >> "$GITHUB_OUTPUT"
set -euo pipefail
# Exclude `.angular/cache/**/package.json` — Angular's Vite dep cache
# writes nested package.json files inside .angular/cache after a build.
# On a fresh CI checkout the cache doesn't exist yet, but the exclude
# hardens us against any future ordering change that runs a build first.
ALL=$(find samples -name "package.json" -not -path "*/node_modules/*" -not -path "*/.angular/*" -exec dirname {} \; 2>/dev/null | sort)

if [ "$EVENT_NAME" = "pull_request" ]; then
CHANGED=$(gh api --paginate "/repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER/files" --jq '.[].filename' 2>/dev/null || echo "")
# If the workflow file itself changed, run the full matrix so we
# exercise the workflow against every sample.
if printf '%s\n' "$CHANGED" | grep -qFx "$WORKFLOW_FILE"; then
FILTERED="$ALL"
else
FILTERED=$(while IFS= read -r proj; do
[ -z "$proj" ] && continue
if printf '%s\n' "$CHANGED" | grep -q "^${proj}/"; then
echo "$proj"
fi
done <<< "$ALL")
fi
else
FILTERED="$ALL"
fi

MATRIX=$(printf '%s\n' "$FILTERED" | jq -R -s -c 'split("\n") | map(select(. != ""))')
echo "matrix=$MATRIX" >> "$GITHUB_OUTPUT"

test:
needs: find-projects
Expand Down