Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
70d1d16
Initial plan
Copilot Jun 29, 2026
108b93f
Apply remaining changes
Copilot Jun 29, 2026
a7b7e64
Apply remaining changes
Copilot Jun 29, 2026
e8f941b
Add redact-secrets integration test scaffolding
Copilot Jun 30, 2026
a9ca67c
Document bearer literal assertion in redaction integration validation
Copilot Jun 30, 2026
3f32c29
docs: extend integration prerequisite skill to redact-secrets workflow
Copilot Jun 30, 2026
9c0d46c
saving work
EMaher Jun 30, 2026
c1e3b2a
saving work
EMaher Jun 30, 2026
308f8ce
test: add debug logging to redact-secrets phase scripts
EMaher Jun 30, 2026
0a8ab60
adding pre-flight check for redaction markers.
EMaher Jun 30, 2026
1fb3f34
refactoring policy redaction check and warning
EMaher Jul 1, 2026
12e40b8
feat: add release-tests workflow for sequential test execution
EMaher Jun 30, 2026
22563e7
refactor: use ci.yml as reusable workflow, remove redundant test work…
EMaher Jun 30, 2026
2df69c6
feat: add redact-secrets integration test to release workflow
EMaher Jun 30, 2026
4a9a57b
fix: update log_level to use choice type with 'Log level' description
EMaher Jun 30, 2026
0873389
fix: remove APIM_SKU secret override, use input directly
EMaher Jun 30, 2026
8f854f4
fix: remove unnecessary Resolve Workflow Settings step
EMaher Jun 30, 2026
d6f24e0
docs: update integration-test-prerequisites skill for release-tests w…
EMaher Jun 30, 2026
c26fb74
feat: add monthly schedule to release-tests and document repo-level s…
EMaher Jul 1, 2026
f244ec1
refactor: remove secrets contract from called workflows, add validati…
EMaher Jul 1, 2026
54f3940
fix: make APIM_PUBLISHER_EMAIL optional with contoso.com fallback
EMaher Jul 1, 2026
a70cc67
Merge remote-tracking branch 'origin/main' into emaher-feat-release-t…
EMaher Jul 1, 2026
0ffb755
fix: remove duplicate step properties from merge conflict resolution
EMaher Jul 1, 2026
ec8dda7
feat: use choice type for sku/log_level inputs, add Azure region vali…
EMaher Jul 1, 2026
2c61605
fix: remove duplicate default key in release-tests.yml
EMaher Jul 1, 2026
0b50bed
refactor: extract defaults into workflow env variables
EMaher Jul 1, 2026
4bd549a
refactor: extract default values into env variables in release-tests.yml
EMaher Jul 1, 2026
171371c
fix: use env.DEFAULT_* instead of vars.DEFAULT_* in release-tests.yml
EMaher Jul 1, 2026
fa28c59
fix: add id-token permission and use vars context in release-tests.yml
EMaher Jul 1, 2026
1c243dd
refactor: rename workflow files to test-* convention
EMaher Jul 1, 2026
69417c4
refactor: rename test-all-types.yml to test-resource-types.yml
EMaher Jul 1, 2026
6351503
fix: rename workflow display name to 'Test: Release Tests'
EMaher Jul 1, 2026
b3f86cc
refactor: rename test-resource-types.yml to test-round-trip.yml
EMaher Jul 1, 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
22 changes: 17 additions & 5 deletions .github/skills/integration-test-prerequisites/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: "integration-test-prerequisites"
description: "Set up Azure and GitHub prerequisites for integration workflows using a user-assigned managed identity, OIDC federated credentials, RBAC roles, and environment secrets. Use when troubleshooting AADSTS70025/AADSTS700213 or authorization failures during integration-test or integration-redact-secrets workflow runs."
description: "Set up Azure and GitHub prerequisites for integration and release-tests workflows using a user-assigned managed identity, OIDC federated credentials, RBAC roles, and environment secrets. Use when troubleshooting AADSTS70025/AADSTS700213 or authorization failures during integration-test or release-tests workflow runs."
domain: "ci-cd"
confidence: "high"
source: "manual + observed from integration-test OIDC and RBAC troubleshooting"
Expand All @@ -10,14 +10,19 @@ source: "manual + observed from integration-test OIDC and RBAC troubleshooting"

