|
1 | | -name: Run Samples |
| 1 | +# --------------------------------------------------------------- |
| 2 | +# .github/workflows/project-e2e-tests.yml |
| 3 | +# |
| 4 | +# PURPOSE |
| 5 | +# ▸ Run the same end-to-end test-suite against **many already- |
| 6 | +# provisioned projects**. Each project has its own value for |
| 7 | +# PROJECT_CLIENT, while MODEL_DEPLOYMENT_NAME is global. |
| 8 | +# |
| 9 | +# HOW TO USE |
| 10 | +# 1. Under **Settings ▸ Environments** create one environment |
| 11 | +# per project (project-alpha, project-beta, …). |
| 12 | +# 2. In every environment add the secret PROJECT_CLIENT |
| 13 | +# with that project’s value. |
| 14 | +# 3. In **Settings ▸ Secrets → Actions** (repo-level) add a |
| 15 | +# secret called MODEL_DEPLOYMENT_NAME that is identical |
| 16 | +# for all projects. |
| 17 | +# 4. List your projects in the matrix below. |
| 18 | +# 5. Push a PR that touches tests/ → this workflow fans out |
| 19 | +# and runs once per project, each run getting the correct |
| 20 | +# secrets automatically. |
| 21 | +# --------------------------------------------------------------- |
| 22 | + |
| 23 | +name: Project E2E Tests |
| 24 | + |
| 25 | +# ── 1️⃣ WHEN TO RUN ───────────────────────────────────────────── |
2 | 26 | on: |
3 | | - # By design pull_request_target event run against the version of the workflow in the target branch. |
4 | | - # So you have to merge changes to this workflow to observe the effects. |
5 | | - pull_request_target: |
6 | | - branches: |
7 | | - - main |
8 | | - paths: |
9 | | - - scenarios/** |
10 | | - - .infra/deployments/**/*.bicep |
| 27 | + pull_request_target: # Use target so the workflow |
| 28 | + # file comes from the protected |
| 29 | + branches: [ main ] # main branch (safer than PR), |
| 30 | + paths: # and we still have access to |
| 31 | + - "tests/**" # secrets for cloud creds. |
| 32 | + |
| 33 | +# ── 2️⃣ JOB DEFINITION (matrix fan-out) ───────────────────────── |
11 | 34 | jobs: |
12 | | - check-if-external: |
| 35 | + e2e: |
| 36 | + name: "E2E – ${{ matrix.project }}" # Shows up as “E2E – alpha” |
13 | 37 | runs-on: ubuntu-latest |
14 | | - outputs: |
15 | | - environment: ${{ steps.set-environment.outputs.result }} |
| 38 | + permissions: |
| 39 | + contents: read # read the repo |
| 40 | + id-token: write # (only if you OIDC into Azure, AWS, …) |
| 41 | + |
| 42 | + # Matrix drives one job per project. |
| 43 | + strategy: |
| 44 | + fail-fast: false # Don’t cancel others if one fails |
| 45 | + matrix: |
| 46 | + project: [ SAI_UAI, UAI] # <── ADD / REMOVE PROJECT_CLIENTS here |
| 47 | + |
| 48 | + # Map the matrix entry → matching Environment |
| 49 | + # e.g. alpha → project-alpha |
| 50 | + environment: project-${{ matrix.project }} |
| 51 | + |
| 52 | + # ── 3️⃣ STEPS ─────────────────────────────────────────────── |
16 | 53 | steps: |
17 | | - - uses: actions/github-script@v7 |
18 | | - id: set-environment |
19 | | - with: |
20 | | - script: | |
21 | | - const actionInitiator = context.payload.sender.login; |
22 | | - const org = "Azure-AI-Foundry"; |
23 | | - let isPublicMember = true; |
24 | 54 |
|
25 | | - // Check if initiator is a public member of the org |
26 | | - try { |
27 | | - await github.rest.orgs.checkPublicMembershipForUser({ |
28 | | - org, |
29 | | - username: actionInitiator |
30 | | - }); |
31 | | - } catch (error) { |
32 | | - if (error.status != 404) { |
33 | | - throw new Error("Unknown error", {cause: error}); |
34 | | - } |
| 55 | + # -- 3.1 Check out PR code ---------------------------------- |
| 56 | + - name: Checkout code |
| 57 | + uses: actions/checkout@v4 |
35 | 58 |
|
36 | | - console.debug([ |
37 | | - `User is not a public member of the organization "${org}"`, |
38 | | - "", |
39 | | - `If you are a Microsoft employee, you can join the "${org}" org and set your org membership visibility to public: https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-personal-account-on-github/managing-your-membership-in-organizations/publicizing-or-hiding-organization-membership#changing-the-visibility-of-your-organization-membership` |
40 | | - ].join("\n")); |
| 59 | + # -- 3.2 JavaScript / TypeScript (Vitest) ------------------- |
| 60 | + - name: Set up Node.js (for Vitest) |
| 61 | + uses: actions/setup-node@v4 |
| 62 | + with: |
| 63 | + node-version: "20" # use LTS; bump as needed |
| 64 | + cache: npm # built-in cache keyed by package-lock.json |
41 | 65 |
|
42 | | - isPublicMember = false; |
43 | | - } |
| 66 | + - name: Install JS dependencies |
| 67 | + run: npm ci |
44 | 68 |
|
| 69 | + - name: Run Vitest integration suite |
| 70 | + # Inject the secrets as environment variables that your app/tests read. |
| 71 | + env: |
| 72 | + PROJECT_CLIENT: ${{ secrets.PROJECT_CLIENT }} |
| 73 | + MODEL_DEPLOYMENT_NAME: ${{ secrets.MODEL_DEPLOYMENT_NAME }} |
| 74 | + run: | |
| 75 | + # Add any flags you like: coverage, reporters, etc. |
| 76 | + npx vitest run |
45 | 77 |
|
46 | | - const isPullRequestEvent = ["pull_request", "pull_request_target"].includes(context.eventName); |
| 78 | + # -- 3.3 .NET (dotnet test) --------------------------------- |
| 79 | + - name: Set up .NET SDK |
| 80 | + uses: actions/setup-dotnet@v4 |
| 81 | + with: |
| 82 | + dotnet-version: "8.0.x" # or 6.x / 7.x |
47 | 83 |
|
48 | | - if (!(isPublicMember && isPullRequestEvent)) { |
49 | | - return "external-contribution"; |
50 | | - } |
51 | | - return ""; |
52 | | - result-encoding: string |
53 | | - run-samples: |
54 | | - permissions: |
55 | | - contents: 'read' |
56 | | - id-token: 'write' |
57 | | - needs: check-if-external |
58 | | - runs-on: ubuntu-latest |
59 | | - # Require manual approval if initiator is not a public member of Azure-AI-Foundry |
60 | | - environment: ${{ needs.check-if-external.outputs.environment }} |
61 | | - steps: |
62 | | - - uses: actions/checkout@v4 |
63 | | - - uses: actions/checkout@v4 |
64 | | - with: |
65 | | - ref: ${{ github.event.pull_request.head.sha || github.ref }} |
66 | | - - uses: actions/setup-python@v5 |
67 | | - with: |
68 | | - python-version: "3.9" |
69 | | - - name: Install dev dependencies |
70 | | - run: | |
71 | | - pip install -r dev-requirements.txt |
72 | | - - uses: azure/login@v2 |
73 | | - with: |
74 | | - client-id: ${{ secrets.AZURE_CLIENT_ID }} |
75 | | - tenant-id: ${{ secrets.AZURE_TENANT_ID }} |
76 | | - subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} |
77 | | - - name: Deploy resources |
78 | | - run: | |
79 | | - principalId="$(az ad sp show --id ${{ secrets.AZURE_CLIENT_ID }} -o tsv --query id)" |
80 | | - az deployment sub create --location eastus \ |
81 | | - --template-file .infra/deployment/main.bicep \ |
82 | | - --parameters principalType=ServicePrincipal \ |
83 | | - --parameters principalId="$principalId" \ |
84 | | - -o json > deployment.json |
85 | | - - name: Run Changed Samples |
86 | | - run: |
87 | | - pytest --changed-samples-only-from ${{ github.event.pull_request.base.sha }} |
| 84 | + - name: Restore & build .NET projects |
| 85 | + run: dotnet restore |
| 86 | + |
| 87 | + - name: Run .NET tests |
| 88 | + env: |
| 89 | + PROJECT_CLIENT: ${{ secrets.PROJECT_CLIENT }} |
| 90 | + MODEL_DEPLOYMENT_NAME: ${{ secrets.MODEL_DEPLOYMENT_NAME }} |
| 91 | + run: | |
| 92 | + dotnet test --configuration Release --verbosity normal |
| 93 | +
|
| 94 | + # -- 3.4 Python / Pytest ------------------------- |
| 95 | + - name: Set up Python |
| 96 | + uses: actions/setup-python@v5 |
| 97 | + with: |
| 98 | + python-version: "3.9" |
| 99 | + cache: pip |
| 100 | + |
| 101 | + - name: Install Python deps |
| 102 | + run: pip install -r requirements.txt |
| 103 | + |
| 104 | + - name: Run pytest |
| 105 | + env: |
| 106 | + PROJECT_CLIENT: ${{ secrets.PROJECT_CLIENT }} |
| 107 | + MODEL_DEPLOYMENT_NAME: ${{ secrets.MODEL_DEPLOYMENT_NAME }} |
| 108 | + run: pytest -q |
0 commit comments