Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
6868e13
Add samples and sample validation ci
YunchuWang Feb 9, 2026
b9a6572
Fix output formatting for emulator and non-emulator samples in valida…
YunchuWang Feb 9, 2026
65ddfb1
Update examples/azure-managed/hello-orchestrations/index.ts
YunchuWang Feb 9, 2026
d55aed6
Update test/e2e-azuremanaged/retry-handler.spec.ts
YunchuWang Feb 9, 2026
70f0b41
Update .github/workflows/validate-samples.yaml
YunchuWang Feb 9, 2026
c609f8d
Update examples/azure-managed/hello-orchestrations/index.ts
YunchuWang Feb 9, 2026
399bce7
Add greeting activity to hello-orchestrations sample and remove comme…
YunchuWang Feb 9, 2026
df57748
cleanup
YunchuWang Feb 9, 2026
097e16d
Refactor DTS emulator setup in validate-samples workflow to use Docke…
YunchuWang Feb 10, 2026
08645bb
Update sample discovery logic to skip root sample.json in validate-sa…
YunchuWang Feb 10, 2026
163a5e9
Add Azure Managed DTS samples for basic usage and distributed tracing
YunchuWang Feb 10, 2026
708f345
Add samples for basics and distributed tracing, update validation log…
YunchuWang Feb 10, 2026
ded5ef4
Enhance sample validation workflow to support skipCi flag and adjust …
YunchuWang Feb 10, 2026
c29af5a
Refactor multiEventOrchestrator to reorder event handling steps and c…
YunchuWang Feb 10, 2026
188ac0f
Reduce timer durations in approval and notifier orchestrators for imp…
YunchuWang Feb 10, 2026
641300f
Refactor orchestration lifecycle management sample to remove recursiv…
YunchuWang Feb 10, 2026
a8d13de
Refactor history event logging to use consistent property names for i…
YunchuWang Feb 10, 2026
4ef83f4
Refactor retry handler naming for consistency and clarity in error ha…
YunchuWang Feb 10, 2026
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
215 changes: 215 additions & 0 deletions .github/workflows/validate-samples.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
name: 🧪 Validate Samples

# Validates all samples under examples/azure-managed/ on PRs and main pushes.
# Samples are auto-discovered: any subfolder containing a sample.json is treated as a sample.
# The "unit-testing" sample runs without emulator; emulator-dependent samples use Docker.

on:
push:
branches: [main]
paths:
- "examples/**"
- "packages/**"
- "package.json"
- "tsconfig.base.json"
- ".github/workflows/validate-samples.yaml"
pull_request:
branches: [main]
paths:
- "examples/**"
- "packages/**"
- "package.json"
- "tsconfig.base.json"
- ".github/workflows/validate-samples.yaml"

permissions:
contents: read

jobs:
# -----------------------------------------------------------------------
# 1. Discover all samples dynamically
# -----------------------------------------------------------------------
discover:
runs-on: ubuntu-latest
outputs:
# JSON arrays of sample directory names
emulator-samples: ${{ steps.find.outputs.emulator }}
no-emulator-samples: ${{ steps.find.outputs.no_emulator }}
steps:
- uses: actions/checkout@v4

- name: 🔍 Discover samples via sample.json
id: find
run: |
SAMPLES_ROOT="examples/azure-managed"

# Find all sample.json files under the samples root
emulator_samples="[]"
no_emulator_samples="[]"

for sample_json in $(find "$SAMPLES_ROOT" -mindepth 1 -name "sample.json" | sort); do
dir=$(dirname "$sample_json")
name=$(basename "$dir")
requires_emulator=$(jq -r '.requiresEmulator // true' "$sample_json")
skip_ci=$(jq -r '.skipCi // false' "$sample_json")

echo "Found sample: $name (requiresEmulator=$requires_emulator, skipCi=$skip_ci)"

if [ "$skip_ci" = "true" ]; then
echo " ⏭️ Skipping $name (skipCi=true)"
continue
fi

if [ "$requires_emulator" = "false" ]; then
no_emulator_samples=$(echo "$no_emulator_samples" | jq --arg n "$name" '. + [$n]')
else
emulator_samples=$(echo "$emulator_samples" | jq --arg n "$name" '. + [$n]')
fi
done

echo "emulator=$(echo "$emulator_samples" | jq -c .)" >> "$GITHUB_OUTPUT"
echo "no_emulator=$(echo "$no_emulator_samples" | jq -c .)" >> "$GITHUB_OUTPUT"

echo "--- Emulator samples ---"
echo "$emulator_samples" | jq .
echo "--- No-emulator samples ---"
echo "$no_emulator_samples" | jq .

# -----------------------------------------------------------------------
# 2. Build the SDK (shared by all sample jobs)
# -----------------------------------------------------------------------
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: ["22.x"]
steps:
- uses: actions/checkout@v4

- name: ⚙️ Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: npm

- name: 📦 Install dependencies
run: npm ci

- name: 🔨 Build SDK
run: npm run build

