From 209277cbb24ae2dcd2ee3af44fcb545e7c437cfe Mon Sep 17 00:00:00 2001 From: willdavsmith Date: Tue, 17 Feb 2026 08:44:15 -0800 Subject: [PATCH 01/24] Terraform workflow updates Signed-off-by: willdavsmith --- .github/workflows/functional-test-cloud.yaml | 2 +- .github/workflows/long-running-azure.yaml | 6 +++--- bicep-types | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) create mode 160000 bicep-types diff --git a/.github/workflows/functional-test-cloud.yaml b/.github/workflows/functional-test-cloud.yaml index 2333028343..e98ddc1050 100644 --- a/.github/workflows/functional-test-cloud.yaml +++ b/.github/workflows/functional-test-cloud.yaml @@ -84,7 +84,7 @@ env: # Private Git repository where terraform module for testing is stored. TF_RECIPE_PRIVATE_GIT_SOURCE: git::https://github.com/radius-project/terraform-private-modules//kubernetes-redis # bicep-types ACR url for uploading Radius Bicep types - BICEP_TYPES_REGISTRY: biceptypes.azurecr.io + BICEP_TYPES_REGISTRY: ${{ vars.BICEP_TYPES_REGISTRY }} # Kubernetes client QPS and Burst settings for high-concurrency CI environments RADIUS_QPS_AND_BURST: "800" diff --git a/.github/workflows/long-running-azure.yaml b/.github/workflows/long-running-azure.yaml index 1e9d85089b..98b574e771 100644 --- a/.github/workflows/long-running-azure.yaml +++ b/.github/workflows/long-running-azure.yaml @@ -57,7 +57,7 @@ env: # Container registry for storing Bicep recipe artifacts BICEP_RECIPE_REGISTRY: ghcr.io/radius-project/dev # ACR url for uploading test UDT Bicep types - TEST_BICEP_TYPES_REGISTRY: testuserdefinedbiceptypes.azurecr.io + TEST_BICEP_TYPES_REGISTRY: ${{ vars.TEST_BICEP_TYPES_REGISTRY }} # The radius functional test timeout FUNCTIONALTEST_TIMEOUT: 60m # The Azure Location to store test resources @@ -71,9 +71,9 @@ env: FUNCTIONAL_TEST_APP_ID: 425843 # The AKS cluster name - AKS_CLUSTER_NAME: radlrtest00-aks + AKS_CLUSTER_NAME: ${{ vars.LRT_AKS_CLUSTER_NAME }} # The resource group for AKS_CLUSTER_NAME resource. - AKS_RESOURCE_GROUP: radlrtest00 + AKS_RESOURCE_GROUP: ${{ vars.LRT_AKS_RESOURCE_GROUP }} # Server where terraform test modules are deployed TF_RECIPE_MODULE_SERVER_URL: http://tf-module-server.radius-test-tf-module-server.svc.cluster.local diff --git a/bicep-types b/bicep-types new file mode 160000 index 0000000000..556bf5edad --- /dev/null +++ b/bicep-types @@ -0,0 +1 @@ +Subproject commit 556bf5edad58e47ca57c6ddb1af155c3bcfdc5c7 From c69e6eca900bb8539f85ec3da4cd5954902eb8d9 Mon Sep 17 00:00:00 2001 From: willdavsmith Date: Tue, 17 Feb 2026 13:04:49 -0800 Subject: [PATCH 02/24] Fork-able Signed-off-by: willdavsmith --- .github/workflows/functional-test-cloud.yaml | 58 ++++++++----------- .../workflows/functional-test-noncloud.yaml | 14 ++--- .github/workflows/long-running-azure.yaml | 51 +++++++--------- 3 files changed, 54 insertions(+), 69 deletions(-) diff --git a/.github/workflows/functional-test-cloud.yaml b/.github/workflows/functional-test-cloud.yaml index e98ddc1050..df12ab0898 100644 --- a/.github/workflows/functional-test-cloud.yaml +++ b/.github/workflows/functional-test-cloud.yaml @@ -62,13 +62,13 @@ env: # Azure workload identity webhook chart version AZURE_WORKLOAD_IDENTITY_WEBHOOK_VER: 1.3.0 # Container registry for storing container images - CONTAINER_REGISTRY: ghcr.io/radius-project/dev + CONTAINER_REGISTRY: ${{ vars.FUNCTIONAL_TEST_CONTAINER_REGISTRY || 'ghcr.io/radius-project/dev' }} # Container registry for storing Bicep recipe artifacts - BICEP_RECIPE_REGISTRY: ghcr.io/radius-project/dev + BICEP_RECIPE_REGISTRY: ${{ vars.FUNCTIONAL_TEST_BICEP_RECIPE_REGISTRY || 'ghcr.io/radius-project/dev' }} # The radius functional test timeout FUNCTIONALTEST_TIMEOUT: 60m # The Azure Location to store test resources - AZURE_LOCATION: westus3 + AZURE_LOCATION: westus2 # The base directory for storing test logs RADIUS_CONTAINER_LOG_BASE: dist/container_logs # The Radius helm chart location. @@ -80,7 +80,7 @@ env: # Server where terraform test modules are deployed TF_RECIPE_MODULE_SERVER_URL: http://tf-module-server.radius-test-tf-module-server.svc.cluster.local # The functional test GitHub app id - FUNCTIONAL_TEST_APP_ID: 425843 + FUNCTIONAL_TEST_APP_ID: ${{ vars.FUNCTIONAL_TEST_APP_ID || '425843' }} # Private Git repository where terraform module for testing is stored. TF_RECIPE_PRIVATE_GIT_SOURCE: git::https://github.com/radius-project/terraform-private-modules//kubernetes-redis # bicep-types ACR url for uploading Radius Bicep types @@ -119,7 +119,7 @@ jobs: if: | always() && (github.event_name != 'pull_request_target' || needs.approval-gate.result == 'success' || needs.approval-gate.result == 'skipped') && - (github.event_name != 'schedule' || github.repository == 'radius-project/radius') + (github.event_name != 'schedule' || github.repository == vars.RADIUS_REPOSITORY) runs-on: ubuntu-24.04 timeout-minutes: 5 permissions: @@ -253,7 +253,7 @@ jobs: ACTION_LINK: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} steps: - name: Get GitHub app token - if: github.repository == 'radius-project/radius' + if: github.repository == vars.RADIUS_REPOSITORY uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1 id: get_installation_token with: @@ -434,8 +434,7 @@ jobs: "extensibility": true }, "extensions": { - "radius": "br:${{ env.BICEP_TYPES_REGISTRY }}/test/radius:$RADIUS_VERSION", - "aws": "br:${{ env.BICEP_TYPES_REGISTRY }}/aws:latest" + "radius": "br:${{ env.BICEP_TYPES_REGISTRY }}/test/radius:$RADIUS_VERSION" } } EOF @@ -486,7 +485,7 @@ jobs: contents: read # Required for listing the commits steps: - name: Get GitHub app token - if: github.repository == 'radius-project/radius' + if: github.repository == vars.RADIUS_REPOSITORY uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1 id: get_installation_token with: @@ -520,6 +519,7 @@ jobs: id-token: write # Required for requesting the JWT contents: read # Required for listing the commits checks: write # Required for publishing test results + packages: read # Required for pulling images from ghcr.io inside KinD env: UNIQUE_ID: ${{ needs.setup.outputs.UNIQUE_ID }} REL_VERSION: ${{ needs.setup.outputs.REL_VERSION }} @@ -533,16 +533,13 @@ jobs: DE_TAG: ${{ needs.setup.outputs.DE_TAG }} steps: - name: Get GitHub app token - if: github.repository == 'radius-project/radius' + if: github.repository == vars.RADIUS_REPOSITORY uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1 id: get_installation_token with: app-id: ${{ env.FUNCTIONAL_TEST_APP_ID }} private-key: ${{ secrets.FUNCTIONAL_TEST_APP_PRIVATE_KEY }} owner: ${{ github.repository_owner }} - repositories: | - radius - terraform-private-modules permission-checks: write permission-pull-requests: write permission-contents: read @@ -622,9 +619,10 @@ jobs: # The role-to-assume is the role that the github action will assume to execute aws commands and # construct cloud control client in test code. - name: configure aws credentials using assumed role + if: false uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # v6.0.0 with: - role-to-assume: ${{ secrets.AWS_GH_ACTIONS_ROLE }} + # role-to-assume: ${{ secrets.AWS_GH_ACTIONS_ROLE }} role-session-name: GitHub_to_AWS_via_FederatedOIDC aws-region: ${{ env.AWS_REGION }} @@ -640,7 +638,7 @@ jobs: # AZURE_OIDC_ISSUER eval "export $(echo "${{ secrets.FUNCTEST_AZURE_OIDC_JSON }}" | jq -r 'to_entries | map("\(.key)=\(.value)") | @sh')" - AUTHKEY=$(echo -n "${{ github.actor }}:${{ secrets.GH_RAD_CI_BOT_PAT }}" | base64) + AUTHKEY=$(echo -n "${{ github.actor }}:${{ github.token }}" | base64) echo "{\"auths\":{\"ghcr.io\":{\"auth\":\"${AUTHKEY}\"}}}" > "./ghcr_secret.json" # Create KinD cluster with OIDC Issuer keys @@ -724,8 +722,7 @@ jobs: --set ucp.image=${{ env.CONTAINER_REGISTRY }}/ucpd,ucp.tag=${{ env.REL_VERSION }} \ --set de.image=${{ env.DE_IMAGE }},de.tag=${{ env.DE_TAG }} \ --set bicep.image=${{ env.CONTAINER_REGISTRY }}/bicep,bicep.tag=${{ env.REL_VERSION }} \ - --set global.azureWorkloadIdentity.enabled=true \ - --set global.aws.irsa.enabled=true + --set global.azureWorkloadIdentity.enabled=true echo "*** Verify manifests are registered ***" rm -f registermanifest_logs.txt @@ -787,11 +784,7 @@ jobs: --client-id ${{ secrets.AZURE_SP_TESTS_APPID }} \ --tenant-id ${{ secrets.AZURE_SP_TESTS_TENANTID }} - echo "*** Configuring AWS provider ***" - rad env update kind-radius --aws-region ${{ env.AWS_REGION }} --aws-account-id ${{ secrets.FUNCTEST_AWS_ACCOUNT_ID }} - - rad credential register aws irsa \ - --iam-role ${{ secrets.FUNC_TEST_RAD_IRSA_ROLE }} + echo "*** Skipping AWS provider configuration for this run ***" - uses: marocchino/sticky-pull-request-comment@773744901bac0e8cbb5a0dc842800d45e9b2b405 # v2.9.4 if: failure() && env.PR_NUMBER != '' @@ -820,8 +813,7 @@ jobs: "extensibility": true }, "extensions": { - "radius": "br:${{ env.BICEP_TYPES_REGISTRY }}/test/radius:$RADIUS_VERSION", - "aws": "br:${{ env.BICEP_TYPES_REGISTRY }}/aws:latest" + "radius": "br:${{ env.BICEP_TYPES_REGISTRY }}/test/radius:$RADIUS_VERSION" }, "cloud": { "credentialPrecedence": ["Environment"] @@ -829,12 +821,10 @@ jobs: } EOF - name: Restore Bicep artifacts before running functional tests - # The exact files chosen to run the command can be changed, but we need 1 that uses the Radius extension and 1 that uses the AWS extension so we can restore both Bicep artifacts before the tests start + # Restore the Radius extension artifact used by Azure cloud tests. run: | # Restore Radius Bicep types bicep restore ./test/functional-portable/corerp/cloud/resources/testdata/corerp-azure-connection-database-service.bicep --force - # Restore AWS Bicep types - bicep restore ./test/functional-portable/corerp/cloud/resources/testdata/aws-logs-loggroup.bicep --force - name: Run functional tests run: | # Ensure rad cli is in path before running tests. @@ -858,7 +848,7 @@ jobs: TEST_TIMEOUT: ${{ env.FUNCTIONALTEST_TIMEOUT }} RADIUS_CONTAINER_LOG_PATH: ${{ github.workspace }}/${{ env.RADIUS_CONTAINER_LOG_BASE }} AWS_REGION: ${{ env.AWS_REGION }} - AWS_ACCOUNT_ID: ${{ secrets.FUNCTEST_AWS_ACCOUNT_ID }} + # AWS_ACCOUNT_ID: ${{ secrets.FUNCTEST_AWS_ACCOUNT_ID }} RADIUS_SAMPLES_REPO_ROOT: ${{ github.workspace }}/samples # Test_MongoDB_Recipe_Parameters is using the following environment variable. INTEGRATION_TEST_RESOURCE_GROUP_NAME: ${{ env.AZURE_TEST_RESOURCE_GROUP }} @@ -867,12 +857,13 @@ jobs: BICEP_RECIPE_REGISTRY: ${{ env.BICEP_RECIPE_REGISTRY }} BICEP_RECIPE_TAG_VERSION: ${{ env.BICEP_RECIPE_TAG_VERSION }} GH_TOKEN: ${{ steps.get_installation_token.outputs.token }} + GOTEST_OPTS: -skip AWS\|TerraformPrivateGitModule GOTESTSUM_OPTS: --junitfile ./dist/functional_test/results.xml - name: Process Functional Test Results uses: ./.github/actions/process-test-results # In case of failure, upload functional_test_results to artifacts so that they are not erased by subsequent runs. - if: failure() && github.repository == 'radius-project/radius' + if: failure() && github.repository == vars.RADIUS_REPOSITORY with: test_group_name: Functional Tests - ${{ matrix.name }} artifact_name: functional_test_results_${{ matrix.name }} @@ -965,7 +956,7 @@ jobs: report-test-results: # Report final test status. Runs after all tests complete (or are skipped). - if: always() && github.repository == 'radius-project/radius' + if: always() && github.repository == vars.RADIUS_REPOSITORY name: Report test results needs: [setup, build, tests] runs-on: ubuntu-24.04 @@ -1023,13 +1014,14 @@ jobs: needs: [build, tests] runs-on: ubuntu-24.04 timeout-minutes: 5 - permissions: {} - if: failure() && github.event_name == 'schedule' && github.repository == 'radius-project/radius' + permissions: + issues: write + if: failure() && github.event_name == 'schedule' && github.repository == vars.RADIUS_REPOSITORY steps: - name: Create failure issue for failing scheduled run uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 with: - github-token: ${{ secrets.GH_RAD_CI_BOT_PAT }} + github-token: ${{ github.token }} script: | github.rest.issues.create({ ...context.repo, diff --git a/.github/workflows/functional-test-noncloud.yaml b/.github/workflows/functional-test-noncloud.yaml index 2d8905b201..643d467405 100644 --- a/.github/workflows/functional-test-noncloud.yaml +++ b/.github/workflows/functional-test-noncloud.yaml @@ -265,8 +265,7 @@ jobs: "extensibility": true }, "extensions": { - "radius": "br:${{ env.LOCAL_REGISTRY_SERVER }}:${{ env.LOCAL_REGISTRY_PORT }}/radius:$RADIUS_VERSION", - "aws": "br:${{ env.BICEP_TYPES_REGISTRY }}/aws:latest" + "radius": "br:${{ env.LOCAL_REGISTRY_SERVER }}:${{ env.LOCAL_REGISTRY_PORT }}/radius:$RADIUS_VERSION" } } EOF @@ -462,7 +461,6 @@ jobs: }, "extensions": { "radius": "br:${{ env.LOCAL_REGISTRY_SERVER }}:${{ env.LOCAL_REGISTRY_PORT }}/radius:$RADIUS_VERSION", - "aws": "br:${{ env.BICEP_TYPES_REGISTRY }}/aws:latest", "testresources": "br:${{ env.LOCAL_REGISTRY_SERVER }}:${{ env.LOCAL_REGISTRY_PORT }}/testresources:$RADIUS_VERSION" } } @@ -501,6 +499,7 @@ jobs: BICEP_RECIPE_REGISTRY: ${{ env.LOCAL_REGISTRY_NAME }}:${{ env.LOCAL_REGISTRY_PORT }} BICEP_RECIPE_TAG_VERSION: ${{ env.BICEP_RECIPE_TAG_VERSION }} GH_TOKEN: ${{ github.token }} + GOTEST_OPTS: -skip AWS\|TerraformPrivateGitModule GOTESTSUM_OPTS: --junitfile ./dist/functional_test/results.xml RADIUS_TEST_FAST_CLEANUP: true GIT_HTTP_PASSWORD: ${{ env.GIT_HTTP_PASSWORD }} @@ -508,7 +507,7 @@ jobs: - name: Process Functional Test Results uses: ./.github/actions/process-test-results # In case of failure, upload functional_test_results to artifacts so that they are not erased by subsequent runs. - if: failure() && github.repository == 'radius-project/radius' + if: failure() && github.repository == vars.RADIUS_REPOSITORY with: test_group_name: Functional Tests - ${{ matrix.name }} artifact_name: functional_test_results_${{ matrix.name }} @@ -584,17 +583,18 @@ jobs: if-no-files-found: error report-failure: - if: failure() && github.event_name == 'schedule' && github.repository == 'radius-project/radius' && needs.changes.outputs.only_changed != 'true' + if: failure() && github.event_name == 'schedule' && github.repository == vars.RADIUS_REPOSITORY && needs.changes.outputs.only_changed != 'true' name: Report test failure needs: [changes, build, tests] runs-on: ubuntu-24.04 timeout-minutes: 5 - permissions: {} + permissions: + issues: write steps: - name: Create failure issue for failing scheduled run uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 with: - github-token: ${{ secrets.GH_RAD_CI_BOT_PAT }} + github-token: ${{ github.token }} script: | github.rest.issues.create({ ...context.repo, diff --git a/.github/workflows/long-running-azure.yaml b/.github/workflows/long-running-azure.yaml index 98b574e771..706cd90267 100644 --- a/.github/workflows/long-running-azure.yaml +++ b/.github/workflows/long-running-azure.yaml @@ -55,20 +55,20 @@ env: GOTESTSUM_VER: 1.13.0 # Container registry for storing Bicep recipe artifacts - BICEP_RECIPE_REGISTRY: ghcr.io/radius-project/dev - # ACR url for uploading test UDT Bicep types - TEST_BICEP_TYPES_REGISTRY: ${{ vars.TEST_BICEP_TYPES_REGISTRY }} + BICEP_RECIPE_REGISTRY: ${{ vars.FUNCTIONAL_TEST_BICEP_RECIPE_REGISTRY || 'ghcr.io/radius-project/dev' }} + # Shared ACR for Radius and UDT Bicep types (different artifact paths/tags). + BICEP_TYPES_REGISTRY: ${{ vars.BICEP_TYPES_REGISTRY }} # The radius functional test timeout FUNCTIONALTEST_TIMEOUT: 60m # The Azure Location to store test resources - AZURE_LOCATION: westus3 + AZURE_LOCATION: westus2 # The base directory for storing test logs RADIUS_CONTAINER_LOG_BASE: dist/container_logs # The region for AWS resources AWS_REGION: us-west-2 # The functional test GitHub app id - FUNCTIONAL_TEST_APP_ID: 425843 + FUNCTIONAL_TEST_APP_ID: ${{ vars.FUNCTIONAL_TEST_APP_ID || '425843' }} # The AKS cluster name AKS_CLUSTER_NAME: ${{ vars.LRT_AKS_CLUSTER_NAME }} @@ -95,7 +95,7 @@ env: jobs: tests: - if: github.repository == 'radius-project/radius' + if: github.repository == vars.RADIUS_REPOSITORY name: Run functional tests runs-on: ubuntu-24.04 timeout-minutes: 120 @@ -113,7 +113,7 @@ jobs: echo "AZURE_TEST_RESOURCE_GROUP=radtest-${UNIQUE_ID}" >> "${GITHUB_OUTPUT}" - name: Get GitHub app token - if: github.repository == 'radius-project/radius' + if: github.repository == vars.RADIUS_REPOSITORY uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1 id: get_installation_token with: @@ -126,9 +126,6 @@ jobs: # already-expired tokens in workflows that exceed the 1-hour token lifetime. skip-token-revoke: true owner: ${{ github.repository_owner }} - repositories: | - radius - terraform-private-modules permission-contents: read - name: Checkout @@ -237,7 +234,7 @@ jobs: run: | export PATH=$GITHUB_WORKSPACE/bin:$PATH which rad || { echo "cannot find rad"; exit 1; } - rad bicep publish-extension -f "./${RELEASE_DIR}/test/functional-portable/dynamicrp/noncloud/resources/testdata/testresourcetypes.yaml" --target "br:${TEST_BICEP_TYPES_REGISTRY}/testresources:latest" --force + rad bicep publish-extension -f "./${RELEASE_DIR}/test/functional-portable/dynamicrp/noncloud/resources/testdata/testresourcetypes.yaml" --target "br:${BICEP_TYPES_REGISTRY}/testresources:latest" --force env: RELEASE_DIR: ${{ steps.checkout-release-codebase.outputs.release-dir }} @@ -295,10 +292,7 @@ jobs: --client-id ${{ secrets.AZURE_SP_TESTS_APPID }} \ --tenant-id ${{ secrets.AZURE_SP_TESTS_TENANTID }} - echo "*** Configuring AWS provider ***" - rad env update ${{ env.RADIUS_TEST_ENVIRONMENT_NAME }} --aws-region ${{ env.AWS_REGION }} --aws-account-id ${{ secrets.FUNCTEST_AWS_ACCOUNT_ID }} - rad credential register aws access-key \ - --access-key-id ${{ secrets.FUNCTEST_AWS_ACCESS_KEY_ID }} --secret-access-key ${{ secrets.FUNCTEST_AWS_SECRET_ACCESS_KEY }} + echo "*** Skipping AWS provider configuration for this run ***" - name: Log radius installation status (failure) if: failure() @@ -337,14 +331,11 @@ jobs: echo "FUNCTEST_OIDC_ISSUER=$(az aks show -n ${{ env.AKS_CLUSTER_NAME }} -g ${{ env.AKS_RESOURCE_GROUP }} --query "oidcIssuerProfile.issuerUrl" -otsv)" >> $GITHUB_OUTPUT - name: Restore Bicep artifacts before running functional tests - # The exact files chosen to run the command can be changed, but we need 1 that uses the Radius extension, 1 that uses the AWS extension and 1 that uses UDT testresources - # so we can restore all Bicep artifacts before the tests start. - run: | - # Restore Radius Bicep types - bicep restore "./${RELEASE_DIR}/test/functional-portable/corerp/cloud/resources/testdata/corerp-azure-connection-database-service.bicep" --force - # Restore AWS Bicep types - bicep restore "./${RELEASE_DIR}/test/functional-portable/corerp/cloud/resources/testdata/aws-s3-bucket.bicep" --force - env: + # Restore the Radius extension artifact used by Azure cloud tests. + run: | + # Restore Radius Bicep types + bicep restore "./${RELEASE_DIR}/test/functional-portable/corerp/cloud/resources/testdata/corerp-azure-connection-database-service.bicep" --force + env: RELEASE_DIR: ${{ steps.checkout-release-codebase.outputs.release-dir }} - name: Run functional tests @@ -353,10 +344,10 @@ jobs: UNIQUE_ID: ${{ steps.gen-id.outputs.UNIQUE_ID }} TEST_TIMEOUT: ${{ env.FUNCTIONALTEST_TIMEOUT }} RADIUS_CONTAINER_LOG_PATH: ${{ github.workspace }}/${{ env.RADIUS_CONTAINER_LOG_BASE }} - AWS_ACCESS_KEY_ID: ${{ secrets.FUNCTEST_AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.FUNCTEST_AWS_SECRET_ACCESS_KEY }} + # AWS_ACCESS_KEY_ID: ${{ secrets.FUNCTEST_AWS_ACCESS_KEY_ID }} + # AWS_SECRET_ACCESS_KEY: ${{ secrets.FUNCTEST_AWS_SECRET_ACCESS_KEY }} AWS_REGION: ${{ env.AWS_REGION }} - AWS_ACCOUNT_ID: ${{ secrets.FUNCTEST_AWS_ACCOUNT_ID }} + # AWS_ACCOUNT_ID: ${{ secrets.FUNCTEST_AWS_ACCOUNT_ID }} RADIUS_SAMPLES_REPO_ROOT: ${{ github.workspace }}/samples # Test_MongoDB_Recipe_Parameters is using the following environment variable. INTEGRATION_TEST_RESOURCE_GROUP_NAME: ${{ steps.gen-id.outputs.AZURE_TEST_RESOURCE_GROUP }} @@ -367,6 +358,7 @@ jobs: BICEP_RECIPE_TAG_VERSION: ${{ steps.gen-id.outputs.UNIQUE_ID }} GH_TOKEN: ${{ steps.get_installation_token.outputs.token }} GIT_HTTP_PASSWORD: ${{ env.GIT_HTTP_PASSWORD }} + GOTEST_OPTS: -skip AWS\|TerraformPrivateGitModule working-directory: ${{ steps.checkout-release-codebase.outputs.release-dir }} run: | # Ensure rad cli is in path before running tests. @@ -452,17 +444,18 @@ jobs: ./.github/scripts/cleanup-long-running-cluster.sh skip-delete-resources-list.txt report-failure: - if: failure() && github.repository == 'radius-project/radius' && github.event_name == 'schedule' + if: failure() && github.repository == vars.RADIUS_REPOSITORY && github.event_name == 'schedule' name: Report test failure needs: [tests] runs-on: ubuntu-24.04 timeout-minutes: 5 - permissions: {} + permissions: + issues: write steps: - name: Create failure issue for failing long running test run uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 with: - github-token: ${{ secrets.GH_RAD_CI_BOT_PAT }} + github-token: ${{ github.token }} script: | github.rest.issues.create({ ...context.repo, From 6b0773aa8af88a59595c68c01ddcda6d31ccd22e Mon Sep 17 00:00:00 2001 From: willdavsmith Date: Tue, 17 Feb 2026 13:09:52 -0800 Subject: [PATCH 03/24] Remove stale bicep-types submodule entry --- bicep-types | 1 - 1 file changed, 1 deletion(-) delete mode 160000 bicep-types diff --git a/bicep-types b/bicep-types deleted file mode 160000 index 556bf5edad..0000000000 --- a/bicep-types +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 556bf5edad58e47ca57c6ddb1af155c3bcfdc5c7 From 790ea7f58e845277697374181e0f72e0e3584b35 Mon Sep 17 00:00:00 2001 From: willdavsmith Date: Tue, 17 Feb 2026 13:25:41 -0800 Subject: [PATCH 04/24] fix Signed-off-by: willdavsmith --- .github/workflows/functional-test-noncloud.yaml | 4 +++- bicep-types | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) create mode 160000 bicep-types diff --git a/.github/workflows/functional-test-noncloud.yaml b/.github/workflows/functional-test-noncloud.yaml index 643d467405..69573baf64 100644 --- a/.github/workflows/functional-test-noncloud.yaml +++ b/.github/workflows/functional-test-noncloud.yaml @@ -265,7 +265,8 @@ jobs: "extensibility": true }, "extensions": { - "radius": "br:${{ env.LOCAL_REGISTRY_SERVER }}:${{ env.LOCAL_REGISTRY_PORT }}/radius:$RADIUS_VERSION" + "radius": "br:${{ env.LOCAL_REGISTRY_SERVER }}:${{ env.LOCAL_REGISTRY_PORT }}/radius:$RADIUS_VERSION", + "aws": "br:${{ env.BICEP_TYPES_REGISTRY }}/aws:latest" } } EOF @@ -461,6 +462,7 @@ jobs: }, "extensions": { "radius": "br:${{ env.LOCAL_REGISTRY_SERVER }}:${{ env.LOCAL_REGISTRY_PORT }}/radius:$RADIUS_VERSION", + "aws": "br:${{ env.BICEP_TYPES_REGISTRY }}/aws:latest", "testresources": "br:${{ env.LOCAL_REGISTRY_SERVER }}:${{ env.LOCAL_REGISTRY_PORT }}/testresources:$RADIUS_VERSION" } } diff --git a/bicep-types b/bicep-types new file mode 160000 index 0000000000..556bf5edad --- /dev/null +++ b/bicep-types @@ -0,0 +1 @@ +Subproject commit 556bf5edad58e47ca57c6ddb1af155c3bcfdc5c7 From 3390ac82d9375f6b43159a0375b297237e376246 Mon Sep 17 00:00:00 2001 From: willdavsmith Date: Tue, 17 Feb 2026 13:26:51 -0800 Subject: [PATCH 05/24] Remove stray bicep-types gitlink --- bicep-types | 1 - 1 file changed, 1 deletion(-) delete mode 160000 bicep-types diff --git a/bicep-types b/bicep-types deleted file mode 160000 index 556bf5edad..0000000000 --- a/bicep-types +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 556bf5edad58e47ca57c6ddb1af155c3bcfdc5c7 From 50403adb36ca3a7279d4d4f6a792749ea70123e3 Mon Sep 17 00:00:00 2001 From: willdavsmith Date: Tue, 17 Feb 2026 13:48:31 -0800 Subject: [PATCH 06/24] Run clouds Signed-off-by: willdavsmith --- .github/workflows/functional-test-cloud.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/functional-test-cloud.yaml b/.github/workflows/functional-test-cloud.yaml index ba66abd267..aae2ebc92c 100644 --- a/.github/workflows/functional-test-cloud.yaml +++ b/.github/workflows/functional-test-cloud.yaml @@ -219,6 +219,7 @@ jobs: changes: name: Changes needs: setup + if: always() && needs.setup.result == 'success' uses: ./.github/workflows/__changes.yml with: ref: ${{ needs.setup.outputs.CHECKOUT_REF }} @@ -232,7 +233,7 @@ jobs: name: Build Radius for test needs: [setup, changes] # Skip if only docs/markdown changed - if: needs.changes.outputs.only_changed != 'true' + if: always() && needs.changes.outputs.only_changed != 'true' runs-on: ubuntu-24.04 timeout-minutes: 15 permissions: @@ -478,7 +479,7 @@ jobs: skip-tests: name: Skip Functional Tests needs: [setup, changes] - if: needs.changes.outputs.only_changed == 'true' + if: always() && needs.changes.outputs.only_changed == 'true' runs-on: ubuntu-24.04 timeout-minutes: 5 permissions: @@ -507,6 +508,7 @@ jobs: tests: name: Run ${{ matrix.name }} functional tests needs: [setup, build] + if: always() && needs.setup.result == 'success' && needs.build.result == 'success' # Approval gate (via environment protection) ensures external contributors are approved before reaching here strategy: fail-fast: true From 748c705de818dc2c5ab47d7978ca62a262a40cbc Mon Sep 17 00:00:00 2001 From: willdavsmith Date: Tue, 17 Feb 2026 14:27:51 -0800 Subject: [PATCH 07/24] Skip AWS Signed-off-by: willdavsmith --- .github/scripts/publish-recipes.sh | 6 ++++++ .github/workflows/functional-test-cloud.yaml | 1 + .github/workflows/functional-test-noncloud.yaml | 1 + .github/workflows/long-running-azure.yaml | 1 + 4 files changed, 9 insertions(+) diff --git a/.github/scripts/publish-recipes.sh b/.github/scripts/publish-recipes.sh index 4b3271c762..e05b4908b7 100755 --- a/.github/scripts/publish-recipes.sh +++ b/.github/scripts/publish-recipes.sh @@ -63,6 +63,12 @@ for RECIPE in $(find "$DIRECTORY" -type f -name "*.bicep"); do continue fi + # Optionally skip AWS recipes when workflows disable AWS tests/providers. + if [[ "${SKIP_AWS_RECIPES:-false}" == "true" && "$FILENAME" =~ [Aa][Ww][Ss] ]]; then + echo "Skipping $RECIPE (AWS recipe skipped: SKIP_AWS_RECIPES=true)" + continue + fi + echo "Publishing $RECIPE to $PUBLISH_REF" echo "- $PUBLISH_REF" >>$GITHUB_STEP_SUMMARY rad bicep publish --file $RECIPE --target "br:$PUBLISH_REF" diff --git a/.github/workflows/functional-test-cloud.yaml b/.github/workflows/functional-test-cloud.yaml index aae2ebc92c..3bcec0e653 100644 --- a/.github/workflows/functional-test-cloud.yaml +++ b/.github/workflows/functional-test-cloud.yaml @@ -453,6 +453,7 @@ jobs: env: BICEP_RECIPE_REGISTRY: ${{ env.BICEP_RECIPE_REGISTRY }} BICEP_RECIPE_TAG_VERSION: ${{ env.REL_VERSION }} + SKIP_AWS_RECIPES: "true" - uses: marocchino/sticky-pull-request-comment@773744901bac0e8cbb5a0dc842800d45e9b2b405 # v2.9.4 if: success() && env.PR_NUMBER != '' diff --git a/.github/workflows/functional-test-noncloud.yaml b/.github/workflows/functional-test-noncloud.yaml index 69573baf64..7d96099efd 100644 --- a/.github/workflows/functional-test-noncloud.yaml +++ b/.github/workflows/functional-test-noncloud.yaml @@ -479,6 +479,7 @@ jobs: env: BICEP_RECIPE_REGISTRY: ${{ env.LOCAL_REGISTRY_SERVER }}:${{ env.LOCAL_REGISTRY_PORT }} BICEP_RECIPE_TAG_VERSION: ${{ env.REL_VERSION }} + SKIP_AWS_RECIPES: "true" TEMP_CERT_DIR: ${{ steps.create-local-registry.outputs.temp-cert-dir }} SSL_CERT_FILE: ${{ steps.create-local-registry.outputs.temp-cert-dir }}/certs/${{ env.LOCAL_REGISTRY_SERVER }}/client.crt diff --git a/.github/workflows/long-running-azure.yaml b/.github/workflows/long-running-azure.yaml index 706cd90267..8e5532f1fa 100644 --- a/.github/workflows/long-running-azure.yaml +++ b/.github/workflows/long-running-azure.yaml @@ -246,6 +246,7 @@ jobs: env: BICEP_RECIPE_REGISTRY: ${{ env.BICEP_RECIPE_REGISTRY }} BICEP_RECIPE_TAG_VERSION: ${{ steps.gen-id.outputs.UNIQUE_ID }} + SKIP_AWS_RECIPES: "true" working-directory: ${{ steps.checkout-release-codebase.outputs.release-dir }} - name: Install gotestsum (test reporting tool) From 59c35e204c5a935dbf68436d550049c9c6db7921 Mon Sep 17 00:00:00 2001 From: willdavsmith Date: Tue, 17 Feb 2026 14:50:31 -0800 Subject: [PATCH 08/24] validate secret oidc Signed-off-by: willdavsmith --- .github/workflows/functional-test-cloud.yaml | 24 ++++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/.github/workflows/functional-test-cloud.yaml b/.github/workflows/functional-test-cloud.yaml index 3bcec0e653..d6da06d8f4 100644 --- a/.github/workflows/functional-test-cloud.yaml +++ b/.github/workflows/functional-test-cloud.yaml @@ -642,21 +642,31 @@ jobs: # create kind cluster with OIDC provider. - name: Create KinD cluster run: | + set -euo pipefail + curl -sSLo "kind" "https://github.com/kubernetes-sigs/kind/releases/download/${{ env.KIND_VER }}/kind-linux-amd64" chmod +x ./kind - # Populate the following environment variables for Azure workload identity from secrets. - # AZURE_OIDC_ISSUER_PUBLIC_KEY - # AZURE_OIDC_ISSUER_PRIVATE_KEY - # AZURE_OIDC_ISSUER - eval "export $(echo "${{ secrets.FUNCTEST_AZURE_OIDC_JSON }}" | jq -r 'to_entries | map("\(.key)=\(.value)") | @sh')" + # Parse and validate Azure workload identity values from secret JSON. + OIDC_JSON='${{ secrets.FUNCTEST_AZURE_OIDC_JSON }}' + if ! echo "${OIDC_JSON}" | jq -e . >/dev/null; then + echo "FUNCTEST_AZURE_OIDC_JSON is not valid JSON." + echo "Expected keys: AZURE_OIDC_ISSUER, AZURE_OIDC_ISSUER_PUBLIC_KEY, AZURE_OIDC_ISSUER_PRIVATE_KEY" + exit 1 + fi + + AZURE_OIDC_ISSUER="$(echo "${OIDC_JSON}" | jq -er '.AZURE_OIDC_ISSUER')" + AZURE_OIDC_ISSUER_PUBLIC_KEY="$(echo "${OIDC_JSON}" | jq -er '.AZURE_OIDC_ISSUER_PUBLIC_KEY')" + AZURE_OIDC_ISSUER_PRIVATE_KEY="$(echo "${OIDC_JSON}" | jq -er '.AZURE_OIDC_ISSUER_PRIVATE_KEY')" AUTHKEY=$(echo -n "${{ github.actor }}:${{ github.token }}" | base64) echo "{\"auths\":{\"ghcr.io\":{\"auth\":\"${AUTHKEY}\"}}}" > "./ghcr_secret.json" # Create KinD cluster with OIDC Issuer keys - echo $AZURE_OIDC_ISSUER_PUBLIC_KEY | base64 -d > sa.pub - echo $AZURE_OIDC_ISSUER_PRIVATE_KEY | base64 -d > sa.key + printf '%s' "${AZURE_OIDC_ISSUER_PUBLIC_KEY}" | base64 -d > sa.pub + printf '%s' "${AZURE_OIDC_ISSUER_PRIVATE_KEY}" | base64 -d > sa.key + openssl pkey -pubin -in sa.pub -noout >/dev/null + openssl pkey -in sa.key -check -noout >/dev/null cat < Date: Tue, 17 Feb 2026 15:27:14 -0800 Subject: [PATCH 09/24] WIP Signed-off-by: willdavsmith --- .github/workflows/functional-test-cloud.yaml | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/.github/workflows/functional-test-cloud.yaml b/.github/workflows/functional-test-cloud.yaml index d6da06d8f4..bf6ed60b97 100644 --- a/.github/workflows/functional-test-cloud.yaml +++ b/.github/workflows/functional-test-cloud.yaml @@ -838,7 +838,7 @@ jobs: "radius": "br:${{ env.BICEP_TYPES_REGISTRY }}/test/radius:$RADIUS_VERSION" }, "cloud": { - "credentialPrecedence": ["Environment"] + "credentialPrecedence": ["AzureCLI", "Environment"] } } EOF @@ -849,6 +849,8 @@ jobs: bicep restore ./test/functional-portable/corerp/cloud/resources/testdata/corerp-azure-connection-database-service.bicep --force - name: Run functional tests run: | + set -euo pipefail + # Ensure rad cli is in path before running tests. export PATH=$GITHUB_WORKSPACE/bin:$PATH # Make directory to capture functional test results @@ -857,12 +859,14 @@ jobs: which rad || { echo "cannot find rad"; exit 1; } - # Populate the following test environment variables from JSON secret. - # AZURE_COSMOS_MONGODB_ACCOUNT_ID - # AZURE_MSSQL_RESOURCE_ID - # AZURE_MSSQL_USERNAME - # AZURE_MSSQL_PASSWORD - eval "export $(echo "${{ secrets.FUNCTEST_PREPROVISIONED_RESOURCE_JSON }}" | jq -r 'to_entries | map("\(.key)=\(.value)") | @sh')" + # Parse and validate preprovisioned Azure resources payload. + PREPROVISIONED_JSON='${{ secrets.FUNCTEST_PREPROVISIONED_RESOURCE_JSON }}' + if ! echo "${PREPROVISIONED_JSON}" | jq -e . >/dev/null; then + echo "FUNCTEST_PREPROVISIONED_RESOURCE_JSON is not valid JSON." + echo "Expected key: AZURE_COSMOS_MONGODB_ACCOUNT_ID" + exit 1 + fi + export AZURE_COSMOS_MONGODB_ACCOUNT_ID="$(echo "${PREPROVISIONED_JSON}" | jq -er '.AZURE_COSMOS_MONGODB_ACCOUNT_ID')" make test-functional-${{ matrix.name }} env: From d1e3f1112b7bef98f87c65be89ea5c9c105fe9b8 Mon Sep 17 00:00:00 2001 From: willdavsmith Date: Tue, 17 Feb 2026 15:53:33 -0800 Subject: [PATCH 10/24] Debug Signed-off-by: willdavsmith --- .github/workflows/functional-test-cloud.yaml | 50 ++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/.github/workflows/functional-test-cloud.yaml b/.github/workflows/functional-test-cloud.yaml index bf6ed60b97..55f2a68930 100644 --- a/.github/workflows/functional-test-cloud.yaml +++ b/.github/workflows/functional-test-cloud.yaml @@ -667,6 +667,27 @@ jobs: printf '%s' "${AZURE_OIDC_ISSUER_PRIVATE_KEY}" | base64 -d > sa.key openssl pkey -pubin -in sa.pub -noout >/dev/null openssl pkey -in sa.key -check -noout >/dev/null + + # Validate the provided signing keys are aligned with the live issuer JWKS. + ISSUER_NO_SLASH="${AZURE_OIDC_ISSUER%/}" + DISCOVERY_URL="${ISSUER_NO_SLASH}/.well-known/openid-configuration" + LIVE_DISCOVERY_JSON="$(curl -fsSL "${DISCOVERY_URL}")" + LIVE_ISSUER="$(echo "${LIVE_DISCOVERY_JSON}" | jq -er '.issuer')" + LIVE_JWKS_URL="$(echo "${LIVE_DISCOVERY_JSON}" | jq -er '.jwks_uri')" + if [[ "${LIVE_ISSUER}" != "${AZURE_OIDC_ISSUER}" ]]; then + echo "OIDC issuer mismatch. Secret AZURE_OIDC_ISSUER='${AZURE_OIDC_ISSUER}', discovery issuer='${LIVE_ISSUER}'." + exit 1 + fi + + SECRET_KID="$(python3 -c "import hashlib,pathlib; print(hashlib.sha256(pathlib.Path('sa.pub').read_text().strip().encode()).hexdigest()[:32])")" + KID_MATCH="$(curl -fsSL "${LIVE_JWKS_URL}" | jq -er --arg kid "${SECRET_KID}" 'any(.keys[]?; .kid == $kid)')" + if [[ "${KID_MATCH}" != "true" ]]; then + echo "OIDC signing key mismatch for issuer '${AZURE_OIDC_ISSUER}'." + echo "Key from FUNCTEST_AZURE_OIDC_JSON is not present in ${LIVE_JWKS_URL}." + echo "Update FUNCTEST_AZURE_OIDC_JSON from Terraform output and rerun." + exit 1 + fi + cat < Date: Tue, 17 Feb 2026 16:13:09 -0800 Subject: [PATCH 11/24] Debug Signed-off-by: willdavsmith --- .github/workflows/functional-test-cloud.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/functional-test-cloud.yaml b/.github/workflows/functional-test-cloud.yaml index 55f2a68930..ffc77378c5 100644 --- a/.github/workflows/functional-test-cloud.yaml +++ b/.github/workflows/functional-test-cloud.yaml @@ -861,13 +861,15 @@ jobs: echo "Workload token subject: ${SUBJECT}" echo "Workload token audience: ${AUDIENCE}" - az account get-access-token \ + az login \ --service-principal \ --username "${{ secrets.AZURE_SP_TESTS_APPID }}" \ --tenant "${{ secrets.AZURE_SP_TESTS_TENANTID }}" \ --federated-token "${FED_TOKEN}" \ - --resource https://management.azure.com/ \ + --allow-no-subscriptions \ -o none + az account set --subscription "${{ secrets.AZURE_SUBSCRIPTIONID_TESTS }}" + az account get-access-token --resource https://management.azure.com/ -o none - name: Publish Terraform test recipes run: | From 038f72ed297398bf7412070f2c8535ec96dac945 Mon Sep 17 00:00:00 2001 From: willdavsmith Date: Tue, 17 Feb 2026 19:11:01 -0800 Subject: [PATCH 12/24] Test Signed-off-by: willdavsmith --- .github/workflows/functional-test-cloud.yaml | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/.github/workflows/functional-test-cloud.yaml b/.github/workflows/functional-test-cloud.yaml index ffc77378c5..a9e5e62258 100644 --- a/.github/workflows/functional-test-cloud.yaml +++ b/.github/workflows/functional-test-cloud.yaml @@ -679,11 +679,12 @@ jobs: exit 1 fi - SECRET_KID="$(python3 -c "import hashlib,pathlib; print(hashlib.sha256(pathlib.Path('sa.pub').read_text().strip().encode()).hexdigest()[:32])")" - KID_MATCH="$(curl -fsSL "${LIVE_JWKS_URL}" | jq -er --arg kid "${SECRET_KID}" 'any(.keys[]?; .kid == $kid)')" + SECRET_KID="$(openssl pkey -pubin -in sa.pub -outform DER | openssl dgst -sha256 -binary | openssl base64 -A | tr '+/' '-_' | tr -d '=')" + KID_MATCH="$(curl -fsSL "${LIVE_JWKS_URL}" | jq -r --arg kid "${SECRET_KID}" 'any(.keys[]?; .kid == $kid)')" if [[ "${KID_MATCH}" != "true" ]]; then echo "OIDC signing key mismatch for issuer '${AZURE_OIDC_ISSUER}'." echo "Key from FUNCTEST_AZURE_OIDC_JSON is not present in ${LIVE_JWKS_URL}." + echo "Expected kid: ${SECRET_KID}" echo "Update FUNCTEST_AZURE_OIDC_JSON from Terraform output and rerun." exit 1 fi @@ -853,13 +854,23 @@ jobs: fi FED_TOKEN="$(kubectl exec -n radius-system deploy/bicep-de -- cat "${FED_TOKEN_FILE}")" - CLAIMS="$(python3 -c "import base64, json, sys; p=sys.stdin.read().strip().split('.')[1]; p += '=' * (-len(p) % 4); print(base64.urlsafe_b64decode(p.encode()).decode())" <<< "${FED_TOKEN}")" + TOKEN_HEADER="$(python3 -c "import base64, sys; h=sys.stdin.read().strip().split('.')[0]; h += '=' * (-len(h) % 4); print(base64.urlsafe_b64decode(h.encode()).decode())" <<< "${FED_TOKEN}")" + TOKEN_KID="$(echo "${TOKEN_HEADER}" | jq -r '.kid')" + CLAIMS="$(python3 -c "import base64, sys; p=sys.stdin.read().strip().split('.')[1]; p += '=' * (-len(p) % 4); print(base64.urlsafe_b64decode(p.encode()).decode())" <<< "${FED_TOKEN}")" ISSUER="$(echo "${CLAIMS}" | jq -r '.iss')" SUBJECT="$(echo "${CLAIMS}" | jq -r '.sub')" AUDIENCE="$(echo "${CLAIMS}" | jq -r '.aud')" + JWKS_URL="$(curl -fsSL "${ISSUER%/}/.well-known/openid-configuration" | jq -r '.jwks_uri')" + KID_FOUND_IN_JWKS="$(curl -fsSL "${JWKS_URL}" | jq -r --arg kid "${TOKEN_KID}" 'any(.keys[]?; .kid == $kid)')" echo "Workload token issuer: ${ISSUER}" echo "Workload token subject: ${SUBJECT}" echo "Workload token audience: ${AUDIENCE}" + echo "Workload token kid: ${TOKEN_KID}" + echo "OIDC JWKS URL: ${JWKS_URL}" + if [[ "${KID_FOUND_IN_JWKS}" != "true" ]]; then + echo "JWT kid ${TOKEN_KID} not found in JWKS for issuer ${ISSUER}." + exit 1 + fi az login \ --service-principal \ From 8925e62e6f1e125dedd35169f6e8c1f0178166a0 Mon Sep 17 00:00:00 2001 From: willdavsmith Date: Wed, 18 Feb 2026 09:43:16 -0800 Subject: [PATCH 13/24] cloud fts working Signed-off-by: willdavsmith From 5b732d2093ca26dd33efae3397c63699a8aa9a2f Mon Sep 17 00:00:00 2001 From: willdavsmith Date: Wed, 18 Feb 2026 09:52:50 -0800 Subject: [PATCH 14/24] WIP Signed-off-by: willdavsmith --- .github/scripts/manage-radius-installation.sh | 2 +- .github/workflows/long-running-azure.yaml | 53 ++++++++++++++++--- 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/.github/scripts/manage-radius-installation.sh b/.github/scripts/manage-radius-installation.sh index 92d2f2e76f..01e8dc8e48 100755 --- a/.github/scripts/manage-radius-installation.sh +++ b/.github/scripts/manage-radius-installation.sh @@ -105,7 +105,7 @@ install_radius() { echo "Installing Radius..." if ! rad install kubernetes \ --set global.azureWorkloadIdentity.enabled=true \ - --set database.enabled=true; then + --set database.enabled=false; then echo "" echo "============================================================================" echo "ERROR: Radius installation failed" diff --git a/.github/workflows/long-running-azure.yaml b/.github/workflows/long-running-azure.yaml index 8e5532f1fa..809b12a9ce 100644 --- a/.github/workflows/long-running-azure.yaml +++ b/.github/workflows/long-running-azure.yaml @@ -331,6 +331,47 @@ jobs: run: | echo "FUNCTEST_OIDC_ISSUER=$(az aks show -n ${{ env.AKS_CLUSTER_NAME }} -g ${{ env.AKS_RESOURCE_GROUP }} --query "oidcIssuerProfile.issuerUrl" -otsv)" >> $GITHUB_OUTPUT + - name: Validate Azure workload identity token exchange + run: | + set -euo pipefail + + FED_TOKEN_FILE="$(kubectl exec -n radius-system deploy/bicep-de -- printenv AZURE_FEDERATED_TOKEN_FILE)" + if [[ -z "${FED_TOKEN_FILE}" ]]; then + echo "AZURE_FEDERATED_TOKEN_FILE is not set in bicep-de pod. Workload identity mutation may have failed." + kubectl -n radius-system get pod -l app.kubernetes.io/name=bicep-de -o jsonpath='{.items[0].metadata.labels}' + echo + exit 1 + fi + + FED_TOKEN="$(kubectl exec -n radius-system deploy/bicep-de -- cat "${FED_TOKEN_FILE}")" + TOKEN_HEADER="$(python3 -c "import base64, sys; h=sys.stdin.read().strip().split('.')[0]; h += '=' * (-len(h) % 4); print(base64.urlsafe_b64decode(h.encode()).decode())" <<< "${FED_TOKEN}")" + TOKEN_KID="$(echo "${TOKEN_HEADER}" | jq -r '.kid')" + CLAIMS="$(python3 -c "import base64, sys; p=sys.stdin.read().strip().split('.')[1]; p += '=' * (-len(p) % 4); print(base64.urlsafe_b64decode(p.encode()).decode())" <<< "${FED_TOKEN}")" + ISSUER="$(echo "${CLAIMS}" | jq -r '.iss')" + SUBJECT="$(echo "${CLAIMS}" | jq -r '.sub')" + AUDIENCE="$(echo "${CLAIMS}" | jq -r '.aud')" + JWKS_URL="$(curl -fsSL "${ISSUER%/}/.well-known/openid-configuration" | jq -r '.jwks_uri')" + KID_FOUND_IN_JWKS="$(curl -fsSL "${JWKS_URL}" | jq -r --arg kid "${TOKEN_KID}" 'any(.keys[]?; .kid == $kid)')" + echo "Workload token issuer: ${ISSUER}" + echo "Workload token subject: ${SUBJECT}" + echo "Workload token audience: ${AUDIENCE}" + echo "Workload token kid: ${TOKEN_KID}" + echo "OIDC JWKS URL: ${JWKS_URL}" + if [[ "${KID_FOUND_IN_JWKS}" != "true" ]]; then + echo "JWT kid ${TOKEN_KID} not found in JWKS for issuer ${ISSUER}." + exit 1 + fi + + az login \ + --service-principal \ + --username "${{ secrets.AZURE_SP_TESTS_APPID }}" \ + --tenant "${{ secrets.AZURE_SP_TESTS_TENANTID }}" \ + --federated-token "${FED_TOKEN}" \ + --allow-no-subscriptions \ + -o none + az account set --subscription "${{ secrets.AZURE_SUBSCRIPTIONID_TESTS }}" + az account get-access-token --resource https://management.azure.com/ -o none + - name: Restore Bicep artifacts before running functional tests # Restore the Radius extension artifact used by Azure cloud tests. run: | @@ -367,12 +408,12 @@ jobs: which rad || { echo "cannot find rad"; exit 1; } - # Populate the following test environment variables from JSON secret. - # AZURE_COSMOS_MONGODB_ACCOUNT_ID - # AZURE_MSSQL_RESOURCE_ID - # AZURE_MSSQL_USERNAME - # AZURE_MSSQL_PASSWORD - eval "export $(echo "${{ secrets.FUNCTEST_PREPROVISIONED_RESOURCE_JSON }}" | jq -r 'to_entries | map("\(.key)=\(.value)") | @sh')" + PREPROVISIONED_JSON='${{ secrets.FUNCTEST_PREPROVISIONED_RESOURCE_JSON }}' + if ! echo "${PREPROVISIONED_JSON}" | jq -e . >/dev/null; then + echo "FUNCTEST_PREPROVISIONED_RESOURCE_JSON is not valid JSON." + exit 1 + fi + export AZURE_COSMOS_MONGODB_ACCOUNT_ID="$(echo "${PREPROVISIONED_JSON}" | jq -er '.AZURE_COSMOS_MONGODB_ACCOUNT_ID')" make test-functional-all From b78b7c5afe4fcef2af7f88f793f11c04a18a9f0a Mon Sep 17 00:00:00 2001 From: willdavsmith Date: Wed, 18 Feb 2026 11:51:56 -0800 Subject: [PATCH 15/24] WIP Signed-off-by: willdavsmith --- .github/workflows/long-running-azure.yaml | 26 +++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/.github/workflows/long-running-azure.yaml b/.github/workflows/long-running-azure.yaml index 809b12a9ce..68af08c7d8 100644 --- a/.github/workflows/long-running-azure.yaml +++ b/.github/workflows/long-running-azure.yaml @@ -238,6 +238,20 @@ jobs: env: RELEASE_DIR: ${{ steps.checkout-release-codebase.outputs.release-dir }} + - name: Point dynamicrp testresources extension to test ACR + run: | + set -euo pipefail + + BICEP_CONFIG_FILE="./${RELEASE_DIR}/test/functional-portable/dynamicrp/noncloud/resources/bicepconfig.json" + TMP_FILE="$(mktemp)" + jq --arg testresources "br:${BICEP_TYPES_REGISTRY}/testresources:latest" \ + '.extensions.testresources = $testresources | .cloud.credentialPrecedence = ["AzureCLI", "Environment"]' \ + "${BICEP_CONFIG_FILE}" > "${TMP_FILE}" + mv "${TMP_FILE}" "${BICEP_CONFIG_FILE}" + cat "${BICEP_CONFIG_FILE}" + env: + RELEASE_DIR: ${{ steps.checkout-release-codebase.outputs.release-dir }} + - name: Publish Bicep Test Recipes run: | export PATH=$GITHUB_WORKSPACE/bin:$PATH @@ -362,6 +376,11 @@ jobs: exit 1 fi + # Isolate this validation login from the job-wide Azure CLI auth context used by tests. + export AZURE_CONFIG_DIR + AZURE_CONFIG_DIR="$(mktemp -d)" + trap 'rm -rf "${AZURE_CONFIG_DIR}"' EXIT + az login \ --service-principal \ --username "${{ secrets.AZURE_SP_TESTS_APPID }}" \ @@ -372,6 +391,13 @@ jobs: az account set --subscription "${{ secrets.AZURE_SUBSCRIPTIONID_TESTS }}" az account get-access-token --resource https://management.azure.com/ -o none + - name: Refresh Azure login before functional tests + uses: azure/login@a457da9ea143d694b1b9c7c869ebb04ebe844ef5 # v2.3.0 + with: + client-id: ${{ secrets.AZURE_SP_TESTS_APPID }} + tenant-id: ${{ secrets.AZURE_SP_TESTS_TENANTID }} + subscription-id: ${{ secrets.AZURE_SUBSCRIPTIONID_TESTS }} + - name: Restore Bicep artifacts before running functional tests # Restore the Radius extension artifact used by Azure cloud tests. run: | From 707e15bf5858df1e99d354ad80e4eb4a356229d3 Mon Sep 17 00:00:00 2001 From: willdavsmith Date: Wed, 18 Feb 2026 13:13:21 -0800 Subject: [PATCH 16/24] LRT working v1 Signed-off-by: willdavsmith From 9aa99e95412da9975e977a9da416d18577425e3a Mon Sep 17 00:00:00 2001 From: willdavsmith Date: Wed, 18 Feb 2026 13:34:14 -0800 Subject: [PATCH 17/24] cleaning it up for PR Signed-off-by: willdavsmith --- .github/scripts/publish-recipes.sh | 6 - .github/workflows/functional-test-cloud.yaml | 127 ++++-------------- .../workflows/functional-test-noncloud.yaml | 2 - .github/workflows/long-running-azure.yaml | 84 +++--------- 4 files changed, 45 insertions(+), 174 deletions(-) diff --git a/.github/scripts/publish-recipes.sh b/.github/scripts/publish-recipes.sh index e05b4908b7..4b3271c762 100755 --- a/.github/scripts/publish-recipes.sh +++ b/.github/scripts/publish-recipes.sh @@ -63,12 +63,6 @@ for RECIPE in $(find "$DIRECTORY" -type f -name "*.bicep"); do continue fi - # Optionally skip AWS recipes when workflows disable AWS tests/providers. - if [[ "${SKIP_AWS_RECIPES:-false}" == "true" && "$FILENAME" =~ [Aa][Ww][Ss] ]]; then - echo "Skipping $RECIPE (AWS recipe skipped: SKIP_AWS_RECIPES=true)" - continue - fi - echo "Publishing $RECIPE to $PUBLISH_REF" echo "- $PUBLISH_REF" >>$GITHUB_STEP_SUMMARY rad bicep publish --file $RECIPE --target "br:$PUBLISH_REF" diff --git a/.github/workflows/functional-test-cloud.yaml b/.github/workflows/functional-test-cloud.yaml index a9e5e62258..4b249db198 100644 --- a/.github/workflows/functional-test-cloud.yaml +++ b/.github/workflows/functional-test-cloud.yaml @@ -453,7 +453,6 @@ jobs: env: BICEP_RECIPE_REGISTRY: ${{ env.BICEP_RECIPE_REGISTRY }} BICEP_RECIPE_TAG_VERSION: ${{ env.REL_VERSION }} - SKIP_AWS_RECIPES: "true" - uses: marocchino/sticky-pull-request-comment@773744901bac0e8cbb5a0dc842800d45e9b2b405 # v2.9.4 if: success() && env.PR_NUMBER != '' @@ -632,62 +631,30 @@ jobs: # The role-to-assume is the role that the github action will assume to execute aws commands and # construct cloud control client in test code. - name: configure aws credentials using assumed role - if: false uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # v6.0.0 with: - # role-to-assume: ${{ secrets.AWS_GH_ACTIONS_ROLE }} + role-to-assume: ${{ secrets.AWS_GH_ACTIONS_ROLE }} role-session-name: GitHub_to_AWS_via_FederatedOIDC aws-region: ${{ env.AWS_REGION }} # create kind cluster with OIDC provider. - name: Create KinD cluster run: | - set -euo pipefail - curl -sSLo "kind" "https://github.com/kubernetes-sigs/kind/releases/download/${{ env.KIND_VER }}/kind-linux-amd64" chmod +x ./kind - # Parse and validate Azure workload identity values from secret JSON. - OIDC_JSON='${{ secrets.FUNCTEST_AZURE_OIDC_JSON }}' - if ! echo "${OIDC_JSON}" | jq -e . >/dev/null; then - echo "FUNCTEST_AZURE_OIDC_JSON is not valid JSON." - echo "Expected keys: AZURE_OIDC_ISSUER, AZURE_OIDC_ISSUER_PUBLIC_KEY, AZURE_OIDC_ISSUER_PRIVATE_KEY" - exit 1 - fi - - AZURE_OIDC_ISSUER="$(echo "${OIDC_JSON}" | jq -er '.AZURE_OIDC_ISSUER')" - AZURE_OIDC_ISSUER_PUBLIC_KEY="$(echo "${OIDC_JSON}" | jq -er '.AZURE_OIDC_ISSUER_PUBLIC_KEY')" - AZURE_OIDC_ISSUER_PRIVATE_KEY="$(echo "${OIDC_JSON}" | jq -er '.AZURE_OIDC_ISSUER_PRIVATE_KEY')" + # Populate the following environment variables for Azure workload identity from secrets. + # AZURE_OIDC_ISSUER_PUBLIC_KEY + # AZURE_OIDC_ISSUER_PRIVATE_KEY + # AZURE_OIDC_ISSUER + eval "export $(echo "${{ secrets.FUNCTEST_AZURE_OIDC_JSON }}" | jq -r 'to_entries | map("\(.key)=\(.value)") | @sh')" AUTHKEY=$(echo -n "${{ github.actor }}:${{ github.token }}" | base64) echo "{\"auths\":{\"ghcr.io\":{\"auth\":\"${AUTHKEY}\"}}}" > "./ghcr_secret.json" # Create KinD cluster with OIDC Issuer keys - printf '%s' "${AZURE_OIDC_ISSUER_PUBLIC_KEY}" | base64 -d > sa.pub - printf '%s' "${AZURE_OIDC_ISSUER_PRIVATE_KEY}" | base64 -d > sa.key - openssl pkey -pubin -in sa.pub -noout >/dev/null - openssl pkey -in sa.key -check -noout >/dev/null - - # Validate the provided signing keys are aligned with the live issuer JWKS. - ISSUER_NO_SLASH="${AZURE_OIDC_ISSUER%/}" - DISCOVERY_URL="${ISSUER_NO_SLASH}/.well-known/openid-configuration" - LIVE_DISCOVERY_JSON="$(curl -fsSL "${DISCOVERY_URL}")" - LIVE_ISSUER="$(echo "${LIVE_DISCOVERY_JSON}" | jq -er '.issuer')" - LIVE_JWKS_URL="$(echo "${LIVE_DISCOVERY_JSON}" | jq -er '.jwks_uri')" - if [[ "${LIVE_ISSUER}" != "${AZURE_OIDC_ISSUER}" ]]; then - echo "OIDC issuer mismatch. Secret AZURE_OIDC_ISSUER='${AZURE_OIDC_ISSUER}', discovery issuer='${LIVE_ISSUER}'." - exit 1 - fi - - SECRET_KID="$(openssl pkey -pubin -in sa.pub -outform DER | openssl dgst -sha256 -binary | openssl base64 -A | tr '+/' '-_' | tr -d '=')" - KID_MATCH="$(curl -fsSL "${LIVE_JWKS_URL}" | jq -r --arg kid "${SECRET_KID}" 'any(.keys[]?; .kid == $kid)')" - if [[ "${KID_MATCH}" != "true" ]]; then - echo "OIDC signing key mismatch for issuer '${AZURE_OIDC_ISSUER}'." - echo "Key from FUNCTEST_AZURE_OIDC_JSON is not present in ${LIVE_JWKS_URL}." - echo "Expected kid: ${SECRET_KID}" - echo "Update FUNCTEST_AZURE_OIDC_JSON from Terraform output and rerun." - exit 1 - fi + echo $AZURE_OIDC_ISSUER_PUBLIC_KEY | base64 -d > sa.pub + echo $AZURE_OIDC_ISSUER_PRIVATE_KEY | base64 -d > sa.key cat </dev/null; then - echo "FUNCTEST_PREPROVISIONED_RESOURCE_JSON is not valid JSON." - echo "Expected key: AZURE_COSMOS_MONGODB_ACCOUNT_ID" - exit 1 - fi - export AZURE_COSMOS_MONGODB_ACCOUNT_ID="$(echo "${PREPROVISIONED_JSON}" | jq -er '.AZURE_COSMOS_MONGODB_ACCOUNT_ID')" + # Populate the following test environment variables from JSON secret. + # AZURE_COSMOS_MONGODB_ACCOUNT_ID + # AZURE_MSSQL_RESOURCE_ID + # AZURE_MSSQL_USERNAME + # AZURE_MSSQL_PASSWORD + eval "export $(echo "${{ secrets.FUNCTEST_PREPROVISIONED_RESOURCE_JSON }}" | jq -r 'to_entries | map("\(.key)=\(.value)") | @sh')" make test-functional-${{ matrix.name }} env: @@ -937,7 +867,7 @@ jobs: TEST_TIMEOUT: ${{ env.FUNCTIONALTEST_TIMEOUT }} RADIUS_CONTAINER_LOG_PATH: ${{ github.workspace }}/${{ env.RADIUS_CONTAINER_LOG_BASE }} AWS_REGION: ${{ env.AWS_REGION }} - # AWS_ACCOUNT_ID: ${{ secrets.FUNCTEST_AWS_ACCOUNT_ID }} + AWS_ACCOUNT_ID: ${{ secrets.FUNCTEST_AWS_ACCOUNT_ID }} RADIUS_SAMPLES_REPO_ROOT: ${{ github.workspace }}/samples # Test_MongoDB_Recipe_Parameters is using the following environment variable. INTEGRATION_TEST_RESOURCE_GROUP_NAME: ${{ env.AZURE_TEST_RESOURCE_GROUP }} @@ -946,7 +876,6 @@ jobs: BICEP_RECIPE_REGISTRY: ${{ env.BICEP_RECIPE_REGISTRY }} BICEP_RECIPE_TAG_VERSION: ${{ env.BICEP_RECIPE_TAG_VERSION }} GH_TOKEN: ${{ steps.get_installation_token.outputs.token }} - GOTEST_OPTS: -skip AWS\|TerraformPrivateGitModule GOTESTSUM_OPTS: --junitfile ./dist/functional_test/results.xml - name: Process Functional Test Results diff --git a/.github/workflows/functional-test-noncloud.yaml b/.github/workflows/functional-test-noncloud.yaml index 7d96099efd..caabd53cb3 100644 --- a/.github/workflows/functional-test-noncloud.yaml +++ b/.github/workflows/functional-test-noncloud.yaml @@ -479,7 +479,6 @@ jobs: env: BICEP_RECIPE_REGISTRY: ${{ env.LOCAL_REGISTRY_SERVER }}:${{ env.LOCAL_REGISTRY_PORT }} BICEP_RECIPE_TAG_VERSION: ${{ env.REL_VERSION }} - SKIP_AWS_RECIPES: "true" TEMP_CERT_DIR: ${{ steps.create-local-registry.outputs.temp-cert-dir }} SSL_CERT_FILE: ${{ steps.create-local-registry.outputs.temp-cert-dir }}/certs/${{ env.LOCAL_REGISTRY_SERVER }}/client.crt @@ -502,7 +501,6 @@ jobs: BICEP_RECIPE_REGISTRY: ${{ env.LOCAL_REGISTRY_NAME }}:${{ env.LOCAL_REGISTRY_PORT }} BICEP_RECIPE_TAG_VERSION: ${{ env.BICEP_RECIPE_TAG_VERSION }} GH_TOKEN: ${{ github.token }} - GOTEST_OPTS: -skip AWS\|TerraformPrivateGitModule GOTESTSUM_OPTS: --junitfile ./dist/functional_test/results.xml RADIUS_TEST_FAST_CLEANUP: true GIT_HTTP_PASSWORD: ${{ env.GIT_HTTP_PASSWORD }} diff --git a/.github/workflows/long-running-azure.yaml b/.github/workflows/long-running-azure.yaml index 68af08c7d8..f25f9fccd1 100644 --- a/.github/workflows/long-running-azure.yaml +++ b/.github/workflows/long-running-azure.yaml @@ -248,7 +248,6 @@ jobs: '.extensions.testresources = $testresources | .cloud.credentialPrecedence = ["AzureCLI", "Environment"]' \ "${BICEP_CONFIG_FILE}" > "${TMP_FILE}" mv "${TMP_FILE}" "${BICEP_CONFIG_FILE}" - cat "${BICEP_CONFIG_FILE}" env: RELEASE_DIR: ${{ steps.checkout-release-codebase.outputs.release-dir }} @@ -260,7 +259,6 @@ jobs: env: BICEP_RECIPE_REGISTRY: ${{ env.BICEP_RECIPE_REGISTRY }} BICEP_RECIPE_TAG_VERSION: ${{ steps.gen-id.outputs.UNIQUE_ID }} - SKIP_AWS_RECIPES: "true" working-directory: ${{ steps.checkout-release-codebase.outputs.release-dir }} - name: Install gotestsum (test reporting tool) @@ -307,7 +305,10 @@ jobs: --client-id ${{ secrets.AZURE_SP_TESTS_APPID }} \ --tenant-id ${{ secrets.AZURE_SP_TESTS_TENANTID }} - echo "*** Skipping AWS provider configuration for this run ***" + echo "*** Configuring AWS provider ***" + rad env update ${{ env.RADIUS_TEST_ENVIRONMENT_NAME }} --aws-region ${{ env.AWS_REGION }} --aws-account-id ${{ secrets.FUNCTEST_AWS_ACCOUNT_ID }} + rad credential register aws access-key \ + --access-key-id ${{ secrets.FUNCTEST_AWS_ACCESS_KEY_ID }} --secret-access-key ${{ secrets.FUNCTEST_AWS_SECRET_ACCESS_KEY }} - name: Log radius installation status (failure) if: failure() @@ -345,64 +346,14 @@ jobs: run: | echo "FUNCTEST_OIDC_ISSUER=$(az aks show -n ${{ env.AKS_CLUSTER_NAME }} -g ${{ env.AKS_RESOURCE_GROUP }} --query "oidcIssuerProfile.issuerUrl" -otsv)" >> $GITHUB_OUTPUT - - name: Validate Azure workload identity token exchange - run: | - set -euo pipefail - - FED_TOKEN_FILE="$(kubectl exec -n radius-system deploy/bicep-de -- printenv AZURE_FEDERATED_TOKEN_FILE)" - if [[ -z "${FED_TOKEN_FILE}" ]]; then - echo "AZURE_FEDERATED_TOKEN_FILE is not set in bicep-de pod. Workload identity mutation may have failed." - kubectl -n radius-system get pod -l app.kubernetes.io/name=bicep-de -o jsonpath='{.items[0].metadata.labels}' - echo - exit 1 - fi - - FED_TOKEN="$(kubectl exec -n radius-system deploy/bicep-de -- cat "${FED_TOKEN_FILE}")" - TOKEN_HEADER="$(python3 -c "import base64, sys; h=sys.stdin.read().strip().split('.')[0]; h += '=' * (-len(h) % 4); print(base64.urlsafe_b64decode(h.encode()).decode())" <<< "${FED_TOKEN}")" - TOKEN_KID="$(echo "${TOKEN_HEADER}" | jq -r '.kid')" - CLAIMS="$(python3 -c "import base64, sys; p=sys.stdin.read().strip().split('.')[1]; p += '=' * (-len(p) % 4); print(base64.urlsafe_b64decode(p.encode()).decode())" <<< "${FED_TOKEN}")" - ISSUER="$(echo "${CLAIMS}" | jq -r '.iss')" - SUBJECT="$(echo "${CLAIMS}" | jq -r '.sub')" - AUDIENCE="$(echo "${CLAIMS}" | jq -r '.aud')" - JWKS_URL="$(curl -fsSL "${ISSUER%/}/.well-known/openid-configuration" | jq -r '.jwks_uri')" - KID_FOUND_IN_JWKS="$(curl -fsSL "${JWKS_URL}" | jq -r --arg kid "${TOKEN_KID}" 'any(.keys[]?; .kid == $kid)')" - echo "Workload token issuer: ${ISSUER}" - echo "Workload token subject: ${SUBJECT}" - echo "Workload token audience: ${AUDIENCE}" - echo "Workload token kid: ${TOKEN_KID}" - echo "OIDC JWKS URL: ${JWKS_URL}" - if [[ "${KID_FOUND_IN_JWKS}" != "true" ]]; then - echo "JWT kid ${TOKEN_KID} not found in JWKS for issuer ${ISSUER}." - exit 1 - fi - - # Isolate this validation login from the job-wide Azure CLI auth context used by tests. - export AZURE_CONFIG_DIR - AZURE_CONFIG_DIR="$(mktemp -d)" - trap 'rm -rf "${AZURE_CONFIG_DIR}"' EXIT - - az login \ - --service-principal \ - --username "${{ secrets.AZURE_SP_TESTS_APPID }}" \ - --tenant "${{ secrets.AZURE_SP_TESTS_TENANTID }}" \ - --federated-token "${FED_TOKEN}" \ - --allow-no-subscriptions \ - -o none - az account set --subscription "${{ secrets.AZURE_SUBSCRIPTIONID_TESTS }}" - az account get-access-token --resource https://management.azure.com/ -o none - - - name: Refresh Azure login before functional tests - uses: azure/login@a457da9ea143d694b1b9c7c869ebb04ebe844ef5 # v2.3.0 - with: - client-id: ${{ secrets.AZURE_SP_TESTS_APPID }} - tenant-id: ${{ secrets.AZURE_SP_TESTS_TENANTID }} - subscription-id: ${{ secrets.AZURE_SUBSCRIPTIONID_TESTS }} - - name: Restore Bicep artifacts before running functional tests - # Restore the Radius extension artifact used by Azure cloud tests. + # The exact files chosen to run the command can be changed, but we need 1 that uses the Radius extension, 1 that uses the AWS extension and 1 that uses UDT testresources + # so we can restore all Bicep artifacts before the tests start. run: | # Restore Radius Bicep types bicep restore "./${RELEASE_DIR}/test/functional-portable/corerp/cloud/resources/testdata/corerp-azure-connection-database-service.bicep" --force + # Restore AWS Bicep types + bicep restore "./${RELEASE_DIR}/test/functional-portable/corerp/cloud/resources/testdata/aws-s3-bucket.bicep" --force env: RELEASE_DIR: ${{ steps.checkout-release-codebase.outputs.release-dir }} @@ -412,10 +363,10 @@ jobs: UNIQUE_ID: ${{ steps.gen-id.outputs.UNIQUE_ID }} TEST_TIMEOUT: ${{ env.FUNCTIONALTEST_TIMEOUT }} RADIUS_CONTAINER_LOG_PATH: ${{ github.workspace }}/${{ env.RADIUS_CONTAINER_LOG_BASE }} - # AWS_ACCESS_KEY_ID: ${{ secrets.FUNCTEST_AWS_ACCESS_KEY_ID }} - # AWS_SECRET_ACCESS_KEY: ${{ secrets.FUNCTEST_AWS_SECRET_ACCESS_KEY }} + AWS_ACCESS_KEY_ID: ${{ secrets.FUNCTEST_AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.FUNCTEST_AWS_SECRET_ACCESS_KEY }} AWS_REGION: ${{ env.AWS_REGION }} - # AWS_ACCOUNT_ID: ${{ secrets.FUNCTEST_AWS_ACCOUNT_ID }} + AWS_ACCOUNT_ID: ${{ secrets.FUNCTEST_AWS_ACCOUNT_ID }} RADIUS_SAMPLES_REPO_ROOT: ${{ github.workspace }}/samples # Test_MongoDB_Recipe_Parameters is using the following environment variable. INTEGRATION_TEST_RESOURCE_GROUP_NAME: ${{ steps.gen-id.outputs.AZURE_TEST_RESOURCE_GROUP }} @@ -426,7 +377,6 @@ jobs: BICEP_RECIPE_TAG_VERSION: ${{ steps.gen-id.outputs.UNIQUE_ID }} GH_TOKEN: ${{ steps.get_installation_token.outputs.token }} GIT_HTTP_PASSWORD: ${{ env.GIT_HTTP_PASSWORD }} - GOTEST_OPTS: -skip AWS\|TerraformPrivateGitModule working-directory: ${{ steps.checkout-release-codebase.outputs.release-dir }} run: | # Ensure rad cli is in path before running tests. @@ -434,12 +384,12 @@ jobs: which rad || { echo "cannot find rad"; exit 1; } - PREPROVISIONED_JSON='${{ secrets.FUNCTEST_PREPROVISIONED_RESOURCE_JSON }}' - if ! echo "${PREPROVISIONED_JSON}" | jq -e . >/dev/null; then - echo "FUNCTEST_PREPROVISIONED_RESOURCE_JSON is not valid JSON." - exit 1 - fi - export AZURE_COSMOS_MONGODB_ACCOUNT_ID="$(echo "${PREPROVISIONED_JSON}" | jq -er '.AZURE_COSMOS_MONGODB_ACCOUNT_ID')" + # Populate the following test environment variables from JSON secret. + # AZURE_COSMOS_MONGODB_ACCOUNT_ID + # AZURE_MSSQL_RESOURCE_ID + # AZURE_MSSQL_USERNAME + # AZURE_MSSQL_PASSWORD + eval "export $(echo "${{ secrets.FUNCTEST_PREPROVISIONED_RESOURCE_JSON }}" | jq -r 'to_entries | map("\(.key)=\(.value)") | @sh')" make test-functional-all From d0440c02eeee59fe6123f6189205fc0cc03f27a7 Mon Sep 17 00:00:00 2001 From: willdavsmith Date: Thu, 19 Feb 2026 12:17:22 -0800 Subject: [PATCH 18/24] PR cleanup Signed-off-by: willdavsmith --- .github/workflows/functional-test-cloud.yaml | 28 +++++++++++--------- .github/workflows/long-running-azure.yaml | 19 +++++++------ 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/.github/workflows/functional-test-cloud.yaml b/.github/workflows/functional-test-cloud.yaml index 4b249db198..75393f8cde 100644 --- a/.github/workflows/functional-test-cloud.yaml +++ b/.github/workflows/functional-test-cloud.yaml @@ -62,9 +62,9 @@ env: # Azure workload identity webhook chart version AZURE_WORKLOAD_IDENTITY_WEBHOOK_VER: 1.3.0 # Container registry for storing container images - CONTAINER_REGISTRY: ${{ vars.FUNCTIONAL_TEST_CONTAINER_REGISTRY || 'ghcr.io/radius-project/dev' }} + CONTAINER_REGISTRY: ${{ vars.FUNCTIONAL_TEST_CONTAINER_REGISTRY }} # Container registry for storing Bicep recipe artifacts - BICEP_RECIPE_REGISTRY: ${{ vars.FUNCTIONAL_TEST_BICEP_RECIPE_REGISTRY || 'ghcr.io/radius-project/dev' }} + BICEP_RECIPE_REGISTRY: ${{ vars.FUNCTIONAL_TEST_BICEP_RECIPE_REGISTRY }} # The radius functional test timeout FUNCTIONALTEST_TIMEOUT: 60m # The Azure Location to store test resources @@ -80,11 +80,13 @@ env: # Server where terraform test modules are deployed TF_RECIPE_MODULE_SERVER_URL: http://tf-module-server.radius-test-tf-module-server.svc.cluster.local # The functional test GitHub app id - FUNCTIONAL_TEST_APP_ID: ${{ vars.FUNCTIONAL_TEST_APP_ID || '425843' }} + FUNCTIONAL_TEST_APP_ID: ${{ vars.FUNCTIONAL_TEST_APP_ID }} # Private Git repository where terraform module for testing is stored. TF_RECIPE_PRIVATE_GIT_SOURCE: git::https://github.com/radius-project/terraform-private-modules//kubernetes-redis - # bicep-types ACR url for uploading Radius Bicep types - BICEP_TYPES_REGISTRY: ${{ vars.BICEP_TYPES_REGISTRY }} + # bicep-types ACR url for pulling latest Radius Bicep types (AWS) + BICEP_TYPES_REGISTRY: biceptypes.azurecr.io + # bicep-types ACR url for uploading test Radius Bicep types + TEST_BICEP_TYPES_REGISTRY: ${{ vars.TEST_BICEP_TYPES_REGISTRY }} # Kubernetes client QPS and Burst settings for high-concurrency CI environments RADIUS_QPS_AND_BURST: "800" @@ -420,7 +422,7 @@ jobs: - name: Publish bicep types run: | - bicep publish-extension ./hack/bicep-types-radius/generated/index.json --target br:${{ env.BICEP_TYPES_REGISTRY }}/test/radius:${{ env.REL_VERSION == 'edge' && 'latest' || env.REL_VERSION }} --force + bicep publish-extension ./hack/bicep-types-radius/generated/index.json --target br:${{ env.TEST_BICEP_TYPES_REGISTRY }}/test/radius:${{ env.REL_VERSION == 'edge' && 'latest' || env.REL_VERSION }} --force - name: Generate test bicepconfig.json run: | @@ -435,7 +437,8 @@ jobs: "extensibility": true }, "extensions": { - "radius": "br:${{ env.BICEP_TYPES_REGISTRY }}/test/radius:$RADIUS_VERSION" + "radius": "br:${{ env.TEST_BICEP_TYPES_REGISTRY }}/test/radius:$RADIUS_VERSION", + "aws": "br:${{ env.BICEP_TYPES_REGISTRY }}/aws:latest" } } EOF @@ -542,6 +545,9 @@ jobs: app-id: ${{ env.FUNCTIONAL_TEST_APP_ID }} private-key: ${{ secrets.FUNCTIONAL_TEST_APP_PRIVATE_KEY }} owner: ${{ github.repository_owner }} + repositories: | + radius + terraform-private-modules permission-checks: write permission-pull-requests: write permission-contents: read @@ -829,8 +835,8 @@ jobs: "extensibility": true }, "extensions": { - "radius": "br:${{ env.BICEP_TYPES_REGISTRY }}/test/radius:$RADIUS_VERSION", - "aws": "br:${{ env.BICEP_TYPES_REGISTRY }}/aws:latest" + "radius": "br:${{ env.TEST_BICEP_TYPES_REGISTRY }}/test/radius:$RADIUS_VERSION", + "aws": "br:${{ env.TEST_BICEP_TYPES_REGISTRY }}/aws:latest" }, "cloud": { "credentialPrecedence": ["Environment"] @@ -1032,14 +1038,12 @@ jobs: needs: [build, tests] runs-on: ubuntu-24.04 timeout-minutes: 5 - permissions: - issues: write if: failure() && github.event_name == 'schedule' && github.repository == vars.RADIUS_REPOSITORY steps: - name: Create failure issue for failing scheduled run uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 with: - github-token: ${{ github.token }} + github-token: ${{ secrets.GH_RAD_CI_BOT_PAT }} script: | github.rest.issues.create({ ...context.repo, diff --git a/.github/workflows/long-running-azure.yaml b/.github/workflows/long-running-azure.yaml index f25f9fccd1..5fc9b51d0e 100644 --- a/.github/workflows/long-running-azure.yaml +++ b/.github/workflows/long-running-azure.yaml @@ -56,8 +56,10 @@ env: # Container registry for storing Bicep recipe artifacts BICEP_RECIPE_REGISTRY: ${{ vars.FUNCTIONAL_TEST_BICEP_RECIPE_REGISTRY || 'ghcr.io/radius-project/dev' }} - # Shared ACR for Radius and UDT Bicep types (different artifact paths/tags). - BICEP_TYPES_REGISTRY: ${{ vars.BICEP_TYPES_REGISTRY }} + # bicep-types ACR url for pulling latest Radius Bicep types (AWS) + BICEP_TYPES_REGISTRY: biceptypes.azurecr.io + # bicep-types ACR url for uploading test Radius Bicep types + TEST_BICEP_TYPES_REGISTRY: ${{ vars.TEST_BICEP_TYPES_REGISTRY }} # The radius functional test timeout FUNCTIONALTEST_TIMEOUT: 60m # The Azure Location to store test resources @@ -68,7 +70,7 @@ env: AWS_REGION: us-west-2 # The functional test GitHub app id - FUNCTIONAL_TEST_APP_ID: ${{ vars.FUNCTIONAL_TEST_APP_ID || '425843' }} + FUNCTIONAL_TEST_APP_ID: ${{ vars.FUNCTIONAL_TEST_APP_ID }} # The AKS cluster name AKS_CLUSTER_NAME: ${{ vars.LRT_AKS_CLUSTER_NAME }} @@ -126,6 +128,9 @@ jobs: # already-expired tokens in workflows that exceed the 1-hour token lifetime. skip-token-revoke: true owner: ${{ github.repository_owner }} + repositories: | + radius + terraform-private-modules permission-contents: read - name: Checkout @@ -234,7 +239,7 @@ jobs: run: | export PATH=$GITHUB_WORKSPACE/bin:$PATH which rad || { echo "cannot find rad"; exit 1; } - rad bicep publish-extension -f "./${RELEASE_DIR}/test/functional-portable/dynamicrp/noncloud/resources/testdata/testresourcetypes.yaml" --target "br:${BICEP_TYPES_REGISTRY}/testresources:latest" --force + rad bicep publish-extension -f "./${RELEASE_DIR}/test/functional-portable/dynamicrp/noncloud/resources/testdata/testresourcetypes.yaml" --target "br:${TEST_BICEP_TYPES_REGISTRY}/testresources:latest" --force env: RELEASE_DIR: ${{ steps.checkout-release-codebase.outputs.release-dir }} @@ -244,7 +249,7 @@ jobs: BICEP_CONFIG_FILE="./${RELEASE_DIR}/test/functional-portable/dynamicrp/noncloud/resources/bicepconfig.json" TMP_FILE="$(mktemp)" - jq --arg testresources "br:${BICEP_TYPES_REGISTRY}/testresources:latest" \ + jq --arg testresources "br:${TEST_BICEP_TYPES_REGISTRY}/testresources:latest" \ '.extensions.testresources = $testresources | .cloud.credentialPrecedence = ["AzureCLI", "Environment"]' \ "${BICEP_CONFIG_FILE}" > "${TMP_FILE}" mv "${TMP_FILE}" "${BICEP_CONFIG_FILE}" @@ -467,13 +472,11 @@ jobs: needs: [tests] runs-on: ubuntu-24.04 timeout-minutes: 5 - permissions: - issues: write steps: - name: Create failure issue for failing long running test run uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 with: - github-token: ${{ github.token }} + github-token: ${{ secrets.GH_RAD_CI_BOT_PAT }} script: | github.rest.issues.create({ ...context.repo, From c459f6fd29e50c688ccf08524d883c872cf85337 Mon Sep 17 00:00:00 2001 From: willdavsmith Date: Fri, 20 Feb 2026 14:42:44 -0800 Subject: [PATCH 19/24] WIP Signed-off-by: willdavsmith --- .github/workflows/functional-test-cloud.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/functional-test-cloud.yaml b/.github/workflows/functional-test-cloud.yaml index 1b7b5f3f05..f6d2a57719 100644 --- a/.github/workflows/functional-test-cloud.yaml +++ b/.github/workflows/functional-test-cloud.yaml @@ -861,7 +861,7 @@ jobs: }, "extensions": { "radius": "br:${{ env.TEST_BICEP_TYPES_REGISTRY }}/test/radius:$RADIUS_VERSION", - "aws": "br:${{ env.TEST_BICEP_TYPES_REGISTRY }}/aws:latest" + "aws": "br:${{ env.BICEP_TYPES_REGISTRY }}/aws:latest" }, "cloud": { "credentialPrecedence": ["Environment"] From 492d63a22fad2c1194af69eaf2b4a660a42e78e1 Mon Sep 17 00:00:00 2001 From: willdavsmith Date: Fri, 20 Feb 2026 14:59:42 -0800 Subject: [PATCH 20/24] WIP Signed-off-by: willdavsmith --- .github/workflows/functional-test-cloud.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/functional-test-cloud.yaml b/.github/workflows/functional-test-cloud.yaml index f6d2a57719..5fcd8f8324 100644 --- a/.github/workflows/functional-test-cloud.yaml +++ b/.github/workflows/functional-test-cloud.yaml @@ -468,6 +468,13 @@ jobs: } EOF + - name: Login to Azure (for private test bicep-types ACR) + uses: azure/login@a457da9ea143d694b1b9c7c869ebb04ebe844ef5 # v2.3.0 + with: + client-id: ${{ secrets.AZURE_SP_TESTS_APPID }} + tenant-id: ${{ secrets.AZURE_SP_TESTS_TENANTID }} + subscription-id: ${{ secrets.AZURE_SUBSCRIPTIONID_TESTS }} + - name: Publish Bicep Test Recipes run: | mkdir ./bin From e97e1a9de381f4b50e97b571528839ed4bec024c Mon Sep 17 00:00:00 2001 From: willdavsmith Date: Fri, 20 Feb 2026 15:23:08 -0800 Subject: [PATCH 21/24] WIP Signed-off-by: willdavsmith --- .github/workflows/functional-test-cloud.yaml | 77 +++++-------------- .../workflows/functional-test-noncloud.yaml | 2 +- .github/workflows/long-running-azure.yaml | 6 +- 3 files changed, 24 insertions(+), 61 deletions(-) diff --git a/.github/workflows/functional-test-cloud.yaml b/.github/workflows/functional-test-cloud.yaml index 5fcd8f8324..5e311a30c0 100644 --- a/.github/workflows/functional-test-cloud.yaml +++ b/.github/workflows/functional-test-cloud.yaml @@ -390,64 +390,32 @@ jobs: message: | :hourglass: Publishing Bicep Recipes for functional tests... - - name: Get App Token (radius-publisher) - uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1 - id: get_publisher_token + - name: Setup Node.js + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: - app-id: ${{ secrets.RADIUS_PUBLISHER_BOT_APP_ID }} - private-key: ${{ secrets.RADIUS_PUBLISHER_BOT_PRIVATE_KEY }} - permission-metadata: read - permission-actions: read - permission-contents: write - owner: azure-octo - repositories: | - radius-publisher + node-version-file: .node-version - - name: Capture dispatch start time - id: dispatch-start - shell: bash + - name: Generate Bicep extensibility types from OpenAPI specs run: | - echo "started_at=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$GITHUB_OUTPUT" + make generate-bicep-types VERSION=${{ env.REL_VERSION == 'edge' && 'latest' || env.REL_VERSION }} - - name: Repository Dispatch (publish test bicep types) - id: repository-dispatch - uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697 # v4.0.1 - with: - token: ${{ steps.get_publisher_token.outputs.token }} - repository: azure-octo/radius-publisher - event-type: bicep-types - client-payload: |- - { - "source_repository": "${{ github.repository }}", - "source_ref": "${{ github.ref }}", - "source_sha": "${{ github.sha }}", - "rel_channel": "${{ env.REL_VERSION }}", - "registry_target": "test/radius" - } + - name: Setup and verify bicep CLI + run: | + curl -Lo bicep https://github.com/Azure/bicep/releases/latest/download/bicep-linux-x64 + chmod +x ./bicep + sudo mv ./bicep /usr/local/bin/bicep + bicep --version - - name: Monitor remote workflow - id: monitor-remote-workflow - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + - name: Login to Azure (for private test bicep-types ACR) + uses: azure/login@a457da9ea143d694b1b9c7c869ebb04ebe844ef5 # v2.3.0 with: - github-token: ${{ steps.get_publisher_token.outputs.token }} - script: | - const { default: script } = await import(`${process.env.GITHUB_WORKSPACE}/.github/scripts/monitor-remote-workflow.mjs`) - await script({context, github, core}) - env: - INPUT_OWNER: azure-octo - INPUT_REPO: radius-publisher - INPUT_WORKFLOW_FILE: publish-bicep-types.yml - INPUT_DISPATCH_STARTED_AT: ${{ steps.dispatch-start.outputs.started_at }} - INPUT_MAX_WAIT_SECONDS: "900" - INPUT_POLL_INTERVAL_SECONDS: "10" - - - name: Show failed logs - if: failure() && steps.monitor-remote-workflow.outputs.run_id != '' - shell: bash - env: - GH_TOKEN: ${{ steps.get_publisher_token.outputs.token }} + client-id: ${{ secrets.AZURE_SP_TESTS_APPID }} + tenant-id: ${{ secrets.AZURE_SP_TESTS_TENANTID }} + subscription-id: ${{ secrets.AZURE_SUBSCRIPTIONID_TESTS }} + + - name: Publish Radius test bicep types run: | - gh run view "${{ steps.monitor-remote-workflow.outputs.run_id }}" --repo azure-octo/radius-publisher --log-failed || true + bicep publish-extension ./hack/bicep-types-radius/generated/index.json --target br:${{ env.TEST_BICEP_TYPES_REGISTRY }}/test/radius:${{ env.REL_VERSION == 'edge' && 'latest' || env.REL_VERSION }} --force - name: Generate test bicepconfig.json run: | @@ -468,13 +436,6 @@ jobs: } EOF - - name: Login to Azure (for private test bicep-types ACR) - uses: azure/login@a457da9ea143d694b1b9c7c869ebb04ebe844ef5 # v2.3.0 - with: - client-id: ${{ secrets.AZURE_SP_TESTS_APPID }} - tenant-id: ${{ secrets.AZURE_SP_TESTS_TENANTID }} - subscription-id: ${{ secrets.AZURE_SUBSCRIPTIONID_TESTS }} - - name: Publish Bicep Test Recipes run: | mkdir ./bin diff --git a/.github/workflows/functional-test-noncloud.yaml b/.github/workflows/functional-test-noncloud.yaml index caabd53cb3..af96a7ea2f 100644 --- a/.github/workflows/functional-test-noncloud.yaml +++ b/.github/workflows/functional-test-noncloud.yaml @@ -75,7 +75,7 @@ env: LOCAL_REGISTRY_SERVER: localhost # Local Docker registry port LOCAL_REGISTRY_PORT: "5000" - # bicep-types ACR url for uploading Radius Bicep types + # bicep-types ACR url for pulling public AWS Bicep types BICEP_TYPES_REGISTRY: biceptypes.azurecr.io # Git HTTP server URL GIT_HTTP_SERVER_URL: http://localhost:30080 diff --git a/.github/workflows/long-running-azure.yaml b/.github/workflows/long-running-azure.yaml index 5fc9b51d0e..5f65835c98 100644 --- a/.github/workflows/long-running-azure.yaml +++ b/.github/workflows/long-running-azure.yaml @@ -249,8 +249,10 @@ jobs: BICEP_CONFIG_FILE="./${RELEASE_DIR}/test/functional-portable/dynamicrp/noncloud/resources/bicepconfig.json" TMP_FILE="$(mktemp)" - jq --arg testresources "br:${TEST_BICEP_TYPES_REGISTRY}/testresources:latest" \ - '.extensions.testresources = $testresources | .cloud.credentialPrecedence = ["AzureCLI", "Environment"]' \ + jq --arg radius "br:${BICEP_TYPES_REGISTRY}/radius:latest" \ + --arg aws "br:${BICEP_TYPES_REGISTRY}/aws:latest" \ + --arg testresources "br:${TEST_BICEP_TYPES_REGISTRY}/testresources:latest" \ + '.extensions.radius = $radius | .extensions.aws = $aws | .extensions.testresources = $testresources | .cloud.credentialPrecedence = ["AzureCLI", "Environment"]' \ "${BICEP_CONFIG_FILE}" > "${TMP_FILE}" mv "${TMP_FILE}" "${BICEP_CONFIG_FILE}" env: From 24782ff91e55341f00f12366881ed3dbf913d792 Mon Sep 17 00:00:00 2001 From: willdavsmith Date: Fri, 20 Feb 2026 16:48:36 -0800 Subject: [PATCH 22/24] WIP Signed-off-by: willdavsmith --- .github/workflows/functional-test-cloud.yaml | 26 ++++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/.github/workflows/functional-test-cloud.yaml b/.github/workflows/functional-test-cloud.yaml index 5e311a30c0..bc3cd21f88 100644 --- a/.github/workflows/functional-test-cloud.yaml +++ b/.github/workflows/functional-test-cloud.yaml @@ -639,21 +639,31 @@ jobs: # create kind cluster with OIDC provider. - name: Create KinD cluster run: | + set -euo pipefail + curl -sSLo "kind" "https://github.com/kubernetes-sigs/kind/releases/download/${{ env.KIND_VER }}/kind-linux-amd64" chmod +x ./kind - # Populate the following environment variables for Azure workload identity from secrets. - # AZURE_OIDC_ISSUER_PUBLIC_KEY - # AZURE_OIDC_ISSUER_PRIVATE_KEY - # AZURE_OIDC_ISSUER - eval "export $(echo "${{ secrets.FUNCTEST_AZURE_OIDC_JSON }}" | jq -r 'to_entries | map("\(.key)=\(.value)") | @sh')" + # Parse and validate Azure workload identity values from secret JSON. + OIDC_JSON='${{ secrets.FUNCTEST_AZURE_OIDC_JSON }}' + if ! echo "${OIDC_JSON}" | jq -e . >/dev/null; then + echo "FUNCTEST_AZURE_OIDC_JSON is not valid JSON." + echo "Expected keys: AZURE_OIDC_ISSUER, AZURE_OIDC_ISSUER_PUBLIC_KEY, AZURE_OIDC_ISSUER_PRIVATE_KEY" + exit 1 + fi + + AZURE_OIDC_ISSUER="$(echo "${OIDC_JSON}" | jq -er '.AZURE_OIDC_ISSUER')" + AZURE_OIDC_ISSUER_PUBLIC_KEY="$(echo "${OIDC_JSON}" | jq -er '.AZURE_OIDC_ISSUER_PUBLIC_KEY')" + AZURE_OIDC_ISSUER_PRIVATE_KEY="$(echo "${OIDC_JSON}" | jq -er '.AZURE_OIDC_ISSUER_PRIVATE_KEY')" - AUTHKEY=$(echo -n "${{ github.actor }}:${{ github.token }}" | base64) + AUTHKEY=$(printf '%s' "${{ github.actor }}:${{ github.token }}" | base64) echo "{\"auths\":{\"ghcr.io\":{\"auth\":\"${AUTHKEY}\"}}}" > "./ghcr_secret.json" # Create KinD cluster with OIDC Issuer keys - echo $AZURE_OIDC_ISSUER_PUBLIC_KEY | base64 -d > sa.pub - echo $AZURE_OIDC_ISSUER_PRIVATE_KEY | base64 -d > sa.key + printf '%s' "${AZURE_OIDC_ISSUER_PUBLIC_KEY}" | base64 -d > sa.pub + printf '%s' "${AZURE_OIDC_ISSUER_PRIVATE_KEY}" | base64 -d > sa.key + openssl pkey -pubin -in sa.pub -noout >/dev/null + openssl pkey -in sa.key -check -noout >/dev/null cat < Date: Fri, 20 Feb 2026 17:36:57 -0800 Subject: [PATCH 23/24] WIP Signed-off-by: willdavsmith --- .../corerp/cloud/mechanics/aws_mechanics_test.go | 2 ++ .../corerp/cloud/resources/aws_logs_loggroup_test.go | 4 ++++ .../cloud/resources/aws_multi_identifier_resource_test.go | 2 ++ .../corerp/cloud/resources/extender_test.go | 2 ++ test/functional-portable/ucp/cloud/aws_credential_test.go | 2 ++ test/functional-portable/ucp/cloud/aws_test.go | 4 ++++ 6 files changed, 16 insertions(+) diff --git a/test/functional-portable/corerp/cloud/mechanics/aws_mechanics_test.go b/test/functional-portable/corerp/cloud/mechanics/aws_mechanics_test.go index c540968de7..b6e8338fc6 100644 --- a/test/functional-portable/corerp/cloud/mechanics/aws_mechanics_test.go +++ b/test/functional-portable/corerp/cloud/mechanics/aws_mechanics_test.go @@ -27,6 +27,8 @@ import ( ) func Test_AWSRedeployWithUpdatedResourceUpdatesResource(t *testing.T) { + t.Skip("temporarily skipping AWS tests while OIDC issuer validation is being updated") + template := "testdata/aws-mechanics-redeploy-withupdatedresource.bicep" name := "radiusfunctionaltest-" + uuid.New().String() creationTimestamp := testutil.GetCreationTimestamp() diff --git a/test/functional-portable/corerp/cloud/resources/aws_logs_loggroup_test.go b/test/functional-portable/corerp/cloud/resources/aws_logs_loggroup_test.go index 39637ec553..c57d19d2c9 100644 --- a/test/functional-portable/corerp/cloud/resources/aws_logs_loggroup_test.go +++ b/test/functional-portable/corerp/cloud/resources/aws_logs_loggroup_test.go @@ -27,6 +27,8 @@ import ( ) func Test_AWS_LogsLogGroup(t *testing.T) { + t.Skip("temporarily skipping AWS tests while OIDC issuer validation is being updated") + template := "testdata/aws-logs-loggroup.bicep" name := "radiusfunctionaltest-" + uuid.New().String() creationTimestamp := testutil.GetCreationTimestamp() @@ -63,6 +65,8 @@ func Test_AWS_LogsLogGroup(t *testing.T) { } func Test_AWS_LogsLogGroup_Existing(t *testing.T) { + t.Skip("temporarily skipping AWS tests while OIDC issuer validation is being updated") + template := "testdata/aws-logs-loggroup.bicep" templateExisting := "testdata/aws-logs-loggroup-existing.bicep" name := "radiusfunctionaltest-" + uuid.New().String() diff --git a/test/functional-portable/corerp/cloud/resources/aws_multi_identifier_resource_test.go b/test/functional-portable/corerp/cloud/resources/aws_multi_identifier_resource_test.go index c5d29da1c4..7fa0131c74 100644 --- a/test/functional-portable/corerp/cloud/resources/aws_multi_identifier_resource_test.go +++ b/test/functional-portable/corerp/cloud/resources/aws_multi_identifier_resource_test.go @@ -28,6 +28,8 @@ import ( ) func Test_AWS_MultiIdentifier_Resource(t *testing.T) { + t.Skip("temporarily skipping AWS tests while OIDC issuer validation is being updated") + template := "testdata/aws-multi-identifier.bicep" filterName := "ms" + uuid.New().String() logGroupName := "ms" + uuid.New().String() diff --git a/test/functional-portable/corerp/cloud/resources/extender_test.go b/test/functional-portable/corerp/cloud/resources/extender_test.go index a599bc6243..0f0ad4300b 100644 --- a/test/functional-portable/corerp/cloud/resources/extender_test.go +++ b/test/functional-portable/corerp/cloud/resources/extender_test.go @@ -30,6 +30,8 @@ import ( ) func Test_Extender_RecipeAWS_LogGroup(t *testing.T) { + t.Skip("temporarily skipping AWS tests while OIDC issuer validation is being updated") + awsAccountID := os.Getenv("AWS_ACCOUNT_ID") awsRegion := os.Getenv("AWS_REGION") // Error the test if the required environment variables are not set diff --git a/test/functional-portable/ucp/cloud/aws_credential_test.go b/test/functional-portable/ucp/cloud/aws_credential_test.go index 0e803353d0..45dc49b6d2 100644 --- a/test/functional-portable/ucp/cloud/aws_credential_test.go +++ b/test/functional-portable/ucp/cloud/aws_credential_test.go @@ -31,6 +31,8 @@ import ( ) func Test_AWS_Credential_Operations(t *testing.T) { + t.Skip("temporarily skipping AWS tests while OIDC issuer validation is being updated") + myTest := test.NewUCPTest(t, "Test_AWS_Credential_Operations", func(t *testing.T, url string, roundTripper http.RoundTripper) { resourceTypePath := "/planes/aws/awstest/providers/System.AWS/credentials" resourceURL := fmt.Sprintf("%s%s/default?api-version=%s", url, resourceTypePath, ucp.Version) diff --git a/test/functional-portable/ucp/cloud/aws_test.go b/test/functional-portable/ucp/cloud/aws_test.go index 09d5d39591..7641c71391 100644 --- a/test/functional-portable/ucp/cloud/aws_test.go +++ b/test/functional-portable/ucp/cloud/aws_test.go @@ -45,6 +45,8 @@ var ( ) func Test_AWS_DeleteResource(t *testing.T) { + t.Skip("temporarily skipping AWS tests while OIDC issuer validation is being updated") + ctx := context.Background() myTest := test.NewUCPTest(t, "Test_AWS_DeleteResource", func(t *testing.T, url string, roundTripper http.RoundTripper) { @@ -106,6 +108,8 @@ func Test_AWS_DeleteResource(t *testing.T) { } func Test_AWS_ListResources(t *testing.T) { + t.Skip("temporarily skipping AWS tests while OIDC issuer validation is being updated") + ctx := context.Background() myTest := test.NewUCPTest(t, "Test_AWS_ListResources", func(t *testing.T, url string, roundTripper http.RoundTripper) { From d3088e045b3f19dd1cde525197107114953d9851 Mon Sep 17 00:00:00 2001 From: willdavsmith Date: Fri, 20 Feb 2026 18:07:10 -0800 Subject: [PATCH 24/24] WIP Signed-off-by: willdavsmith --- .github/workflows/functional-test-cloud.yaml | 16 ++++++++++++++-- .github/workflows/long-running-azure.yaml | 14 +++++++++++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/.github/workflows/functional-test-cloud.yaml b/.github/workflows/functional-test-cloud.yaml index bc3cd21f88..1cbb352497 100644 --- a/.github/workflows/functional-test-cloud.yaml +++ b/.github/workflows/functional-test-cloud.yaml @@ -842,7 +842,7 @@ jobs: "aws": "br:${{ env.BICEP_TYPES_REGISTRY }}/aws:latest" }, "cloud": { - "credentialPrecedence": ["Environment"] + "credentialPrecedence": ["AzureCLI", "Environment"] } } EOF @@ -855,6 +855,8 @@ jobs: bicep restore ./test/functional-portable/corerp/cloud/resources/testdata/aws-logs-loggroup.bicep --force - name: Run functional tests run: | + set -euo pipefail + # Ensure rad cli is in path before running tests. export PATH=$GITHUB_WORKSPACE/bin:$PATH # Make directory to capture functional test results @@ -868,7 +870,17 @@ jobs: # AZURE_MSSQL_RESOURCE_ID # AZURE_MSSQL_USERNAME # AZURE_MSSQL_PASSWORD - eval "export $(echo "${{ secrets.FUNCTEST_PREPROVISIONED_RESOURCE_JSON }}" | jq -r 'to_entries | map("\(.key)=\(.value)") | @sh')" + PREPROVISIONED_JSON='${{ secrets.FUNCTEST_PREPROVISIONED_RESOURCE_JSON }}' + if ! echo "${PREPROVISIONED_JSON}" | jq -e . >/dev/null; then + echo "FUNCTEST_PREPROVISIONED_RESOURCE_JSON is not valid JSON." + echo "Expected keys: AZURE_COSMOS_MONGODB_ACCOUNT_ID, AZURE_MSSQL_RESOURCE_ID, AZURE_MSSQL_USERNAME, AZURE_MSSQL_PASSWORD" + exit 1 + fi + + export AZURE_COSMOS_MONGODB_ACCOUNT_ID="$(echo "${PREPROVISIONED_JSON}" | jq -er '.AZURE_COSMOS_MONGODB_ACCOUNT_ID')" + export AZURE_MSSQL_RESOURCE_ID="$(echo "${PREPROVISIONED_JSON}" | jq -er '.AZURE_MSSQL_RESOURCE_ID')" + export AZURE_MSSQL_USERNAME="$(echo "${PREPROVISIONED_JSON}" | jq -er '.AZURE_MSSQL_USERNAME')" + export AZURE_MSSQL_PASSWORD="$(echo "${PREPROVISIONED_JSON}" | jq -er '.AZURE_MSSQL_PASSWORD')" make test-functional-${{ matrix.name }} env: diff --git a/.github/workflows/long-running-azure.yaml b/.github/workflows/long-running-azure.yaml index 5f65835c98..a6c8c7113a 100644 --- a/.github/workflows/long-running-azure.yaml +++ b/.github/workflows/long-running-azure.yaml @@ -386,6 +386,8 @@ jobs: GIT_HTTP_PASSWORD: ${{ env.GIT_HTTP_PASSWORD }} working-directory: ${{ steps.checkout-release-codebase.outputs.release-dir }} run: | + set -euo pipefail + # Ensure rad cli is in path before running tests. export PATH=$GITHUB_WORKSPACE/bin:$PATH @@ -396,7 +398,17 @@ jobs: # AZURE_MSSQL_RESOURCE_ID # AZURE_MSSQL_USERNAME # AZURE_MSSQL_PASSWORD - eval "export $(echo "${{ secrets.FUNCTEST_PREPROVISIONED_RESOURCE_JSON }}" | jq -r 'to_entries | map("\(.key)=\(.value)") | @sh')" + PREPROVISIONED_JSON='${{ secrets.FUNCTEST_PREPROVISIONED_RESOURCE_JSON }}' + if ! echo "${PREPROVISIONED_JSON}" | jq -e . >/dev/null; then + echo "FUNCTEST_PREPROVISIONED_RESOURCE_JSON is not valid JSON." + echo "Expected keys: AZURE_COSMOS_MONGODB_ACCOUNT_ID, AZURE_MSSQL_RESOURCE_ID, AZURE_MSSQL_USERNAME, AZURE_MSSQL_PASSWORD" + exit 1 + fi + + export AZURE_COSMOS_MONGODB_ACCOUNT_ID="$(echo "${PREPROVISIONED_JSON}" | jq -er '.AZURE_COSMOS_MONGODB_ACCOUNT_ID')" + export AZURE_MSSQL_RESOURCE_ID="$(echo "${PREPROVISIONED_JSON}" | jq -er '.AZURE_MSSQL_RESOURCE_ID')" + export AZURE_MSSQL_USERNAME="$(echo "${PREPROVISIONED_JSON}" | jq -er '.AZURE_MSSQL_USERNAME')" + export AZURE_MSSQL_PASSWORD="$(echo "${PREPROVISIONED_JSON}" | jq -er '.AZURE_MSSQL_PASSWORD')" make test-functional-all