Use this skill when preparing or repairing prerequisites for:

- `.github/workflows/integration-test.yml`
- `.github/workflows/integration-redact-secrets.yml`
- `.github/workflows/test-round-trip.yml` — Extract→Publish round-trip
- `.github/workflows/test-redact-secrets.yml` — Secret redaction validation
- `.github/workflows/test-all.yml` — Orchestrator that calls CI, then both integration-test workflows sequentially

All integration-test workflows share the same GitHub environment (`integration-test`) and Azure identity. Setting up prerequisites once covers all three workflows.

These workflows expect:
- OIDC login through `azure/login@v2`
- GitHub environment `integration-test` (shared by both workflows)
- OIDC login through `azure/login@v3`
- GitHub environment `integration-test` (shared by all integration workflows)
- Azure identity with enough permissions to deploy resources and create role assignments in test resource groups

The `test-all.yml` orchestrator calls `ci.yml` (no Azure prereqs), then `test-round-trip.yml` and `test-redact-secrets.yml`. The called workflows access secrets directly from the `integration-test` environment — no secret pass-through from the orchestrator is needed.

Preferred identity model: user-assigned managed identity (UAMI).

## Required Inputs
Expand Down Expand Up @@ -135,12 +140,19 @@ gh secret set AZURE_SUBSCRIPTION_ID \
--env "${GITHUB_ENVIRONMENT}" \
--body "${SUBSCRIPTION_ID}"

# Optional — falls back to apim-integration-test@contoso.com if not set
gh secret set APIM_PUBLISHER_EMAIL \
--repo "${GITHUB_OWNER}/${GITHUB_REPO}" \
--env "${GITHUB_ENVIRONMENT}" \
--body "${APIM_PUBLISHER_EMAIL}"
```

### 6) Verify Called Workflows Can Access Environment Secrets

The `test-all.yml` orchestrator does **not** pass secrets to called workflows. Instead, the called workflows (`test-round-trip.yml`, `test-redact-secrets.yml`) access secrets directly via their `environment: integration-test` declaration. Each called workflow includes a "Validate Required Secrets" step that fails fast with a clear error if any secret is missing.

No repo-level secrets are required — all secrets are scoped to the `integration-test` environment.

## Verification

```bash
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
pull_request:
branches:
- main
workflow_call:

permissions:
contents: read
Expand Down
68 changes: 68 additions & 0 deletions .github/workflows/test-all.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
# ===========================================================================
# Release Tests — Run all test suites in order before a release.
# ===========================================================================
# Executes unit tests, build-package integration tests, and the full
# extract→publish round-trip integration test sequentially. Fails fast:
# subsequent stages are skipped if any prior stage fails.
# ===========================================================================

name: "Test: Release Tests"

on:
schedule:
- cron: '0 9 1 * *' # 1st of every month at 9:00 UTC
workflow_dispatch:
inputs:
sku:
description: 'APIM SKU for all-types integration test'
required: true
type: choice
options:
- Standard
- StandardV2
- Premium
- PremiumV2
default: StandardV2
location:
description: 'Azure region for all-types integration test'
required: false
type: string
default: 'centralus'
log_level:
description: 'Log level'
required: false
type: choice
options:
- Info
- Verbose
- Debug
default: Verbose

permissions:
contents: read
Comment thread
Copilot marked this conversation as resolved.
id-token: write

jobs:
ci:
name: CI (Unit + Build Package Tests)
uses: ./.github/workflows/ci.yml

all-types-integration:
name: All-Types Integration Test
needs: ci
uses: ./.github/workflows/test-round-trip.yml
with:
sku: ${{ inputs.sku || vars.DEFAULT_SKU || 'StandardV2' }}
location: ${{ inputs.location || vars.DEFAULT_LOCATION || 'centralus' }}
log_level: ${{ inputs.log_level || vars.DEFAULT_LOG_LEVEL || 'Verbose' }}

