Skip to content

Commit e4da4a0

Browse files
authored
Add samples and sample validation ci (#100)
1 parent fb988d4 commit e4da4a0

File tree

31 files changed

+2639
-14
lines changed

31 files changed

+2639
-14
lines changed
Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
name: 🧪 Validate Samples
2+
3+
# Validates all samples under examples/azure-managed/ on PRs and main pushes.
4+
# Samples are auto-discovered: any subfolder containing a sample.json is treated as a sample.
5+
# The "unit-testing" sample runs without emulator; emulator-dependent samples use Docker.
6+
7+
on:
8+
push:
9+
branches: [main]
10+
paths:
11+
- "examples/**"
12+
- "packages/**"
13+
- "package.json"
14+
- "tsconfig.base.json"
15+
- ".github/workflows/validate-samples.yaml"
16+
pull_request:
17+
branches: [main]
18+
paths:
19+
- "examples/**"
20+
- "packages/**"
21+
- "package.json"
22+
- "tsconfig.base.json"
23+
- ".github/workflows/validate-samples.yaml"
24+
25+
permissions:
26+
contents: read
27+
28+
jobs:
29+
# -----------------------------------------------------------------------
30+
# 1. Discover all samples dynamically
31+
# -----------------------------------------------------------------------
32+
discover:
33+
runs-on: ubuntu-latest
34+
outputs:
35+
# JSON arrays of sample directory names
36+
emulator-samples: ${{ steps.find.outputs.emulator }}
37+
no-emulator-samples: ${{ steps.find.outputs.no_emulator }}
38+
steps:
39+
- uses: actions/checkout@v4
40+
41+
- name: 🔍 Discover samples via sample.json
42+
id: find
43+
run: |
44+
SAMPLES_ROOT="examples/azure-managed"
45+
46+
# Find all sample.json files under the samples root
47+
emulator_samples="[]"
48+
no_emulator_samples="[]"
49+
50+
for sample_json in $(find "$SAMPLES_ROOT" -mindepth 1 -name "sample.json" | sort); do
51+
dir=$(dirname "$sample_json")
52+
name=$(basename "$dir")
53+
requires_emulator=$(jq -r '.requiresEmulator // true' "$sample_json")
54+
skip_ci=$(jq -r '.skipCi // false' "$sample_json")
55+
56+
echo "Found sample: $name (requiresEmulator=$requires_emulator, skipCi=$skip_ci)"
57+
58+
if [ "$skip_ci" = "true" ]; then
59+
echo " ⏭️ Skipping $name (skipCi=true)"
60+
continue
61+
fi
62+
63+
if [ "$requires_emulator" = "false" ]; then
64+
no_emulator_samples=$(echo "$no_emulator_samples" | jq --arg n "$name" '. + [$n]')
65+
else
66+
emulator_samples=$(echo "$emulator_samples" | jq --arg n "$name" '. + [$n]')
67+
fi
68+
done
69+
70+
echo "emulator=$(echo "$emulator_samples" | jq -c .)" >> "$GITHUB_OUTPUT"
71+
echo "no_emulator=$(echo "$no_emulator_samples" | jq -c .)" >> "$GITHUB_OUTPUT"
72+
73+
echo "--- Emulator samples ---"
74+
echo "$emulator_samples" | jq .
75+
echo "--- No-emulator samples ---"
76+
echo "$no_emulator_samples" | jq .
77+
78+
# -----------------------------------------------------------------------
79+
# 2. Build the SDK (shared by all sample jobs)
80+
# -----------------------------------------------------------------------
81+
build:
82+
runs-on: ubuntu-latest
83+
strategy:
84+
matrix:
85+
node-version: ["22.x"]
86+
steps:
87+
- uses: actions/checkout@v4
88+
89+
- name: ⚙️ Setup Node.js ${{ matrix.node-version }}
90+
uses: actions/setup-node@v4
91+
with:
92+
node-version: ${{ matrix.node-version }}
93+
cache: npm
94+
95+
- name: 📦 Install dependencies
96+
run: npm ci
97+
98+
- name: 🔨 Build SDK
99+
run: npm run build
100+
101+
- name: 📁 Cache build output
102+
uses: actions/cache/save@v4
103+
with:
104+
path: |
105+
node_modules
106+
packages/*/dist
107+
packages/*/node_modules
108+
key: sdk-build-${{ github.sha }}-node${{ matrix.node-version }}
109+
110+
# -----------------------------------------------------------------------
111+
# 3. Run samples that DON'T need the emulator (e.g., unit-testing)
112+
# -----------------------------------------------------------------------
113+
samples-no-emulator:
114+
needs: [discover, build]
115+
if: needs.discover.outputs.no-emulator-samples != '[]'
116+
runs-on: ubuntu-latest
117+
strategy:
118+
fail-fast: false
119+
matrix:
120+
sample: ${{ fromJson(needs.discover.outputs.no-emulator-samples) }}
121+
node-version: ["22.x"]
122+
steps:
123+
- uses: actions/checkout@v4
124+
125+
- name: ⚙️ Setup Node.js ${{ matrix.node-version }}
126+
uses: actions/setup-node@v4
127+
with:
128+
node-version: ${{ matrix.node-version }}
129+
130+
- name: 📦 Restore build cache
131+
uses: actions/cache/restore@v4
132+
with:
133+
path: |
134+
node_modules
135+
packages/*/dist
136+
packages/*/node_modules
137+
key: sdk-build-${{ github.sha }}-node${{ matrix.node-version }}
138+
139+
- name: 🧪 Run sample — ${{ matrix.sample }}
140+
run: |
141+
echo "Running sample: ${{ matrix.sample }}"
142+
npx ts-node --swc ./examples/azure-managed/${{ matrix.sample }}/index.ts
143+
timeout-minutes: 2
144+
145+
# -----------------------------------------------------------------------
146+
# 4. Run samples that need the DTS emulator (Docker)
147+
# -----------------------------------------------------------------------
148+
samples-with-emulator:
149+
needs: [discover, build]
150+
if: needs.discover.outputs.emulator-samples != '[]'
151+
runs-on: ubuntu-latest
152+
strategy:
153+
fail-fast: false
154+
matrix:
155+
sample: ${{ fromJson(needs.discover.outputs.emulator-samples) }}
156+
node-version: ["22.x"]
157+
158+
env:
159+
DURABLE_TASK_SCHEDULER_CONNECTION_STRING: "Endpoint=http://localhost:8080;Authentication=None;TaskHub=default"
160+
161+
steps:
162+
- uses: actions/checkout@v4
163+
164+
- name: 🐳 Start DTS emulator
165+
run: |
166+
docker pull mcr.microsoft.com/dts/dts-emulator:latest
167+
docker run --name dtsemulator -d -p 8080:8080 mcr.microsoft.com/dts/dts-emulator:latest
168+
169+
- name: ⏳ Wait for DTS emulator
170+
run: sleep 10
171+
172+
- name: ⚙️ Setup Node.js ${{ matrix.node-version }}
173+
uses: actions/setup-node@v4
174+
with:
175+
node-version: ${{ matrix.node-version }}
176+
177+
- name: 📦 Restore build cache
178+
uses: actions/cache/restore@v4
179+
with:
180+
path: |
181+
node_modules
182+
packages/*/dist
183+
packages/*/node_modules
184+
key: sdk-build-${{ github.sha }}-node${{ matrix.node-version }}
185+
186+
- name: 🧪 Run sample — ${{ matrix.sample }}
187+
run: |
188+
echo "Running sample: ${{ matrix.sample }}"
189+
npx ts-node --swc ./examples/azure-managed/${{ matrix.sample }}/index.ts
190+
timeout-minutes: 5
191+
192+
- name: 🧹 Stop DTS emulator
193+
if: always()
194+
run: docker rm -f dtsemulator || true
195+
196+
# -----------------------------------------------------------------------
197+
# 5. Summary gate — all samples must pass
198+
# -----------------------------------------------------------------------
199+
samples-gate:
200+
needs: [samples-no-emulator, samples-with-emulator]
201+
if: always()
202+
runs-on: ubuntu-latest
203+
steps:
204+
- name: ✅ Check results
205+
run: |
206+
echo "No-emulator result: ${{ needs.samples-no-emulator.result }}"
207+
echo "Emulator result: ${{ needs.samples-with-emulator.result }}"
208+
209+
if [[ ! "${{ needs.samples-no-emulator.result }}" =~ ^(success|skipped)$ ]] || \
210+
[[ ! "${{ needs.samples-with-emulator.result }}" =~ ^(success|skipped)$ ]]; then
211+
echo "❌ Some samples failed or were cancelled!"
212+
exit 1
213+
fi
214+
215+
echo "✅ All samples passed!"
Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,22 @@
11
# Azure Managed Durable Task Scheduler (DTS) Configuration
22
# Copy this file to .env and update the values for your environment.
3+
#
4+
# To find your endpoint, run:
5+
# az durabletask scheduler show --resource-group <rg> --name <scheduler> --query endpoint -o tsv
6+
#
7+
# Make sure you have the "Durable Task Data Contributor" role assigned on the scheduler resource.
8+
# Authenticate via: az login
9+
310
# Option 1: Using connection string (recommended)
4-
# Supported authentication types: DefaultAzure, ManagedIdentity, WorkloadIdentity,
11+
# Supported authentication types: DefaultAzure, ManagedIdentity, WorkloadIdentity,
512
# Environment, AzureCli, AzurePowerShell, VisualStudioCode, InteractiveBrowser, None
13+
# Use Authentication=None only for the local emulator.
614
DURABLE_TASK_SCHEDULER_CONNECTION_STRING=Endpoint=https://your-scheduler.eastus.durabletask.io;Authentication=DefaultAzure;TaskHub=your-taskhub
15+
716
# Option 2: Using explicit parameters (uses DefaultAzureCredential)
817
# Uncomment these lines and comment out DURABLE_TASK_SCHEDULER_CONNECTION_STRING above
918
# AZURE_DTS_ENDPOINT=https://your-scheduler.eastus.durabletask.io
10-
# AZURE_DTS_TASKHUB=your-taskhub
19+
# AZURE_DTS_TASKHUB=your-taskhub
20+
21+
# Optional: OTLP endpoint for distributed tracing (Jaeger, Azure Monitor, Aspire Dashboard, etc.)
22+
# OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318

0 commit comments

Comments
 (0)