- name: 📁 Cache build output
uses: actions/cache/save@v4
with:
path: |
node_modules
packages/*/dist
packages/*/node_modules
key: sdk-build-${{ github.sha }}-node${{ matrix.node-version }}

# -----------------------------------------------------------------------
# 3. Run samples that DON'T need the emulator (e.g., unit-testing)
# -----------------------------------------------------------------------
samples-no-emulator:
needs: [discover, build]
if: needs.discover.outputs.no-emulator-samples != '[]'
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
sample: ${{ fromJson(needs.discover.outputs.no-emulator-samples) }}
node-version: ["22.x"]
steps:
- uses: actions/checkout@v4

- name: ⚙️ Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}

- name: 📦 Restore build cache
uses: actions/cache/restore@v4
with:
path: |
node_modules
packages/*/dist
packages/*/node_modules
key: sdk-build-${{ github.sha }}-node${{ matrix.node-version }}

- name: 🧪 Run sample — ${{ matrix.sample }}
run: |
echo "Running sample: ${{ matrix.sample }}"
npx ts-node --swc ./examples/azure-managed/${{ matrix.sample }}/index.ts
timeout-minutes: 2

# -----------------------------------------------------------------------
# 4. Run samples that need the DTS emulator (Docker)
# -----------------------------------------------------------------------
samples-with-emulator:
needs: [discover, build]
if: needs.discover.outputs.emulator-samples != '[]'
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
sample: ${{ fromJson(needs.discover.outputs.emulator-samples) }}
node-version: ["22.x"]

env:
DURABLE_TASK_SCHEDULER_CONNECTION_STRING: "Endpoint=http://localhost:8080;Authentication=None;TaskHub=default"

steps:
- uses: actions/checkout@v4

- name: 🐳 Start DTS emulator
run: |
docker pull mcr.microsoft.com/dts/dts-emulator:latest
docker run --name dtsemulator -d -p 8080:8080 mcr.microsoft.com/dts/dts-emulator:latest

- name: ⏳ Wait for DTS emulator
run: sleep 10

- name: ⚙️ Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}

- name: 📦 Restore build cache
uses: actions/cache/restore@v4
with:
path: |
node_modules
packages/*/dist
packages/*/node_modules
key: sdk-build-${{ github.sha }}-node${{ matrix.node-version }}

- name: 🧪 Run sample — ${{ matrix.sample }}
run: |
echo "Running sample: ${{ matrix.sample }}"
npx ts-node --swc ./examples/azure-managed/${{ matrix.sample }}/index.ts
timeout-minutes: 5

- name: 🧹 Stop DTS emulator
if: always()
run: docker rm -f dtsemulator || true

# -----------------------------------------------------------------------
# 5. Summary gate — all samples must pass
# -----------------------------------------------------------------------
samples-gate:
needs: [samples-no-emulator, samples-with-emulator]
if: always()
runs-on: ubuntu-latest
steps:
- name: ✅ Check results
run: |
echo "No-emulator result: ${{ needs.samples-no-emulator.result }}"
echo "Emulator result: ${{ needs.samples-with-emulator.result }}"

if [[ ! "${{ needs.samples-no-emulator.result }}" =~ ^(success|skipped)$ ]] || \
[[ ! "${{ needs.samples-with-emulator.result }}" =~ ^(success|skipped)$ ]]; then
echo "❌ Some samples failed or were cancelled!"
exit 1
fi

echo "✅ All samples passed!"
16 changes: 14 additions & 2 deletions examples/azure-managed/.env.example
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
# Azure Managed Durable Task Scheduler (DTS) Configuration
# Copy this file to .env and update the values for your environment.
#
# To find your endpoint, run:
# az durabletask scheduler show --resource-group <rg> --name <scheduler> --query endpoint -o tsv
#
# Make sure you have the "Durable Task Data Contributor" role assigned on the scheduler resource.
# Authenticate via: az login

# Option 1: Using connection string (recommended)
# Supported authentication types: DefaultAzure, ManagedIdentity, WorkloadIdentity,
# Supported authentication types: DefaultAzure, ManagedIdentity, WorkloadIdentity,
# Environment, AzureCli, AzurePowerShell, VisualStudioCode, InteractiveBrowser, None
# Use Authentication=None only for the local emulator.
DURABLE_TASK_SCHEDULER_CONNECTION_STRING=Endpoint=https://your-scheduler.eastus.durabletask.io;Authentication=DefaultAzure;TaskHub=your-taskhub

# Option 2: Using explicit parameters (uses DefaultAzureCredential)
# Uncomment these lines and comment out DURABLE_TASK_SCHEDULER_CONNECTION_STRING above
# AZURE_DTS_ENDPOINT=https://your-scheduler.eastus.durabletask.io
# AZURE_DTS_TASKHUB=your-taskhub
# AZURE_DTS_TASKHUB=your-taskhub

# Optional: OTLP endpoint for distributed tracing (Jaeger, Azure Monitor, Aspire Dashboard, etc.)
# OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
Loading
Loading