redact-secrets-integration:
name: Redact Secrets Integration Test
needs: all-types-integration
uses: ./.github/workflows/test-redact-secrets.yml
with:
sku: ${{ inputs.sku || vars.DEFAULT_SKU || 'StandardV2' }}
location: ${{ inputs.location || vars.DEFAULT_LOCATION || 'centralus' }}
log_level: ${{ inputs.log_level || vars.DEFAULT_LOG_LEVEL || 'Verbose' }}
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,13 @@ on:
type: string
default: 'centralus'
log_level:
description: 'PowerShell log level (Info, Verbose, Debug)'
description: 'Log level'
required: false
type: string
type: choice
options:
- Info
- Verbose
- Debug
default: Verbose

workflow_call:
Expand All @@ -40,21 +44,10 @@ on:
type: string
default: 'centralus'
log_level:
description: 'PowerShell log level (Info, Verbose, Debug)'
description: 'Log level'
required: false
type: string
default: Verbose
secrets:
AZURE_CLIENT_ID:
required: true
AZURE_TENANT_ID:
required: true
AZURE_SUBSCRIPTION_ID:
required: true
APIM_PUBLISHER_EMAIL:
required: true
APIM_SKU:
required: false

permissions:
id-token: write
Expand All @@ -64,6 +57,10 @@ concurrency:
group: integration-redact-secrets
cancel-in-progress: false

env:
DEFAULT_LOCATION: centralus
DEFAULT_PUBLISHER_EMAIL: apim-integration-test@contoso.com

jobs:
redact-secrets-test:
name: Extract Secret Redaction
Expand All @@ -82,22 +79,17 @@ jobs:

- run: npm ci && npm run build

- name: Resolve Workflow Settings
id: settings
shell: pwsh
- name: Validate Required Secrets
shell: bash
run: |
$logLevel = '${{ inputs.log_level }}'
if ([string]::IsNullOrWhiteSpace($logLevel)) { $logLevel = 'Verbose' }
if ($logLevel -notin @('Info', 'Verbose', 'Debug')) {
throw "Invalid log_level '$logLevel'. Allowed values: Info, Verbose, Debug."
}

$skuName = '${{ secrets.APIM_SKU }}'
if ([string]::IsNullOrWhiteSpace($skuName)) { $skuName = '${{ inputs.sku }}' }
if ([string]::IsNullOrWhiteSpace($skuName)) { $skuName = 'StandardV2' }

"logLevel=$logLevel" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
"skuName=$skuName" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
missing=()
[[ -z "${{ secrets.AZURE_CLIENT_ID }}" ]] && missing+=("AZURE_CLIENT_ID")
[[ -z "${{ secrets.AZURE_TENANT_ID }}" ]] && missing+=("AZURE_TENANT_ID")
[[ -z "${{ secrets.AZURE_SUBSCRIPTION_ID }}" ]] && missing+=("AZURE_SUBSCRIPTION_ID")
if [[ ${#missing[@]} -gt 0 ]]; then
echo "::error::Missing required secrets: ${missing[*]}"
exit 1
fi

- name: Azure Login
uses: azure/login@v3
Expand All @@ -106,6 +98,17 @@ jobs:
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

- name: Validate Azure Region
shell: bash
run: |
LOCATION="${{ inputs.location }}"
if [[ -z "$LOCATION" ]]; then LOCATION="${{ env.DEFAULT_LOCATION }}"; fi
VALID_LOCATIONS=$(az account list-locations --query "[].name" -o tsv)
if ! echo "$VALID_LOCATIONS" | grep -qx "$LOCATION"; then
echo "::error::Invalid Azure region: '$LOCATION'. Run 'az account list-locations --query [].name' to see valid options."
exit 1
fi

- name: Run redaction integration test
shell: pwsh
env:
Expand All @@ -114,7 +117,7 @@ jobs:
run: |
./tests/integration/redact-secrets/run-redact-secrets-test.ps1 `
-SourceSubscriptionId '${{ secrets.AZURE_SUBSCRIPTION_ID }}' `
-PublisherEmail '${{ secrets.APIM_PUBLISHER_EMAIL }}' `
-SkuName '${{ steps.settings.outputs.skuName }}' `
-PublisherEmail '${{ secrets.APIM_PUBLISHER_EMAIL || env.DEFAULT_PUBLISHER_EMAIL }}' `
-SkuName '${{ inputs.sku }}' `
-Location '${{ inputs.location }}' `
-LogLevel '${{ steps.settings.outputs.logLevel }}'
-LogLevel '${{ inputs.log_level }}'
Loading